vue生命周期

vue

730c92b5f91ce0ebb7fb3f1d64442bd

渲染流程

解析器生成AST>>优化器处理静态节点>>代码生成器生成渲染函数>>生成虚拟dom>>patch>>生成真实dom>>回流重绘

VUE 组件系统的运作原理

​ vue中所有组件都是vue实例,组件在进行模板解析时,会将标签上的属性解析成数据,最终生成渲染函数。而在渲染函数被执行时,会生成真实dom渲染到视图。但在这里面有一个细节,如果某个节点是组件节点,也就是说模板中的、某个标签的名字是组件名,那么在渲染虚拟dom的过程中就会把子组件实例化,这会将模板解析时从标签属性上解析出的数据当作参数传递给子组件,其中就包含props数据。——刘博文《深入浅出VUE.js》

vue2 vue3 响应式原理区别

​ vue2借助Object.defineProperty()对方法定义getter、setter,数组的话直接拦截数组方法(Object.defineProperty也可监听数组,但成本代价太大), 收集window.target依赖于Observer对象中的dep数组

​ vue3通过proxy结合Reflect代理对象和数组,将effect依赖保存起来,放在一个大weakMap里面,一个响应对象对应一个map,而一个key的依赖函数放在一个set里面

     vue2  dep里面放的是Watcher对象   每个双向绑定的元素都有一个Observer

vue v-model

​ 语法糖 1. v-model不仅可以用在input上 2. 还可以用在父子组件间双向绑定

<input v-model="data" />
//d等于
<input :value="data" @input="data = $event.target.value" />
/* 假如是obj data.a
"input": function ($event) {
if ($event.target.composing) return; //都有无论data还是data.a
$set(data, "a", $event.target.value)
}

<input :value="data" @input=" if ($event.target.composing) return;
$set(data, "a", $event.target.value)" />
*/
//发生在代码生成器阶段 generate-》genDirectives

// 2.
<my-checkbox v-model="foo"></my-checkbox>
//等于
<my-checkbox :data="foo" @func1="foo=arguments[0]" ></my-checkbox>


Vue.component('my-checkbox', {
template: `<input
type="checkbox"
@change="$emit('func1', $event.target.checked)"
:checked="data" //若是text 则为value
/>`,
props: ['checked'],
model: {
prop: 'data', //默认为value
event: 'func1' //默认是input
},
})

父子组件间数据双向绑定.asyn:

<my-component :data.sync="data"></my-checkbox>
//等价于
<my-component :data="data" @update:data="val=>data=val"></my-checkbox>
//子组件需要通过emit @update:data 事件触发响应

:bind

通过directive处理bind,对el的属性赋值,并将这个赋值操作放在一个函数里封装成一个依赖被收集

vue.$nextTick

​ 注册回调,获取更新后的dom,或者再更新dom后做点什么事情。

nextTick默认是进入微任务,也可以使用宏任务,在同一个事件循环中,每注册一个nextTick并不会加一个微任务,而是在nextTick中会有一个回调队列,每注册一个nextTick,会把回调函数加入到回调队列中,形成一个微任务(或者宏任务),在任务执行时会把回调队列逐个执行,后清空

当数据更新时,何时更新dom?

当数据更新后,Watcher会收到通知,触发虚拟dom的渲染流程,而触发这个操作并不是同步的,而是异步的,Watcher会借助nextTick更新dom.(因此要注意想在$nextTick中获取更新后的dom,则一定要再更新数据的后面使用$nextTick注册回调)