С тех пор, как я начал использовать Typescript для написания мини-игр H5, я полагался на Ts (интеллектуальные подсказки и дружественные подсказки по рефакторингу), но из-за егоType SystemНеобходимо больше практики.
Недавно разработанные мини-игры H5, с точки зрения мобильной отладки, режим проверки не используется для удобства. используется грубоvConsole, вы должны научиться быть благодарным за чужие вещи, поэтому я решил понять его принцип и, наконец, использовать Ts + React для кодирования одногоКонсоль мобильного браузера, бытьTs+React в действии.
С помощью этого урока вы можете узнать:
- Процесс разработки Ts + React + Mobx
- Базовая система типов
- Некоторые основные концепции JavaScript
- Знание консоли браузера
- Console
- Сеть, XHR
- Storage
- Основной код рендеринга DevTool
Исходный код проектаВпервые используя проект кода Typescript + React,Запишите итерационный процесс, если вам интересно зайти в яму, можете поставить звездочкуС нетерпением жду CodeReview.
Начинать
В соответствии с концепцией быстрого развития (хочу родить ребенка), на основеCreate React AppДля строительных проектов фреймворк пользовательского интерфейса использует тот же написано ЦAntMobile. Прежде чем приступить к объяснению проекта, очевидно, что вам необходимо иметь определенное представление об этих двух (предложения можно использовать в качестве справочного материала для дальнейшего изучения Ts + React).
Ниже давайте взглянем на превью изображения
Пользовательский интерфейс прост, разделен по функциям на
- Журнал 、 Система
- Network
- Elemnet
- Storage
В основном из вышеперечисленных функциональных модулей
PS: В туториале некоторые пропущены, например, как поддерживать стилус (проект выполнил yarn run eject ), добавлять ли I в интерфейс, делать публичный рендеринг или нет, как удалить некоторые Tslint и т. д. (отслеживание истории файла git может быть малоизвестно) PWA и т. д.
базовый стиль кода
Я буду писать компоненты в этом стиле (не лучшая практика) на протяжении всей этой статьи (меньше компонентов без состояния и без применения компонентов более высокого порядка).
import React, { Component } from 'react';
interface Props {
// props type here
}
interface State {
// state type here
}
export default class ClassName extends Component<Props, State> {
// state: State = {...}; 我更喜欢将 state 写在这。
constructor(props: Props) {
super(props);
this.state = {
// some state
};
}
// some methods...
render() {
// return
}
}
Log
Наиболее часто используемая консоль отладки — Log, а неотъемлемый API —window.console
['log', 'info', 'warn', 'debug', 'error']
console
window.console
console
const methodList = ['log', 'info', 'warn', 'debug', 'error'];
methodList.map(method => {
// 1. 保存 window 自带 console 方法。
this.console[method] = window.console[method];
});
methodList.map(method => {
window.console[method] = (...args: any[]) => {
// 2. 做一些保存数据及展示的操作。
// 3. 调用原生 console 方法。
this.console[method].apply(window.console, infos);
};
});
console.log(参数)
import { observable, action, computed } from 'mobx';
export interface LogType {
logType: string;
infos: any[]; // 来自 console 方法的参数。
}
export class LogStore {
@observable logList: LogType[] = [];
@observable logType: string = 'All';
// some action...
}
export default new LogStore();
logView
key-value
__proto__
function
log()
Object
key-value
Array
<li className="my-code-wrap">
<div className="my-code-box">
// 1. 判断是否需要显示展开图标
{opener}
<div className="my-code-key">
// 2. 显示 key
{name}
</div>
<div className="my-code-val">
// 3. 根据值类型,选择其展示方式
{preview}
</div>
</div>
// 4. 如果是 Object 或 Array,则重复 1.
{children}
</li>
sendCMD() {
return (cmd: string) => {
let result = void 0;
try {
result = eval.call(window, '(' + cmd + ')');
} catch (e) {
try {
result = eval.call(window, cmd);
} catch (e) {
;
}
}
// mobx中的 action
logStore.addLog({ logType: 'log', infos: [result] })
}
}
eval()
winodw.console
script error
fundebug
System
userAgent
Network
network
XMLHttpRequest
open
send
getAllResponseHeaders
onreadystatechange
readyState
status
response
onreadystatechange
XMLHttpRequest.readyState
XMLHttpRequest
0 | UNSENT | |
1 | OPENED | |
2 | HEADERS_RECEIVED | |
3 | LOADING | |
4 | DONE |
mockAjax() {
// 这里的 (window as any).XMLHttpRequest 我用的很虚。太粗暴了
const XMLHttpRequest = (window as any).XMLHttpRequest;
if (!XMLHttpRequest) {
return;
}
const that = this;
// 1、备份原生 XMLHttpRequest 的 open 和 send 方法
const XHRnativeOpen = XMLHttpRequest.prototype.open;
const XHRnativeSend = XMLHttpRequest.prototype.send;
// 2、重写 open 方法
XMLHttpRequest.prototype.open = function (...args: any) {
// 3、获取 open 方法传入的参数
const [method, url] = args;
// 4、保存原有 onreadystatechange
const userOnreadystatechange = this.onreadystatechange;
this.onreadystatechange = function (...stateArgs: any) {
// do something
// 5、根据 readyState 做相应处理,主要是保存需要展示的数据,比如 response 和 header
// 6、调用原有 onreadystatechange
return (
userOnreadystatechange &&
userOnreadystatechange.apply(this, stateArgs)
);
};
// 7、调用原生 XMLHttpRequest.open 方法
return XHRnativeOpen.apply(this, args);
};
XMLHttpRequest.prototype.send = function (...args: any) {
// 8、重写 XMLHttpRequest.send 方法并保存数据
return XHRnativeSend.apply(this, args);
};
}
prototype
XMLHttpRequest
axiosXMLHttpRequest
fetch
Element
document.documentElement
<body style="background:#000"></body>
<img src="...">
htmlView
import { parseDOM } from 'htmlparser2';
// 1. 将 HTML 文本,解析为 JSON 格式
const tree = parseDOM(document.documentElement.outerHTML);
// 2. 转换为易于展示的 JSON 格式,并转换为 Immutable 数据
getRoot() {
const { tree, defaultExpandedTags } = this.props;
transformNodes(tree, [], true);
return Immutable.fromJS(tree[0]);
function transformNodes(trees: any[], keyPath: any, initial?: boolean) {
trees.forEach((node: any, i: number) => {
// 3. 数据转换逻辑
});
}
}
// 3. 根据 type 来区分渲染 UI
if (type === 'text' || type === 'comment') {
}
htmlparser2
demohtmlparser2
Storage
localstorage
cookies
Ts + React + Mobx
// Ts 让代码更加易于阅读,只需要看组件这部分代码即可知道,
// 组件接受哪些属性以及其内部状态,并且可以知道他们都接受什么样的类型。
interface Props {
togglePane: () => void;
logList: LogType[]
}
interface State {
searchVal: string
}
// 组件泛型
export default class ClassName extends PureComponent<Props, State> {
// ...
}
"devDependencies": {
"@types/jest": "^23.3.9",
"@types/node": "^10.12.5",
"@types/react": "^16.7.2",
"@types/react-dom": "^16.0.9",
"typescript": "^3.1.6"
}
// 获取 ref 上有所不同
export default class Log extends Component<Props, State> {
private searchBarRef = createRef<SearchBar>()
sendCMD = ()=> {
this.searchBarRef.current!.focus()
}
render() {
return (
<Flex>
<SearchBar
ref={this.searchBarRef}
onclic={this.sendCMD}
/>
</Flex>
);
}
}
yarn run eject
package.json
{
"scripts": {
"eject": "react-scripts eject"
}
}