Mixins
Mixin 可以向使用它们的组件添加方法、属性和默认生命周期方法。在下面的示例中,我们定义了一个 mixin,它将一个 greet 方法和一个 greeting 字段添加到组件的 data 函数中:
export default {
methods: {
greet(name) {
return `${this.greeting} ${name}`
}
},
data() {
return {
greeting: 'Hello'
}
}
}
Mixins 允许独立定义多个组件的共享功能。它们通过 mixins 组件属性来使用,该属性接受一个数组。
在 App.vue 文件中,我们可以通过设置组件的 mixins 属性来使用 mixin。
然后,mixin 的属性和方法在组件中可用(就像在组件本身中定义它们一样):
<template>
<div>{{ greet('World') }}</div>
</template>
<script>
import greeter from './mixins/greeter.js'
export default {
mixins: [greeter]
}
</script>
这会在浏览器中显示以下消息:

当组件和 mixin 之间存在命名相同的实例属性或方法冲突时,组件获胜。这可以被认为是默认情况下采用 mixin 行为的组件,除非该组件声明相同的实例属性或方法。在这种情况下,mixin 中定义的实例访问将访问组件的实例。
例如,让我们向 App 组件添加一个 data() 初始值设定项,并将 greeting 设置为 Hi:
<script>
// other imports
export default {
// other component properties
data() {
return {
greeting: 'Hi'
}
}
}
</script>
mixin 定义了一个 data 方法,组件也定义了一个 data 方法。在这种情况下,组件获胜,因此显示的问候语是 Hi(如组件中定义)而不是 Hello(如 mixin 中定义),如以下屏幕截图所示:

请注意,当组件未定义 data 方法时,将使用 mixin 的实现,但如果 mixin 和组件都定义了它,则组件 “获胜”。
Vue.js 生命周期钩子是提取到 mixin 中的主要候选者。我们可以使用的生命周期钩子(按执行顺序)是 beforeCreated、created、beforeMount、mounted、beforeUpdate、updated、beforeDestroy 和 destroyed。
生命周期钩子是前面提到的混合/组件冲突解决规则的一个例外。对于 Vue.js 生命周期钩子函数来说,对于每个 mixin、组件和钩子,钩子函数都按照 mixin 先(按添加到组件的顺序)、组件最后的顺序执行。
我们可以在下面的示例中看到这一点。让我们创建两个 mixins 来实现已安装的生命周期钩子并在组件中实现该钩子。这说明了用于 mixin/组件冲突解决的生命周期钩子的情况:
<template>
<div ref="zone" />
</template>
<script>
const firstMixin = {
mounted() {
console.log('First mixin mounted hook')
}
}
const secondMixin = {
mounted() {
console.log('Second mixin mounted hook')
}
}
export default {
mixins: [firstMixin, secondMixin],
mounted() {
console.log('Component mounted hook')
}
}
</script>
该组件的浏览器控制台输出将(按顺序)第一个 mixin 安装钩子、第二个 mixin 安装钩子和组件安装钩子,如以下屏幕截图所示:

我们看到的所有示例都直接使用 mixin 将功能注入到组件中。Mixin 也可以通过使用 Vue.mixin 函数调用来全局创建。
例如,我们可以将 greeting 函数设为全局实例方法:
Vue.mixin({
methods: {
$greet(greeting, name) {
return `${greeting} ${name}`
}
}
})
this.$greet 现在可在 Vue.mixin 调用后声明的所有 Vue 实例上使用。然而,这个用例最好通过插件来满足。
$methodName 约定在 Vue.js 中用于 Vue.js 应用程序实例(而不是当前组件实例)提供的方法。 |
练习 5.01:创建你自己的 Mixin
在本练习中,我们将创建一个名为 debug 的 mixin,它将返回已传递的输入的 JSON-stringified 表示形式。JavaScript 对象表示法或 JSON 是 JavaScript 的一个子集,它允许将对象和数组的注释以紧凑的人类和机器可读的格式放置。这对于将数据打印到控制台甚至页面上非常有用。 我们将使调试执行所谓的漂亮打印,以便我们可以更轻松地阅读它。
这对于调试 Vue 时在 HTML 中打印数据也很有用。 在 Vue.js DevTools 不可用或不可靠的情况下运行 Node.js 应用程序。 要访问本练习的代码文件,请参阅 https://packt.live/38ivgFq 。
我们将从一个干净的 Vue CLI 项目开始(可以使用 vue new exercise5.01
命令创建)。 Vue CLI 项目中的应用程序可以通过 npm run serve
启动。
请按照以下步骤完成本练习:
-
创建一个新的 src/mixins 文件夹和 src/mixins/debug.js 文件,我们将在其中定义 mixin 的框架:
export default {}
-
mixin 将添加一个 debug 方法,我们应该在 methods 下定义该方法。debug 方法将接收 obj 参数并返回 JSON.stringify 的输出。我们将使用 JSON.stringify(obj, null, 2) 输出两空格的漂亮打印 JSON:
export default { methods: { debug(obj) { return JSON.stringify(obj, null, 2) } } }
-
我们现在可以从 src/App.vue 导入 debug mixin 并将其注册到 mixins 属性下:
<script> import debug from './mixins/debug.js' export default { mixins: [debug], } </script>
-
要查看 debug 方法的实际效果,我们将在 src/App.vue 文件中添加一个 data 方法和一个 created 的钩子(我们可以从中打印 debug 的输出):
<script> // imports export default { // other component properties data() { return { myObj: { some: 'data', other: 'values' } } }, created() { console.log(this.debug(this.myObj)) } } </script>
您应该得到以下输出:
Figure 4. Figure 5.4: Browser console output due to the created hook -
模板中也可以进行 debug;我们可以将其输出插入到 pre 标记中,以便尊重空格:
<template>
<div id="app">
<pre>{{ debug(myObj) }}</pre>
</div>
</template>
该应用程序以及该模板将如下所示:

至此,我们已经了解了如何使用 mixins 以非常明确的方式(mixins
属性)将共享功能注入到多个组件中。 我们还有机会看到当组件的实现覆盖 mixin 提供的属性和方法时会发生什么(通常是组件获胜)。
我们现在将了解如何 注入实例 和 全局功能 并通过插件分发它。