目录
简述Mixin
Mixin被认为是“有害的”
命名冲突
隐式依赖
从mixin迁移
Composition API速成课程
代码提取
代码重用
命名冲突……已解决!
隐式依赖……已解决!
总结
首页 web前端 css教程 VUE组成API如何替代Vue Mixins

VUE组成API如何替代Vue Mixins

Apr 07, 2025 am 10:50 AM

How the Vue Composition API Replaces 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中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

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

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

VUE 3 VUE 3 Apr 02, 2025 pm 06:32 PM

它的出局!恭喜Vue团队完成了完成,我知道这是一项巨大的努力,而且很长时间。所有新文档也是如此。

您可以从浏览器获得有效的CSS属性值吗? 您可以从浏览器获得有效的CSS属性值吗? Apr 02, 2025 pm 06:17 PM

我有人写了这个非常合法的问题。 Lea只是在博客上介绍了如何从浏览器中获得有效的CSS属性。那样的是这样。

在CI/CD上有点 在CI/CD上有点 Apr 02, 2025 pm 06:21 PM

我说的“网站”比“移动应用程序”更合适,但我喜欢Max Lynch的框架:

带有粘性定位的堆叠卡和一点点的杂物 带有粘性定位的堆叠卡和一点点的杂物 Apr 03, 2025 am 10:30 AM

前几天,我发现了科里·金尼文(Corey Ginnivan)网站上的这一点,当您滚动时,彼此之间的卡片堆放集。

在WordPress块编辑器中使用Markdown和本地化 在WordPress块编辑器中使用Markdown和本地化 Apr 02, 2025 am 04:27 AM

如果我们需要直接在WordPress编辑器中向用户显示文档,那么最佳方法是什么?

比较浏览器的响应式设计 比较浏览器的响应式设计 Apr 02, 2025 pm 06:25 PM

这些桌面应用程序中有许多目标是同时在不同的维度上显示您的网站。因此,例如,您可以写作

为什么Flex布局中的紫色斜线区域会被误认为是'溢出空间”? 为什么Flex布局中的紫色斜线区域会被误认为是'溢出空间”? Apr 05, 2025 pm 05:51 PM

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

如何将CSS网格用于粘头和页脚 如何将CSS网格用于粘头和页脚 Apr 02, 2025 pm 06:29 PM

CSS网格是一系列属性的集合,旨在使布局比以往任何时候都容易。像任何东西一样,那里有一点学习曲线,但是网格是

See all articles