Mixins是一种分发Vue组件中可复用功能的很是灵活的一种方式。
何时使用
Mixins
1. 页面的风格不用,可是执行的方法和须要的数据相似,咱们是选择每一个都写呢仍是提取出公共部分呢?
基础实例vue
咱们有一对不一样的组件,它们的做用是切换一个状态布尔值,一个模态框和一个提示框。这些提示框和模态框除了在功能上,没有其余共同点:它们看起来不同,用法不同,可是逻辑同样。
// 模态框 const Modal = { template: '#modal', data() { return { isShowing: false } }, methods: { toggleShow() { this.isShowing = !this.isShowing; } }, components: { appChild: Child } }
// 提示框 const Tooltip = { template: '#tooltip', data() { return { isShowing: false } }, methods: { toggleShow() { this.isShowing = !this.isShowing; } }, components: { appChild: Child } }
解决办法以下:
const toggle = { data () { isshowing: false }, methods: { toggleShow() { this.isshowing = !this.isshowing } } } // 下面便可使用了 // mixins: [变量名] const Modal = { template: '#modal', mixins: [toggle], components: { appChild: Child } }; const Tooltip = { template: '#tooltip', mixins: [toggle], components: { appChild: Child } };
若是你是以vue-cli建立的项目来写,能够这样
// mixin.js export const toggle = { data () { isshowing: false }, methods: { toggleShow() { this.isshowing = !this.isshowing } } }
// modal.vue // 将mixin引入该组件,就能够直接使用 toggleShow() 了 import {mixin} from '../mixin.js' export default { mixins: [mixin], mounted () { } } // tooltip组件同上
合并vuex
当组件和混入对象含有同名选项时,这些选项将以恰当的方式混合。vue-cli
1、数据对象内
mixin的数据对象和组件的数据发生冲突时以组件数据优先。数组
var mixin = { data: function () { return { message: 'hello', foo: 'abc' } } } new Vue({ mixins: [mixin], data: function () { return { message: 'goodbye', bar: 'def' } }, created: function () { console.log(this.$data) // => { message: "goodbye", foo: "abc", bar: "def" } } })
2、钩子函数
同名钩子函数将会混合为一个数组,都将被调用到,可是混入对象的钩子将在组件自身钩子以前调用。app
var mixin = { created: function () { console.log('混入对象的钩子被调用') } } new Vue({ mixins: [mixin], created: function () { console.log('组件钩子被调用') } }) // => "混入对象的钩子被调用" // => "组件钩子被调用"
3、值为对象的选项
值为对象的选项,例如 methods
, components
和 directives
,将被混合为同一个对象。两个对象键名冲突时,取组件对象的键值对。ssh
var mixin = { methods: { foo: function () { console.log('foo') }, conflicting: function () { console.log('from mixin') } } } var vm = new Vue({ mixins: [mixin], methods: { bar: function () { console.log('bar') }, conflicting: function () { console.log('from self') } } }) vm.foo() // => "foo" vm.bar() // => "bar" vm.conflicting() // => "from self"
全局混入函数
全局混合被注册到了每一个单一组件上。所以,它们的使用场景极其有限而且要很是的当心。一个我能想到的用途就是它像一个插件,你须要赋予它访问全部东西的权限。但即便在这种状况下,我也对你正在作的保持警戒,尤为是你在应用中扩展的函数,可能对你来讲是不可知的。this
Vue.mixin({ mounted() { console.log("我是mixin"); } }) new Vue({ ... })
再次提醒,当心使用它!那个 console.log将会出如今每一个组件上。这种状况还不算坏(除了控制台上有多余的输出),但若是它被错误的使用,你将能看到它会多么的有害。spa
一个使用合理的例子
// 为自定义的选项 'myOption' 注入一个处理器。 Vue.mixin({ created: function () { var myOption = this.$options.myOption if (myOption) { console.log(myOption) } } }) new Vue({ myOption: 'hello!' }) // => "hello!"
总结插件
混合对于封装一小段想要复用的代码来说是有用的。对你来讲它们固然不是惟一可行的。混合很好,它不须要传递状态,可是这种模式固然也可能会被滥用。因此咱们仍是须要仔细斟酌使用喽!!
例子
import {mapGetters} from 'vuex' // 目的是想要处理 scroll 的bottom值,在含有playlist列表的状况下 export const playlistMixin = { computed: { ...mapGetters([ 'playList' ]) }, mounted() { this.handlePlaylist(this.playList) }, activated() { this.handlePlaylist(this.playList) }, watch: { playlist(newVal) { this.handlePlaylist(newVal) } }, methods: { // 若是组件中没有这个方法,那么就报错 handlePlaylist() { throw new Error('component must implement handlePlaylist method') } } }