[Vue.js] global method 的復用
情境
我們可能需要為 Vue 專案添加自定義 method,重點是每個 component 都有可能用到,有什麼方法可以不用一直複製貼上?
例如原生 JS 操作瀏覽器 cookie 總是很囉唆,可以用幾個 function 包起來用:
1 | function setCookie(name, value, expireDays){ |
看來可以當 Vue method 了,但難道我一個 component 用到一次就要再寫一次嗎?直覺想到ES6的import
好像有辦法用,那要如何跟 Vue instance 好好合作呢?
寫成 Mixins
Mixins 能提供 Vue instance 屬性定義的復用。若 component 的 method 與 mixin 的衝突,會以 component 為主。
Mixins 不只能混入 method,還包括 data, lifecycle-hook 等其他屬性,但 merge 後的行為不盡相同,像是
created()
mixin 後比較像堆疊而不是覆寫,有興趣可以翻翻文件
建立一個 export
object 的 js 檔,把自定義 method 寫入 methods
屬性裡:
1 | export const cookieMixin = { |
在 component 使用 mixin
只要引入 js 檔並用Array assign 給 mixins
屬性:
1 | import {cookieMixin} from 'cookieMixin.js' |
如此這個 component 便能使用 this.setCookie()
等 method。
Global mixin
若想在每一個 component 中引用,不用每個文件都寫個 import
,而是直接在入口 JS 文件定義:
1 | import {cookieMixin} from 'cookieMixin.js' |
注意 global mixin 會影響所有Vue instance,包括第三方引入的 component,用於 data 或 lifecycle-hook 更是要謹慎設計。
使用Vue.prototype
另一種方法,利用JS的原型鏈將自定義 method 掛到 Vue instance上,在入口 JS 文件定義:
1 | Vue.prototype.$setCookie = function(name, value, expireDays){ ... }, |
如此一來不需要用 mxixns
,各 component 也能直接呼叫 this.$setCookie(...)
原型鏈上自定義 method 加錢號
$
的原因,是避免與 component 中this
所 proxy 的 data, computed, method 等命名空間互衝突,也聲明其特殊性,算是開發潛規則
嗯?錢號? this.$store
…this.$router
…うっ、頭が
這種熟悉感不是巧合,Vue 生態系的套件就是以此套路開發的,只是再包成 Vue plugin 使用,寫到這覺得 Vue 真的是很優雅靈活,各種應用游刃有餘又不會賣弄艱澀語法,佩服作者的設計與發揮 JS 特性能力。
包成 Plugin
既然都講到這地步了,乾脆把自定義 method 做成一個 vue-cookie plugin ( Github 真的有這個 plugin )
整理一下 code,其實可以用 object 比較乾淨:
1 | Vue.prototype.$cookie = { |
建立一個 vue-cookie.js , export
輸出 install(Vue, options)
這個 function,Vue
作為參數帶入,然後將 method 寫進 install
裡:
1 | export default { |
入口 js 文件 import
進來就是個 plugin,使用Vue.use
載入 :
1 | import VueCookie from './vue-cookie.js' |
就能在 App 中使用 this.$cookie.set()
了。搞不好能放到 npm 給別人用呢~