目录
6.现实中DOM,Comp,Data,BusinessLogic关系更为复杂
如下是典型的前端页面,再看看手机APP, windows操作系统UI界面。


UI的核心是一棵多叉树。因此,UI的理论都以树为基础。如UI框架,VUE,REACT也都是以树为其基层,web中叫DOM(文档对象模型 )。此处的文档是树,对象的嵌套结构也是树

想像一只猴子,如果不能在树枝之间跳转,他的行动会很麻烦。

尽量减少不必要的重新绘制UI.
减小页面跳转的闪烁。
核心思想:
不变的就不要重复渲染。
虚拟DOM(VDOM)与真实DOM(ROM),先构建虚拟DOM,然后批量渲染真 实DOM.
React使用各种Hook: useState, useCallback, useMemo....目的就是加缓存
将模型数据变量与虚拟DOM绑定,修改数据自动触发虚拟DOM改变,进而触发真实DOM改变。
切记,不要直接修改真实DOM. 真实DOM上的事件应该当抛出来由数据模型处理,处理完后修改模型,进而改变DOM.
flux架构:单向数据流 user/system --> action->dispatcher --> stores ---> views
在树上,每个子结点和叶子结点应当只保存自己的状态,最好不要保存任何状态。这些子
树根保存全局状态。
5.1. props
组件要Pure:内部没有自己的状态,所有状态通过参数props传入。
组件内部发生事件,不要在内部直接改状态,而是把事件抛到上层,一直抛到顶层去处理。 可以通过回调函数(委托)一层层回调回去。 或者通过事件中心去处理
只有顶层能修改状态,状态修改会传入到组件内部,而导致DOM更新。
5.2. 全局context
react: Context Provider Consumer
VUE: vuex, state

让用户通过编程绑定数据模型变量与vdom和rdom. 达到修改数据模型变量后能自动修改DOM.
数据模型存储
用户事件送达business模块。一般通过事件中心来解决。 也可以像数据一样,把回调函数也当数据一样,绑定到RDOM的如OnClick函数等上去。这个回调函数可以只是抛一个事件,也可以直接处理业务逻辑。

VOM与数据层变量绑定后,要不要直接修改数据变量?
CompA中是否要有自己的业务逻辑处理?
CompA中是否要有数据存储?



全局数据应该只能由全局Business模块修改。
组件内数据只应由组件内Business逻辑。
全局Business模块不要直接组件内数据,也不直接调用组件内Business逻辑。可以抛出全局事件
组件内Business模块想修改全局数据,可以抛出事件,或者使用委托。
组件应当监听全局数据变化,监听全局事件。

所谓PureComponent架构,是指Component中不包含任务状态数据,也没有任何业务逻辑。组件所需数据由Global数据提供,并只读Global数据。组件不修改Global数据。组件产生的事件后,回调Global提供的函数。抽象成函数是:
void ComponentA(InData1, InData2, ..., EventCallBackA, EventCallbackB,...);
VUE使用模板技术,动态生成HTML代码。
而React使用JSX技术,直接在JS中写HTML。
重要标签 html, head, title, body, script, div, button, input, list, tree, table 事件处理... 直接使用element-ui或者ant design里的吧
选择器:标签,id,类
布局: display: flext, float, padding, margin, 使用UI库里的布局器
基本属性设置:color, font ...。一般使用UI库,这些也少用
基本语法,get, post, 函数,类, 数组,字符串 并发与异步,async await, locastorage
Component[template(v-on, v-bind, v-model, v-for, v-if), props, JavaScript(data, compute, watch, OnMounted), CSS], slot, event($.emit)],
路由,网络axios,存储vuex
Compoent(jsx(js中使用html), hook[useState, useEffect, useMemo, useCallback...])
router,
全局存储 context provider/consumer
css: className, 内联style
网络:graphQL
Suspense:拆分组件,延迟加载
使用函数:React.createElement(tagName, props, children)
tagName就是html标签如div, input, span...
props就是标签属性
children就是标签包裹的内容
如this is a input
翻译成react: React.createElement("input", {id:"hello", value:"default"}, "this is a input");
children也可以是React.createElement()
JSX可以在js中写html标签
import React from "react"
export default function Component(props){
const msg = "hello";
return(
<>
{msg}
>
);
}
import React from "react"
export default function Component(props){
const msg = "hello";
return React.createElement("span", {id:props.id}, msg);
}
上代码忽略了import 和<>>的翻译。 JSX只能有一个根标签,所以用<>>把其他标签
包裹起来。
有了这个组件后,可以在其他JSX中用
Component = {
type: span,
props:{ id:props.id, children:msg} msg,被放在chidren中。
}
html里:
JS: ReactDOM.render(Component, docuemnt.getElementById("root"));

hook,也挂钩技术。把Component渲染与变量更新挂钩。
其他Hook: useState, useCallback, useMemo, useLayoutEffect, useEffect, useRef, useReducer,memo
compB = memo(compA); 让A组件的props不变的情况下不重render。所以组件A最好是Pure组件。
- function component(props){
- const [login, setLogin] = useState("cosmicpython");
- return (
- <>
- <input type="text" value={login} onChange={(e)=>setLogin(e.target.value)}/>
- <>);
- }
input的value只读login. onChange时设置login,触发Component()函数调用,重绘input.