vue3的源码已经开放很久了,官网也火速出了新文档。但奈何我的速度总是能和蜗牛相比。正好,最近有做到vue3的项目。那我来写一篇 “用后感”
吧!把项目中学习到的关于vue3的理解分享给大家。
这里做一个简单的归纳,个人认为vue3中值得大家注意的点:
- 1、数据拦截机制的变更
- 2、组合API的引入
- 3、setup函数带来的一系列惊喜
- 4、响应式API的实际应用
一、数据拦截机制的变更
vue2 通过 Object.defineProperty() 方式来截持数据的变更。而在升级为 vue3 之后,作者不再借助 Object.defineProperty 来劫持数据,而是通过 es6 的新特性 proxy
来劫持数据。因为在 vue2 中,响应式数据需要通过 data() 初始化预先定义好,但是在 vue3 之后,data 中的数据不再进行响应式追踪,而是将它转化为proxy
代理再进行追踪更新。
注意
: 在vue3中,它将任何在data()函数中定义的数据,会使用getter或setter遍历所有的property,将其转化成proxy代理。
二、组合API的引入
vue3中最大的改变还是compositionApi的引入,这是vue3中的最核心的部分。
包括以下几方面:
- a、setup函数
下一节有详细介绍,这里就不赘述了。
- b、生命周期钩子
vue3抛出了全局的API,通过引入
onX
的形式,使setup函数中支持钩子函数的调用。
- c、provide/Inject
vue3 中也支持在 setup 函数中使用 provide和inject,只要在对应的位置引入即可:
import { provide } from 'vue';
setup(){
provide(name, 'hello!');
}
import {inject} from 'vue';
setup(){
inject('name', [default-value]: string);
}
- d、getCurrentInstance
支持在setup函数中访问自己的实例
import { getCurrentInstance } from 'vue';
setup() {
const internalInstance = getCurrentInstance();
}
三、setup函数带来的一系列惊喜
在vue3中,setup函数的引入,这种函数式的开发方式,很好地将代码整合到一起。
-
在vue2中,data数据需要在使用的时候调用this访问,现在vue3中使用reactive,ref来设置响应式数据。
data() {
return {
name: 'aaa',
};
}
=>
const name = ref('aaa');
就像简单的定义变量一样,使用ref就可以为变量初始化
-
setup函数取代了methods的函数定义方式
在setup函数中,我们可以选择性地对外暴露我们定义的函数。
在vue2中,我们所定义在methods里的函数,都绑定到了this上。this得有多累啊 (> 3 >)
,而setup函数却正好解决了这个问题,很好地保护了我们自己定义的私有变量。
methods: {
function unkouwnFunc() {
console.log(3333);
}
},
=>
setup () {
function unkownFunc() {
console.log(3333);
}
return {
unkownFunc, // return之后,该函数绑定到了组件实例上,可以在模版中直接使用
};
}
-
关于setup函数中使用emit事件
import { SetupContext } from 'vue';
emits: ['eventName'],
setup(props, ctx: SetupContext){
ctx.emit('event-name', value);
}
-
另外作者为了支持setup函数,向外抛出了全局的生命周期钩子,只在setup函数中使用有效。
import { onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, onUnmounted } from 'vue';
setup() {
onBeforeMount() {
your code
}
onMounted () {
your code
}
onBeforeUpdate() {
your code
}
onUpdated() {
your code
}
onBeforeUnmount() {
your code
}
onUnmounted() {
your code
}
}
四、响应式API的实际应用
-
Ref Vs Reactive
ref 是一种基本数据类型的创建方式,返回的是一个 RefImpl 对象。value 指向其绑定的值。如果用它来创建对像的话,会将它的 value 返回一个 reactive 对象。
reactive 对象的返回的是一个 proxy 代理,他在创建的时候,就会一一遍历每一个属性,并将它创建为 es6 代理方式。
从打印的数据我们可以看出,ref数据创建的对象类型的.value跟reactive的数据结构是一致的。也就是说,在ref创建对象类型的数据时,对自动转化为reactive数据。
-
Ref和reactive API带来的便利
vue3中的 ref的reactive 非常非常的好用,为什么这么说?因为vue在这里直接给出了他的全局API。不管在任何场景下,我们都可以直接引入,并创建这个响应式的数据。通过导入,导出,实现代码的
集中化管理
。所谓
集中化管理
, 在这里指的是代码的运用灵活度提升了,vue2中,使用store来集中管理状态,而现在,我们可以直接真正抛弃store了。因为vue3的响应式API 给我们带来了非常nice的体验。
>> state.js
store = {
state: reactive({
count: 0,
})
};
export default store;
=>
import store from 'state.js';
setup() {
// set count
store.count = 2;
// get count
}
-
关于computed和watch的使用问题
computed: {
aaa() => {
return 333
}
},
watch: {
bbb(newv, oldv) {
console.log(newv, oldv);
}
},
}
=>
import { computed } from 'vue';
const aaa = computed(() => {
return 333;
})
watch & watchEffect
import {watchEffect, watch} from 'vue';
// watch 实现了$watch全部的功能
// 单个数据源侦听
watch((bbb, (current, prev)) => {
Your Code
});
// 多个数据源的侦听
watch([aaa, bbb], ([current, prev], [current2, prev2]) => {
Your Code
})
// watchEffect 只追踪依赖项的变更,在变化时,会执行回调函数
const aaa = ref(0);
watchEffect(() => {
console.log(aaa.value);
});
watch VS watchEffect
1、惰性侦听
watchEffect 只具备追踪变更的功能,并且在追踪依赖项的时候就会执行回调函数 watch 相比,会惰性侦听依赖项,在追踪依赖项的时候,不会执行回调函数。
- 2、支持访问当前和之前的状态
3、更具体地说明什么情况下应该触发对调函数
应该是watch相对于watchEffect给出了更多的选项。 比如,获取之前和现在的状态,通过状态的变化,我们可以判段是否执行对应的回调。
END TK U