VUE组成API如何替代Vue Mixins
在Vue组件间共享代码?如果您熟悉Vue 2,您可能已经使用过mixin来实现此目的。但是新的Composition API(现在可作为Vue 2的插件使用,并且是Vue 3的即将推出的功能)提供了一种更好的解决方案。
本文将探讨mixin的缺点,并了解Composition API如何克服这些缺点,并使Vue应用程序更具可扩展性。
简述Mixin
让我们快速回顾一下mixin模式,因为它对于我们将在下一节中介绍的内容至关重要。
通常,Vue组件由一个JavaScript对象定义,该对象具有各种属性,表示我们需要实现的功能——例如数据、方法、计算属性等等。
// MyComponent.js export default { data: () => ({ myDataProperty: null }), methods: { myMethod () { ... } } // ... }
当我们想要在组件之间共享相同的属性时,可以将公共属性提取到一个单独的模块中:
// MyMixin.js export default { data: () => ({ mySharedDataProperty: null }), methods: { mySharedMethod () { ... } } }
现在,我们可以通过将其分配给mixin配置属性,将此mixin添加到任何使用它的组件中。在运行时,Vue会将组件的属性与任何添加的mixin合并。
// ConsumingComponent.js import MyMixin from "./MyMixin.js"; export default { mixins: [MyMixin], data: () => ({ myLocalDataProperty: null }), methods: { myLocalMethod () { ... } } }
对于此特定示例,运行时使用的组件定义如下所示:
export default { data: () => ({ mySharedDataProperty: null, myLocalDataProperty: null }), methods: { mySharedMethod () { ... }, myLocalMethod () { ... } } }
Mixin被认为是“有害的”
早在2016年中期,Dan Abramov就撰写了“Mixins Considered Harmful”(认为Mixin有害),其中他认为在React组件中使用mixin来重用逻辑是一种反模式,主张避免使用它们。
不幸的是,他提到的关于React mixin的缺点也适用于Vue。在了解Composition API如何克服这些缺点之前,让我们先了解一下这些缺点。
命名冲突
我们看到了mixin模式如何在运行时合并两个对象。如果它们都共享一个同名的属性会发生什么?
const mixin = { data: () => ({ myProp: null }) } export default { mixins: [mixin], data: () => ({ // 同名! myProp: null }) }
这就是合并策略发挥作用的地方。这是一组规则,用于确定当组件包含多个同名选项时会发生什么。
Vue组件的默认(但可配置)合并策略规定局部选项将覆盖mixin选项。不过也有例外。例如,如果我们有多个相同类型的生命周期钩子,这些钩子将被添加到钩子数组中,并且所有钩子都将按顺序调用。
即使我们不会遇到任何实际错误,但在多个组件和mixin之间处理命名属性时,编写代码也会越来越困难。一旦添加了作为npm包的第三方mixin及其可能导致冲突的命名属性,情况尤其困难。
隐式依赖
mixin和使用它的组件之间没有层次关系。这意味着组件可以使用mixin中定义的数据属性(例如mySharedDataProperty),但mixin也可以使用它假定在组件中定义的数据属性(例如myLocalDataProperty)。当使用mixin来共享输入验证时,这种情况很常见。mixin可能期望组件具有一个输入值,它将在自己的validate方法中使用该值。
但这可能会导致问题。如果我们稍后想要重构组件并更改mixin需要的变量的名称会发生什么?从组件中我们不会注意到任何问题。代码检查器也不会发现它。我们只会在运行时看到错误。
现在想象一个包含许多mixin的组件。我们可以重构局部数据属性吗,或者它会破坏mixin吗?哪个mixin?我们必须手动搜索所有mixin才能知道。
从mixin迁移
Dan的文章提供了mixin的替代方案,包括高阶组件、实用程序方法和一些其他组件组合模式。
虽然Vue在许多方面与React相似,但他建议的替代模式并不能很好地转换为Vue。因此,尽管这篇文章写于2016年中期,但Vue开发人员从那时起就一直在忍受mixin问题。
直到现在。mixin的缺点是Composition API背后的主要动机因素之一。在了解它如何克服mixin问题之前,让我们快速了解一下它的工作原理。
Composition API速成课程
Composition API的关键思想是,与其将组件的功能(例如状态、方法、计算属性等)定义为对象属性,不如将它们定义为从新的setup函数返回的JavaScript变量。
这是一个使用Composition API定义的Vue 2组件的经典示例,它定义了一个“计数器”功能:
//Counter.vue export default { data: () => ({ count: 0 }), methods: { increment() { this.count ; } }, computed: { double () { return this.count * 2; } } }
以下是使用Composition API定义的完全相同的组件。
// Counter.vue import { ref, computed } from "vue"; export default { setup() { const count = ref(0); const double = computed(() => count.value * 2) function increment() { count.value ; } return { count, double, increment } } }
您首先会注意到我们导入了ref函数,它允许我们定义一个响应式变量,其功能与data变量几乎相同。computed函数也是如此。
increment方法不是响应式的,因此可以将其声明为普通的JavaScript函数。请注意,我们需要更改子属性值才能更改count响应式变量的值。这是因为使用ref创建的响应式变量需要是对象才能在传递时保持其响应性。
最好查阅Vue Composition API文档以详细了解ref的工作原理。
定义这些功能后,我们从setup函数返回它们。上面两个组件的功能没有区别。我们所做的只是使用了替代API。
提示:Composition API将成为Vue 3的核心功能,但您也可以在Vue 2中使用NPM插件@vue/composition-api。
代码提取
Composition API的第一个明显优势是易于提取逻辑。
让我们使用Composition API重构上面定义的组件,以便我们定义的功能位于JavaScript模块useCounter中。(使用“use”作为功能描述的前缀是Composition API的命名约定。)
// useCounter.js import { ref, computed } from "vue"; export default function () { const count = ref(0); const double = computed(() => count.value * 2) function increment() { count.value ; } return { count, double, increment } }
代码重用
要在组件中使用该功能,我们只需将模块导入到组件文件中并调用它(注意导入是一个函数)。这将返回我们定义的变量,然后我们可以从setup函数返回这些变量。
// MyComponent.js import useCounter from "./useCounter.js"; export default { setup() { const { count, double, increment } = useCounter(); return { count, double, increment } } }
起初,这似乎有点冗长且毫无意义,但让我们看看这种模式如何克服我们之前看到的mixin的问题。
命名冲突……已解决!
我们之前看到,mixin可以使用可能与使用组件中甚至更隐蔽地与使用组件使用的其他mixin中的属性同名的属性。
Composition API中不存在这个问题,因为我们需要显式命名从组合函数返回的任何状态或方法:
export default { setup () { const { someVar1, someMethod1 } = useCompFunction1(); const { someVar2, someMethod2 } = useCompFunction2(); return { someVar1, someMethod1, someVar2, someMethod2 } } }
命名冲突将以与任何其他JavaScript变量相同的方式解决。
隐式依赖……已解决!
我们之前还看到,mixin可以使用使用组件上定义的数据属性,这会使代码变得脆弱且难以理解。
组合函数也可以调用使用组件中定义的局部变量。但是,区别在于现在必须将此变量显式地传递给组合函数。
import useCompFunction from "./useCompFunction"; export default { setup () { // 组合函数需要使用的某个局部值 const myLocalVal = ref(0); // 它必须作为参数显式传递 const { ... } = useCompFunction(myLocalVal); } }
总结
mixin模式表面上看起来非常安全。但是,由于它增加了代码的脆弱性以及它掩盖了理解功能的能力的方式,通过合并对象来共享代码成为了一种反模式。
Composition API最巧妙之处在于它允许Vue依靠内置于原生JavaScript中的安全措施来共享代码,例如将变量传递给函数和模块系统。
这是否意味着Composition API在各个方面都优于Vue的经典API?不。在大多数情况下,您可以坚持使用经典API。但是,如果您计划重用代码,Composition API无疑是更好的选择。
以上是VUE组成API如何替代Vue Mixins的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

关于Flex布局中紫色斜线区域的疑问在使用Flex布局时,你可能会遇到一些令人困惑的现象,比如在开发者工具(d...
