vue2
生命周期图
第一张当然是官网的生命周期图 生命周期 beforeCrated, created, beforeMounted, mounted, beforeDestroy, destroyed, beforeUpdated updated, actived, deactived
双向绑定原理
-
JavaScript 对象传入 Vue 实例作为
data选项,Vue 将遍历此对象所有的 property,并使用Object.defineProperty把这些 property 全部转为 getter/setter。Object.defineProperty是 ES5 中一个无法 shim 的特性,这也就是 Vue 不支持 IE8 以及更低版本浏览器的原因。 -
这些 getter/setter 对用户来说是不可见的,但是在内部它们让 Vue 能够追踪依赖,在 property 被访问和修改时通知变更
-
每个组件实例都对应一个 watcher 实例,它会在组件渲染的过程中把“接触”过的数据 property 记录为依赖。之后当依赖项的 setter 触发时,会通知 watcher,关联的组件重新渲染。
数据响应式更新
- 数据对象上更新数据 需要使用 Vue.set(data, property, value)
- 数组数据的更新使⽤了函数劫持的⽅式,重写了数组的⽅法,Vue将data中的数组进⾏了原型方法重写,指 向了⾃⼰定义的数组原型⽅法。当调⽤数组api时,可以通知依赖更新。如果数组中 包含着引⽤类型,会对数组中的引⽤类型再次递归遍历,实现了监测数组变化
vue3
ref 和 reactive
- ref 可以声明任何数据
- reactive 只能声明对象
为什么会出现这种情况呢,原因是Proxy无法对原始数据类型代理,运行了上述代码,会发现控制台正常输出了set和get。如果我们将obj改成原始数据类型,并再次测试,你会发现控制台输出了报错信息。
// 定义一个对象
let obj = { name: "juejin" };
// 将对象传入Proxy中,并传入处理器对象来重写它的get和set方法
const proxyObj = new Proxy(obj, {
get(target, property, receiver) {
// 获取数据的时候输出‘get’
console.log("get");
},
set(target, property, value, receiver) {
// 设置数据的时候输出‘set’
console.log("set");
return "set";
},
});
proxyObj.name = '1';
proxyObj.name
然而,转变思路 我把简单数据改为 { value } 是不是就可以了
function ref(value) {
// 将传入的值存在obj中
const obj = { value };
// 返回一个Proxy代理
return new Proxy(obj, {
// 获取数据
get(target, property, receiver) {
console.log("get");
return target.value;
},
set(target, property, value, receiver) {
target.value = value;
console.log("set");
return "set";
},
});
}
// 测试
const num = ref(0);
num.value; // 输出'get'
num.value = 1; // 输出'set'
watch和watchEffect的区别
-
watch和watchEffect都是监听器,watchEffect是一个副作用函数。它们之间的区别有: -
watch:既要指明监视的数据源,也要指明监视的回调 -
而
watchEffect可以自动监听数据源作为依赖。不用指明监视的具体数据,监视的回调中用到的数据。 -
watch可以访问改变之前和之后的值,watchEffect只能获取改变后的值。 -
watch运行的时候不会立即执行,值改变后才会执行 -
watchEffect运行后可立即执行。这一点可以通过watch的配置项immediate改变。 -
watchEffect有点像computed,多对一,不过不用写返回值
vue3与 vue2的比较
-
vue3使用 TS 重写
-
支持 Composition API:基于函数的API,更加灵活组织组件逻辑(vue2用的是options api)。 可以用
scrtpt setup来写。 这是vue3的语法糖,简化了组合式 API的写法,并且运行性能更好。使用script setup语法糖的特点 -
响应式系统提升:Vue3中响应式数据原理改成proxy,可监听动态新增删除属性,以及数组变化
-
编译优化:vue2通过标记静态根节点优化diff,Vue3 标记和提升所有静态根节点,diff的时候只需要对比动态节点内容
-
打包体积优化:treeshaking 不引入的包,不会打包进去; 移除了一些不常用的api(inline-template、filter)
-
生命周期的变化:使用setup代替了之前的beforeCreate和created,其他只是改名字效果一样
-
Vue3 的 template 模板支持多个根标签
-
Vuex状态管理:创建实例的方式改变,Vue2为new Store , Vue3为createStore
-
Route 获取页面实例与路由信息:vue2通过this获取router实例,vue3通过使用 getCurrentInstance/ userRoute和userRouter方法获取当前组件实例
-
Props 的使用变化:vue2 通过 this 获取 props 里面的内容,vue3 直接通过 props
-
父子组件传值:vue3 在向父组件传回数据时,如使用的自定义名称,如事件,需要在 emits 中定义一下
-
父组件获取子组件的数据时,需要defineExpose 导出
-
Pinia 移除
mutations,只剩下state、actions、getters。