Vue
# Vue
# 基本原理
当一个Vue实例创建时,Vue会遍历 data 中的属性,用Object.defieProperty (Vue3.0使用proxy)将它们转换为getter/setter ,在内部追踪相关依赖,在属性被访问和修改时通知变化。在每个组件实例都有相应的watcher程序实例,它会在组件渲染的过程中把属性记录为依赖,之后当依赖项的setter被调用时,会通知watcher重新计算,从而致使它关联的组件得以更新

const obj = { a: 1 };
const p = new Proxy(obj, {
get(target, property, receiver) {
console.log("get");
return Reflect.get(target, property, receiver);
},
set(target, property, value, receiver) {
console.log("set");
return Reflect.set(target, property, receiver);
},
has(target, prop) {
console.log("has");
return Reflect.has(target, prop);
},
deleteProperty(target, prop) {
console.log("deleteProperty");
return Reflect.deleteProperty(target, prop);
},
});
p.a; // 输出 --> get
p.a = 2; // 输出 --> set
"a" in p; // 输出 --> has
delete p.a; // 输出 --> deleteProperty
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# Reflect
与Proxy搭配使用,当劫持某些操作时,需要将这些操作反射回去,就使用Reflect
想拥有拦截前的功能,需要使用Reflect反射回去
# 优点
- 轻量级 框架
- 简单易学
- 双向数据 绑定
- 组件化
- 视图 数据 结构 分离
- VDOM
- 运行速度快
# 缺点
- 生态不够完善
构建大型应用——React居多
中小型企业——Vue居多
# 性能优化
# 编码
- 建少 data中数据
- v-if和v-for不能连用
- SPA页面使用keep-alive缓存组件
- key 唯一
- 路由懒加载 异步组件
- 防抖 节流
- 三方模块 按需导入
- 图片懒加载
- 长列表 滚动到可视化动态加载
# 生命周期
beforeCreate
创建前,实例初始化之后,data和methods中数据未初始化,常执行与vue数据无关的事,比如loading
created
实例创建完成,挂载未开始,完成data和methods的初始化,只是页面还未渲染,可发起请求,操作data或methods
beforeMount
mounted
实例被挂载后调用,完成vue实例初始化,且已挂载到页面,我们可以操作DOM节点
beforeUpdate
updated
beforeDestroy
destroyed
# Computed、Watch
# Computed
- 支持缓存,只有依赖的数据变化,才会重新计算
- 不支持异步
- 默认走缓存,基于响应式依赖缓存,即 基于 data 声明过,或是 父组件 传递过来的props 中的数据进行计算
- 属性有一个get 方法 和set方法 ,数据变化时调用set方法
# Watch
- 不支持 缓存,数据变化 就触发相应操作
- 支持异步监听
- 当属性变化时 就需要执行相应 操作
- 监听数据必须是data中或是父组件传递的props
# 总结
computed计算属性,依赖其他属性值,并且computed有缓存,只有依赖的属性变化,下一次获取computed的值才会重新计算
Watch侦听器,更多是 观察 的作用,没有缓存,类似某些数据的 监听回调,数据变化时 执行回调
# v-model
# 作用在表单元素
动态绑定了 input 的value指向 message变量,在触发input事件时动态 将message设为目标值
<input v-model="sth" />
// 等同于
<input
v-bind:value="message"
v-on:input="message=$event.target.value"
>
//$event 指代当前触发的事件对象;
//$event.target 指代当前触发的事件对象的dom;
//$event.target.value 就是当前dom的value值;
//在@input方法中,value => sth;
//在:value中,sth => value;
2
3
4
5
6
7
8
9
10
11
# 作用在组件
自定义组件中,v-model默认利用名为value的prop和名为input的事件
本质是一个父子组件通信的语法糖,通过 props 和 $emit 实现
<child :value="message" @input="function(e){message = e}"></child>
# data为啥是函数
JS的对象是引用类型数据,当多个实例引用同一个对象时,只要一个实例对这个对象进行操作,其他实例中的数据也会变化
Vue中需要复用组件,每个组件都有自己的数据,组件间 才不会相互干扰
所以组件数据不能是对象的形式,而是 函数 的形式
数据以函数返回值的形式定义,这样复用时,返回新的data,每个组件都有私有数据空间,各自维护自己的数据
# Vue template到render
vue模板编译过程:template->AST->render函数
# data变化,会立即同步re-render吗?
不会立即同步执行re-render,Vue实现响应式 是按一定的策略进行 DOM的更新
只要侦听到数据变化,Vue将开启一个队列,并缓存 在同一事件循环中发生的 数据变更
若同一个 watcher 触发多次,只会被push到队列一次,即 在缓存时去除重复数据,避免 不必要的计算和DOM 操作
然后,在下一个事件循环tick中,Vue刷新队列并 执行工作
# Vue-router 路由守卫
- 全局前置/钩子:beforeEach、beforeResolve、afterEach
- 路由独享的守卫:beforeEnter
- 组件内的守卫:beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave
# Vuex
# 原理
Vuex是一个专为Vue开发的状态管理模式,每个Vuex应用核心是store,store包含应用中大部分状态——state
- Vuex状态存储是响应式的,当Vuex组件从store读取状态时,若store中状态变化,相应组件会相应更新
- 改变store中的状态唯一途径是 显式 提交(commit)mutation,便于跟踪状态变化

# Vue模块化开发思路
# v-show、v-if
v-if
- 真正 的条件渲染,确保在切换过程中 分支内的事件监听器和子组件适当被销毁和重建
- 动态向DOM树添加/删除 DOM元素
- 惰性,若初始条件为假 啥也不做;在条件第一次变为真时 才开始局部编译
- 更高的切换消耗
v-show
- 不管初始条件是啥,总被 渲染,仅基于CSS切换
- 设置DOM的display
- 任何条件都被编译,缓存
- 更高的初识渲染消耗
总结
- 若非常频繁切换,使用v-show;若运行时条件很少改变,使用v-if
- 都用来控制元素渲染。v-if判断是否加载 减轻服务器压力,有更高切换开销;display调整display 是客户端操作更流畅,但更高的初始渲染开销