(1)vue2:内置的Object.defineProperty将data中的数据转化成响应式数据的,它会将data中的每个属性都转换为具有getter和setter的响应式属性
Object.defineProperty是一个内置的方法,它用于定义或修改对象的属性特性。
在Vue2中,通过使用Object.defineProperty方法,可以将data对象中的属性转换为具有getter和setter的响应式属性。getter和setter是属性的访问器函数,用于获取和设置属性的值。
具体来说,getter用于获取属性的值,setter用于设置属性的值。当属性被访问时,getter函数会被调用,当属性被修改时,setter函数会被调用。通过在getter和setter函数中进行依赖追踪和触发更新,Vue能够实现响应式数据。
明显缺点:每个data属性都被定义了getter和setter导致产生了大量的getter和setter,影响性能
(2)vue3:引入Proxy拦截==>通过以下两点实现
ref将值包装成响应式(比如常见的布尔值)
reactive将对象包装成响应式的
vue3利用Proxy在ref和reactive内部创建了一个代理对象
实现了对属性和访问的修改拦截,从而实现响应式效果
需要注意的是,这里的Proxy不是指代理服务器,而是指ES6中的Proxy对象,用于实现拦截和代理目标对象操作的功能。
明显优点:Proxy拦截器方法只有在需要时才被调用,这意味着只有在访问或修改被代理对象的属性时才会触发相应的拦截器方法。这样可以提升性能,避免不必要的操作和触发。
vue2:computed和watch都是属性
vue3:computed和watch都是方法
在Vue 3中,computed和watch被更改为方法的好处是:
更加灵活:以前的computed属性和watch属性是在选项对象中定义的,而现在的computed方法和watch方法可以在组件的任何地方定义,使得代码更加灵活。
更好的类型推断:在Vue 2中,computed和watch属性的类型推断有时不够准确,而在Vue 3中,computed方法和watch方法的类型推断更加准确。这是因为方法的参数和返回值可以更直接地反映它们的实际类型。
更好的代码组织:将computed和watch作为方法定义,使得代码结构更加清晰。开发者可以将它们放置在组件内部的任何位置,根据逻辑组织代码,而不再被限制在选项对象中。
更好的性能:在Vue 2中,computed属性和watch属性会在组件实例化时被计算和观察,即使它们没有被使用。而在Vue 3中,computed方法和watch方法只有在被调用时才会执行,提升了性能。
除ref、reactive、toRefs、computed、watch外
还有useStore:在组件中访问Vuex store的实例
useRouter:在组件中访问Vue Router的实例
useRoute:在组件中访问当前路由的信息
(1)useStore:可以通过import {useStore} from "vuex"
然后const store = useStore()
就可以直接通过store.的方式访问vuex中的内容了
而在vue2中:需要使用this.$store来访问vuex
在Vue 2中,需要通过Vue实例的
this.$store
来访问Vuex的内容,而在Vue 3中可以直接通过useStore
函数获取store实例,无需依赖Vue实例。Vue3更加灵活方便
(2)useRouter和useRoute同理
这些新增的函数在Vue 3中提供了更加直接、简洁的方式来访问Vue Router的实例和当前路由的信息,使得代码更加清晰易读
(1)在Vue 2中,响应式数据是通过Object.defineProperty来实现的。这个方法可以将一个属性定义为getter和setter,从而在属性被读取和修改时触发相应的操作。但是,它无法直接拦截属性的添加和删除操作。
举个例子来说明:
// Vue 2
var data = { name: 'Fengfeng' };
Object.defineProperty(data, 'age', {
get() {
console.log('age被读取');
return 18;
},
set(newValue) {
console.log('age被修改为', newValue);
}
});
console.log(data.age); // 输出:age被读取,18
data.age = 20; // 输出:age被修改为 20
在这个例子中,我们通过Object.defineProperty定义了一个名为age
的属性,当我们读取或修改age
属性时,会触发相应的操作。
然而,如果我们尝试添加或删除age
属性,将不会触发任何操作:
data.age = 20;
console.log(data.age); // 输出:18,age并没有被修改为20
delete data.age;
console.log(data.age); // 输出:18,age并没有被删除
相比之下,Vue 3使用了Proxy拦截器来实现响应式。Proxy拦截器可以拦截对象的所有操作,包括属性的读取、修改、添加和删除。这使得Vue 3可以提供更强大的响应式能力。
(2)下面是使用Proxy拦截器实现响应式的例子:
// Vue 3
var data = new Proxy({ name: 'Fengfeng' }, {
get(target, key) {
console.log(key, '被读取');
return target[key];
},
set(target, key, value) {
console.log(key, '被修改为', value);
target[key] = value;
},
deleteProperty(target, key) {
console.log(key, '被删除');
delete target[key];
}
});
console.log(data.age); // 输出:age 被读取,undefined
data.age = 18; // 输出:age 被修改为 18
console.log(data.age); // 输出:age 被读取,18
delete data.age; // 输出:age 被删除
console.log(data.age); // 输出:age 被读取,undefined
在这个例子中,我们使用Proxy来创建一个代理对象,在代理对象上定义了get、set和deleteProperty方法来拦截属性的读取、修改和删除操作。当我们读取、修改或删除age
属性时,会触发相应的操作。
所以,Vue 3相比Vue 2具有更强大的拦截能力,可以通过Proxy拦截器实现属性的添加和删除操作的拦截。