vue3---ref,reactive,toRef,toRefs
在vue2中,数据的响应式是根据 Object.defineProperty方法实现的,所以需要拦截的属性key必须是已知的,也就是对于新增的key无能为力。
在vue3中,使用了代理Proxy。该方法不需要关心key,他拦截的是data,不管是新增还是已知的key,都会被捕捉到。
vue3和vue2差异性,与React hook比如何?
vue3的生命周期:setup(替换beforeCreate,created ),onBeforeupdate,onUpdated,onBeforeMount,onMounted,onBeforeUnmount,onUnmounted.
vue2双向数据绑定的核心是Object.defineProperty(),但是为什么不能实现深度监听呢?
因为组件每次渲染都会将data里的数据通过defineProperty进行响应式或者双向数据绑定,后加的属性是不会被绑定的,也就不会触发更新渲染。
- vue2 -- Object.defineProperty()
let Obj={}; Object.defineProperty(Obj,'name',{ enumerable:true, configurable:true, get:function(){ return `我是获取到的数据:${def}`; }, set:function(val){ def=val; } }) Obj.name=2; console.log(Obj.name);
打印结果:
- vue3 -- Proxy
const handler={ get:function(obj,prop){ return prop in obj? obj[prop]:'17' }, set:function(){ //13中配置 } } let p=new Proxy({a:'2'},handler); p.a=22; console.log(p.a)
打印结果:
两者兼容性:
vue2的definePropertry 只兼容到ie8, vue3的proxy 除了ie都兼容。
对比Vue2
vue2新增属性,往往需要调用$set,因为object.defineProperty只能监听已存在属性,无法监听新增属性,通过$set相当于手动给对象新增属性,然后触发数据响应。vue3中使用proxy,不需要使用$set.
示例:
function observe(obj, callback) { let newObj = {}; Object.keys(obj).forEach((key) => { Object.defineProperty(newObj, key, { enumerable: true, configurable: true, get() { return obj[key]; }, set(val) { obj[key] = val; callback(key, val); } }) }) return newObj; } let obj = observe({ name: 'alan', age: '1888' }, (key, value) => { console.log(`打印${value}`) }); obj.agew = '33ss33' console.log('年龄', obj.agew); function obseve2(obj, callback) { return new Proxy(obj, { set(target, key, value) { target[key] = value; callback(key, value); }, get(taget, key) { return taget[key]; } } ) } let obj2 = obseve2({ x: 1, y: 2 }, (key, value) => { console.log('坐标系') }) obj2.x2 = 3; console.log(obj2.x2);
打印结果:
Diff算法的提升
vue2的潜在问题:它是将模板编译成渲染函数并返回虚拟DOM树,vue框架通过递归遍历两个虚拟DOM树。并比较两个节点的每个属性,来确定实际DOM需要更新的部分。 --缺点:涉及很多不必要的cpu工作。
vue3突破:
vue3的setup()替换了beforeCreate , created ; 类似于初始化功能。
△ ref响应式数据,在函数读取时需要 .value 获取,dom内不需要添加.value 可自动解构;组件return时 将reactive的对象 toRefs,可以使代码更简洁,又不丢失代码响应式。
reactive
内部可以使用计算属性等各种方法,他只是把数据实现响应式而已。
reacive 后的return数据最好用toRefs转化一下。
跟ref混用时可以根据isRef判断类型。
对比:
setup的每个组件实例只会在初始化时调用一次,状态通过应用储存在setup闭包内,而react hook 在每次组件渲染时都会调用,通过隐式地将状态挂载在当前的内部组件节点上。
setup 初始化调用一次,即不受调用顺序的限制,可以有条件的被调用。
watch和watchEffect的区别:
1、watch可以访问新值和旧值,watchEffect不能访问。
2、watchEffect有副作用,dom挂载和更新之前会触发,需要我们自己去清除副作用。
3、watch是惰性的,只有数据变化才会执行,但是watchEffect,每次加载它都会执行。
4、watch需要监听对象,也需要指明监听的回调。但是watchEffect不能指明监听了哪个属性。