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') } } }