共计 3101 个字符,预计需要花费 8 分钟才能阅读完成。
1.vue2 中的响应式与 vue3 中有什么不同
vue2 中响应式采纳 Object.defineProperty
对对象中的属性进行 get
和set
拦挡。创立 observer
类,为每个数据创立一个数组来治理依赖,在 getter
中收集依赖,在 setter
中告诉依赖更新。所以每当属性进行读写操作时就会触发 get
和set
,从而实现对属性的监听。
vue2 中对对象属性的拜访须要先晓得特定的key
,所以对于对象中新增的属性、数组中通过下标新增数据会有些有余。
vue2 中的全局的 $set
办法的实质就是给新增的属性手动observer
Object.defineProperty(car, 'price', {get() {},
set() {}
})
vue3 中的响应式则是借助 Proxy
,target
是指标对象能够是数组甚至是另一个代理,handler
通常是用来定制拦挡行为,通常含有 has
、get
、set
、deleteProperty
等办法。能够看到 vue3 对对象的代理不依赖对象属性,所以能够很好的解决 vue2 中的有余。
const proxy = new Proxy(target, {get: function(target, propKey, receiver) {return '10'}
})
2.vue3 比 vue2 优化了哪些地方
- 全局 API 的批改:vue2 中是导出全局的 vue 对象,在单元测试中,很容易净化全局环境以及带来抵触。vue3 中通过
createApp
创立 app 实例,所有操作批改从间接操作 Vue 全局对象,转变成了操作 vue 实例 - 一些全局的 api 反对了
tree-shaking
,变成了具名的导出,从 vue 对象中脱离。如 nextTick 的援用形式从Vue.nextTicke
变成了import {nextTick, observable} from vue
- 通过
Composition API
以逻辑来划分代码,更好的重用代码,vue2 中对代码的抽离能够通过mixins
,然而mixins
存在命名抵触、裸露进去的变量起源不清晰等问题。composition api
能够进行重命名,防止了命名抵触。 - 对 typescript 更好的反对
- 新增了一些其余的个性,比方
teleport
和suspense
3.vue3 中的 suspense 组件
vue3 中应用 defineAsyncCompoent
办法,办法承受返回 promise
的工厂函数,动静加载组件
const AsyncComp = defineAsyncComopent(() => new Promise((resolve, reject) => {
resolve({template: '<div>test</div>'})
})
)
vue2 中则是间接通过 import 导入。
4.vue3 中的 teleport 组件
teleport
像是一个传送门,容许咱们管制在哪个 dom 节点下出现 html。to
属性承受一个 querySelector,设置父级节点。
实现原理:通过 createBlock
生成一个 vnode
,创立teleport
组件,通过调用 Teleport.process
,选中父节点,mountChildren
办法挂在到 dom
中。
<teleport to="body">
<div></div>
</teleport>
5. 说说虚构 dom 及 vue3 中对虚构 dom 对优化
虚构 dom 就是一个 js 对象来形容 dom 节点,当数据发生变化时,比照变动前后的虚构 dom 节点,通过 dom-diff 算法计算出须要更新的中央,而后来更新须要的视图。
vue 中通过 VNode
类来实例化出不同类型的虚构 dom,比方正文节点通过 isComment 来示意是否是正文节点,text 示意具体的正文信息。
export const createEmptyVNode = (text: string = '') => {const node = new VNode();
node.text = text;
node.isComment = true;
return node;
}
优化前,在一个默认的 Virtual Dom 的 diff 中,须要遍历所有节点,去比拟旧的 props 和新的 props 有没有变动
而优化之后,创立的 vnode 多了 patch flag
标记该节点的可变属性,当 diff 算法走到 _createBlock 函数的时候,会疏忽所有的动态节点,只对有标记的动静节点进行比照,而且在多层的嵌套下仍然无效。
6.vue3 中的生命周期
beforeCreate 和 create 简直是同时在 setup 函数中进行触发的。生命周期函数的书写 OnBeforeMount、OnMounted、onUpdated
vue3 中多了两个调试钩子函数 onRenderTracked onRenderTriggered,顾名思义就是在 render 从新绘制时进行触
7.vue 中的 key 有什么作用
- 在
dom-diff
中标识Vnode
,标识变动前后是否是同一个组件 - 通过
key
复用元素,所以批改某一个元素的 key 能够从新渲染该元素
8.vue3 的 watch 与 vue2 中有哪些不同
- vue3 中的
watch
函数第一个参数为响应式对象、有getter/setter
的effect
函数、或者这些类型数组;第二个参数为数据变动时的回调;第三个参数为watchOption
,提供是否立刻监听和是否深度监听的配置。 -
vue3 能够屡次应用
watch
办法watch(data, () => {}) watch(() => data.name, () => {}) watch([data, name], () => {})
-
vue3 的 setup 中不存在
this
对象,监听路由须要应用 vue-router 提供的userRoute
,vue2 则是在 watch 对象里增加'$route'
进行监听import {useRoute} from "vue-router"; // setup const route = useRoute(); const userData = ref(); // 当参数更改时获取用户信息 watch(() => route.params, () => {});
9.vue3 中 watchEffect 与 watch 的异同
不同点:
watchEffect
立刻执行传入的函数,在初始化时主动收集依赖,并在其依赖变更时从新运行该函数watchEffect
无奈获取原值,只能失去变动后的值
相同点:两者都可通过 StopHandle.stop()
函数手动进行监听
const stopHandle = watchEffect();
handle.stop();
10.v-model 的原理及 vue3 中 v -model 的扭转
v-model
通过在数据批改时,告诉父级节点实现数据的双向绑定。其实是一个语法糖当满足以下两个条件时,可实现自定义组件的 v -model:
- 子组件受控接管 prop
- 数据批改时触发 event 把新的数据提交给父组件
props: {value: String},
model: {
prop: 'value',
event: 'change'
}
vue3 中降级了 v -mode 的用法,通过 update:modelValue
来触发事件,prop 也被更改为 modelValue
。还在一个组件上反对多个 v -model,如新增v-model:lastName
等。
props: {modelValue: String,}
emits: ['update:modelValue'],
methods: {changeTitle() {this.$emit('update:modelValue', title)
}
}
参考链接
- 抄笔记:尤雨溪在 Vue3.0 Beta 直播里聊到了这些
- Vue 原理解析(八):一起搞明确令人头疼的 diff 算法