编写基础和全局混入
混入(mixin
)就是一个包含任意组件选项(如 created
、methods
、mounted
等)的 JavaScript
对象,可用于实现这些选项的复用。我们可以通过将混入导入组件,并与该组件的其他选项 "混合" 来使用它们。
在某些场景下使用混入非常实用,例如第 2 章《Nuxt 入门》中的案例。我们知道当 Vue Loader 编译单文件组件中的 <template>
块时,会将所有遇到的资源 URL 转换为 webpack
模块请求,例如:
<img src="~/assets/sample-1.jpg">
上述图片会被转换成如下 JavaScript
代码:
createElement('img', {
attrs: {
src: require('~/assets/sample-1.jpg') // 这里变成了模块请求
}
})
如果是手动插入图片,这并不复杂。但大多数情况下,我们需要动态加载图片:
<!-- pages/about.vue -->
<template>
<img :src="'~/assets/images' + post.image.src" :alt="post.image.alt">
</template>
const post = {
title: 'About',
image: {
src: '/about.jpg',
alt: 'Sample alt 1'
}
}
export default {
data () {
return { post }
}
}
这个例子中,控制台会出现图片 404
错误,因为当图片与 :src
指令配合使用时,Vue Loader
不会进行编译,导致 webpack
在构建过程中没有处理该图片。要解决这个问题,需要手动在 :src
指令中插入模块请求:
<img :src="require('~/assets/images/about.jpg')" :alt="post.image.alt">
但这样又失去了动态加载图片的优势。因此最佳解决方案是:
<img :src="loadAssetImage(post.image.src)" :alt="post.image.alt">
通过编写可复用的 loadAssetImage
函数,就能在任何需要的 Vue
组件中调用。这正是混入的用武之地。混入有几种常见的使用方式,我们将在后续章节具体探讨。
创建基础混入/非全局混入
在非单文件组件的 Vue
应用中,我们可以这样定义一个混入对象:
var myMixin = {
created () {
this.hello()
},
methods: {
hello () { console.log('hello from mixin!') }
}
}
然后通过 Vue.extend()
将其 "附加" 到组件:
const Foo = Vue.extend({
mixins: [myMixin],
template: '<div>foo</div>'
})
在这个例子中,我们只将这个混入应用到了 Foo
组件,所以你只会在调用这个组件时看到那条 console.log
消息。
您可以在本书 |
对于 Nuxt
应用,我们需要在 /plugins/
目录的 .js
文件中创建和维护混入对象。具体操作如下:
-
在
/plugins/
目录创建mixin-basic.js
文件,包含一个在Vue
实例创建时向浏览器控制台输出消息的函数:// plugins/mixin-basic.js export default { created () { this.hello() }, methods: { hello () { console.log('hello from mixin!') } } }
-
在需要的地方导入使用:
// pages/about.vue import Mixin from '~/plugins/mixin-basic.js' export default { mixins: [Mixin] }
在这个例子中,你只有在 /about
路由下才会收到 console.log
的消息。这就是我们创建和使用非全局混入的方式。但在某些情况下,我们需要在应用的所有组件中使用全局混入。让我们来看看如何实现这一点。
您可以在本书 |
创建全局混入
我们可以通过 Vue.mixin()
创建并全局应用混入:
Vue.mixin({
mounted () {
console.log('来自混入的问候!')
}
})
全局混入必须在实例化 Vue
之前定义:
const app = new Vue({
//...
}).$mount('#app')
现在,你创建的每个组件都会受到影响并显示该消息。你可以在本书 GitHub
仓库的 /chapter-5/vue/mixins/global.html
中找到这个例子。如果你在浏览器中运行它,你会看到控制台的 console.log
消息出现在每个路由上,因为它会传播到所有的路由组件。通过这种方式,我们可以看到如果滥用它可能会造成的潜在危害。在 Nuxt
中,我们以相同的方式创建全局混入;也就是说,通过使用 Vue.mixin()
。让我们来看一下:
-
在
/plugins/
目录创建mixin-utils.js
文件,包含从/assets/
目录加载图片的函数:// plugins/mixin-utils.js import Vue from 'vue' Vue.mixin({ methods: { loadAssetImage (src) { return require('~/assets/images' + src) } } })
-
在
Nuxt
配置文件中引入该全局混入:// nuxt.config.js module.exports = { plugins: [ '~/plugins/mixin-utils.js' ] }
-
现在您可以在任意组件中使用
loadAssetImage
函数:// pages/about.vue <img :src="loadAssetImage(post.image.src)" :alt="post.image.alt">
注意:与基础混入不同,我们不需要手动导入全局混入,因为它们已通过
nuxt.config.js
完成全局注入。但请再次注意,应当谨慎且节制地使用它们。您可以在本书
GitHub
仓库的/chapter-5/nuxt-universal/mixins/global/
目录找到此混入示例。
混入虽然实用,但像全局 Vue
组件一样,过多的全局混入会使应用难以管理和调试,导致不可预测的行为。因此请明智且节制地使用它们。希望您现在已了解 Vue
组件的工作原理及编写方法。然而,仅知道如何编写还不够——我们还需要遵守标准规范来保证代码的可读性和可维护性。在结束本章前,我们将探讨一些相关规范。