响应式基础
vue2中的响应式数据使在data函数所返回的数据对象中声明,而vue3中用es6的Proxy对象取代了这一做法。原因是因为vue2中的响应式原理核心是基于Object.defineProperty()这一方法的,这一方法在vue2中的缺陷在于:
-
性能问题:
Object.defineProperty()会为每个属性添加 getter 和 setter,当处理大型数据对象时,可能会导致性能下降。此外,当有大量的属性变化时,触发大量的重渲染也可能会影响性能。 -
深层次嵌套对象:Vue.js 在默认情况下只会对对象的第一层进行响应式处理。如果对象非常深层嵌套,需要手动确保所有嵌套层级都是响应式的,这可能会导致复杂性增加。
-
数组检测的局限性:虽然 Vue.js 也能使数组响应式,但对数组的方法调用(如
push、pop等)进行劫持需要更多的特殊处理,而这可能不是那么直观。 -
属性的动态添加:使用
Object.defineProperty()无法监视到对象上新添加的属性。Vue 2.x 需要使用$set方法来动态添加响应式属性。这在开发过程中可能会造成不便和混淆。 -
性能监控:在调试和性能监控时,
Object.defineProperty()的使用可能会使调试信息变得复杂和难以理解,尤其是当响应式系统出现问题时,追踪和修复变得更加困难。
以上问题在vue2的开发中经常遇到,所以在vue3中引入了Proxy 来替代 Object.defineProperty(),解决了很多上述的缺陷:
-
全面拦截:Proxy 能够直接拦截对象的动态添加、删除和属性访问,这使得深层次嵌套对象也能轻松实现响应式。
-
性能提升:由于 Proxy 可以更高效地拦截和处理对象操作,因此在性能上有显著提升,特别是在处理大规模数据时。
-
更好的数组处理:Proxy 对数组的处理更加自然和直观,不需要对数组方法进行特殊劫持。
对于数据的处理过滤
vue2中可以使用过滤器filter来进行对数据的加工,而在vue3中删除了filter过滤器,主要是为了简化 API 和提升性能。
-
简化模板逻辑:Vue 团队认为过滤器在模板中使用可能会导致模板逻辑过于复杂。模板的主要目的是声明视图结构,而不是处理数据逻辑。将数据处理逻辑放在模板中可能会导致代码难以维护和调试。
-
更好的可读性和可维护性:在 Vue 3 中,推荐使用方法(methods)和计算属性(computed properties)来替代过滤器。这有助于保持模板的简洁性,同时将数据处理逻辑放在组件的 JavaScript 部分,使代码更加模块化和可维护。
-
性能提升:过滤器在每次渲染时都会重新计算,这可能会影响性能。使用方法和计算属性可以更好地控制何时计算和更新数据,从而提高性能。
-
更灵活的数据处理:
方法和计算属性提供了比过滤器更大的灵活性。你可以在方法和计算属性中编写更复杂的数据处理逻辑,而这在过滤器中可能会变得不切实际和难以维护。
-
与 Vue 的核心理念一致:Vue 3 强调的是基于组合式 API(Composition API)和函数式编程的思想。通过取消过滤器,鼓励开发者更多地使用这些新特性,使代码更加现代化和符合 Vue 的设计哲学。
-
替代方案:虽然过滤器在 Vue 3 中被取消了,但你仍然可以通过以下几种方式实现类似的功能:
使用计算属性
javascript
Copy code
const app = {
data() {
return {
message: 'Hello World'
};
},
computed: {
reversedMessage() {
return this.message.split('').reverse().join('');
}
}
};
使用方法
javascript
Copy code
const app = {
data() {
return {
message: 'Hello World'
};
},
methods: {
reverseMessage(message) {
return message.split('').reverse().join('');
}
}
};
自定义指令
对于更复杂的场景,你可以考虑使用自定义指令,不过在大多数情况下,计算属性和方法已经足够满足需求。
通过这些方式,你可以更灵活地处理数据,同时保持代码的可读性和维护性。取消过滤器的决定是为了更好地实现这些目标,并使 Vue 3 更加简洁和高效。
mixin的取消
在vue3中取消了vue2中的mixin,在vue3的官方文档中写道:
- 不清晰的数据来源:当使用了多个 mixin 时,实例上的数据属性来自哪个 mixin 变得不清晰,这使追溯实现和理解组件行为变得困难。这也是我们推荐在组合式函数中使用 ref + 解构模式的理由:让属性的来源在消费组件时一目了然。
- 命名空间冲突:多个来自不同作者的 mixin 可能会注册相同的属性名,造成命名冲突。若使用组合式函数,你可以通过在解构变量时对变量进行重命名来避免相同的键名。
- 隐式的跨 mixin 交流:多个 mixin 需要依赖共享的属性名来进行相互作用,这使得它们隐性地耦合在一起。而一个组合式函数的返回值可以作为另一个组合式函数的参数被传入,像普通函数那样。
基于上述理由,不再推荐在 Vue 3 中继续使用 mixin。保留该功能只是为了项目迁移的需求和照顾熟悉它的用户。取而代之的是组合式函数,在 Vue 应用的概念中,“组合式函数”(Composables) 是一个利用 Vue 的组合式 API 来封装和复用有状态逻辑的函数。
当构建前端应用时,我们常常需要复用公共任务的逻辑。例如为了在不同地方格式化时间,我们可能会抽取一个可复用的日期格式化函数。这个函数封装了无状态的逻辑:它在接收一些输入后立刻返回所期望的输出。