Vue Component 之 Mixin
栏目: JavaScript · 发布时间: 6年前
内容简介:若多個 component 間有共用的 property,則可抽成 Mixin 讓多個 component 共用,類似 PHP 的 Trait。Vue 2.5.17Vue CLI 3.0.5
若多個 component 間有共用的 property,則可抽成 Mixin 讓多個 component 共用,類似 PHP 的 Trait。
Version
Vue 2.5.17
Vue CLI 3.0.5
Basics
todo-list.vue
import { fetchTodos } from '../api/todos.api'; const finishItem = function(index) { this.todos[index].completed = !this.todos[index].completed; }; const addItem = function() { const elem = { title: this.input, completed: false }; this.todos = [...this.todos, elem]; }; const error = e => console.log(e); const mounted = function() { const response = res => this.todos = res.data.slice(0, 5); fetchTodos() .then(response) .catch(error); }; const data = function() { return { input: '', todos: [], }; }; const methods = { finishItem, addItem, }; export default { name: 'todo-list', data, methods, mounted, };
15 行
const finishItem = function(index) { this.todos[index].completed = !this.todos[index].completed; }; const addItem = function() { const elem = { title: this.input, completed: false }; this.todos = [...this.todos, elem]; };
假設 finishItem()
與 addItem()
兩個 function 在多個 component 都共用,則可抽成 Mixin。
mixins/my-mixin.js
const finishItem = function(index) { this.todos[index].completed = !this.todos[index].completed; }; const addItem = function() { const elem = { title: this.input, completed: false }; this.todos = [...this.todos, elem]; }; const methods = { finishItem, addItem, }; export const myMixin = { methods, };
將 finishItem()
與 addItem()
兩個 function 移到 my-mixin.js
,由於其為 method,因此宣告 myMixin
object 並且 export 出去。
todo-list.vue
import { fetchTodos } from '../api/todos.api'; import { myMixin } from '../mixins/my-mixin'; const mounted = function() { const response = res => this.todos = res.data.slice(0, 5); const error = e => console.log(e); fetchTodos() .then(response) .catch(error); }; const data = function() { return { input: '', todos: [], }; }; export default { name: 'todo-list', mixins: [myMixin], data, mounted, };
第 2 行
import { myMixin } from '../mixins/my-mixin';
使用 Named Import 載入 myMixin
。
22 行
export default { name: 'todo-list', mixins: [myMixin], data, mounted, };
加入 mixins
property,使用 []
加入 myMixin
。
Option Merging
若 Mix 內的 property 與 component 的 property 衝突,則 Vue 有其 合併
的邏輯。
const myMixin = { data: function () { return { message: 'hello', foo: 'abc' } } }; new Vue({ mixins: [myMixin], data: function () { return { message: 'goodbye', bar: 'def' } }, created: function () { console.log(this.$data) // => { message: "goodbye", foo: "abc", bar: "def" } } });
myMixin
所提供的 data()
與原本 Vue Instance 的 data()
有衝突。
當 Mixin 有衝突時,Vue 所採取的策略是 Shallow Merge :
- 第一層 property 重複會合併
- 第二層之後 property 重複會以 component 為主
var mixin = { created: function () { console.log('mixin hook called') } } new Vue({ mixins: [mixin], created: function () { console.log('component hook called') } }) // => "mixin hook called" // => "component hook called"
Mixin 若造成 hooks 衝突,則先執行 mixin 的 hook,再執行 component 的 hook。
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"
foo()
與 bar()
因為名稱不同,所以會合併。
conflicting()
名稱衝突,但因為是 第二層
,所以 component 優先權高於 mixin。
Conclusion
- 若 component 間有共用的 property,可考慮使用 Mixin,但設計時應盡量避免名稱衝突
- Mixin 若名稱衝突則必須參考 Vue 的合併策略
Sample Code
完整的範例可以在我的 GitHub 上找到
Reference
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。