Vue插件編寫、用法詳解(附demo)

Vue插件編寫、用法詳解(附demo)javascript

一、概述

簡單來講,插件就是指對Vue的功能的加強或補充。css

好比說,讓你在每一個單頁面的組件裏,均可以調用某個方法,或者共享使用某個變量,或者在某個方法以前執行一段代碼等vue

二、使用方法

整體流程應該是:java

【聲明插件】——【寫插件】——【註冊插件】——【使用插件】node

寫插件和聲明插件是同步的,而後註冊到Vue對象中(不用擔憂重複註冊),最後在寫Vue組件的時候使用寫的插件express

聲明插件

先寫一個js文件,這個js文件就是插件文件,裏面的基本內容以下:app

/* 說明: * 插件文件:service.js * 做者:王冬 QQ:20004604 * */ export default { install: function (Vue, options) { // 添加的內容寫在這個函數裏面 } };

其中install的第一個參數Vue表示的是Vue的實例,第二個參數表示的是一些設置選項。函數

Vue實例好理解,就是Vue對象。學習

而options設置選項就是指,在調用這個插件時,能夠傳一個對象。測試

例如這個對象有一個屬性float,而後在寫插件的一個方法/變量時,我須要輸出一個數字,而後寫一個if判斷語句,

假如options.float爲true時,輸出浮點數;

假如爲false或undefined(即沒傳參)時,輸出爲整數。

具體怎麼添加,以後再說。

註冊插件

若是使用過Vue-router,就很好理解,經過import引入後,而後經過 Vue.use(插件名) 註冊插件;

例如,咱們一般在main.js裏引入各類東西,而且組件的根實例也在這裏

//main.js import Vue from 'vue' import App from './App.vue' //關鍵是這兩行 import service from './service.js' Vue.use(service) new Vue({ el: '#app', render: (h) => h(App) })

如代碼中註釋所說,關鍵是經過import導入service文件,而後在建立根組件以前,讓Vue對象經過use方法來註冊插件service。

經過這樣簡單的兩步,就可使用插件了。

三、寫插件、使用插件

按照官方文檔,寫插件有四種方法,先給出官方的代碼:

//如下內容都是添加到上面install的函數裏面的

// 1. 添加全局方法或屬性 Vue.myGlobalMethod = function () { // 邏輯... } // 2. 添加全局資源 Vue.directive('my-directive', { bind (el, binding, vnode, oldVnode) { // 邏輯... } ... }) // 3. 注入組件 Vue.mixin({ created: function () { // 邏輯... } ... }) // 4. 添加實例方法 Vue.prototype.$myMethod = function (options) { // 邏輯... }

先給出最經常使用的:【4. 添加實例方法】的寫法和使用方法

3.1【添加實例方法或屬性】

一、核心思想:

經過prototype來添加方法和屬性。

二、寫:

//讓輸出的數字翻倍,若是不是數字或者不能隱式轉換爲數字,則輸出null
Vue.prototype.doubleNumber = function (val) {
    if (typeof val === 'number') {
        return val * 2;
    } else if (!isNaN(Number(val))) {
        return Number(val) * 2;
    } else {
        return null
    }
}

三、用:

假設有這樣一個組件:

<template> <div> {{num}} <button @click="double">點擊後讓左邊的數字翻倍</button> </div> </template> <script> export default{ data(){ return { num: 1 } }, methods: { double: function () { //這裏的this.doubleNumber()方法就是上面寫的組件裏的方法 this.num = this.doubleNumber(this.num); } } } </script>

咱們即可以經過點擊button按鈕,讓num的值,在每次點擊都翻倍了。

四、假如添加的是屬性:

例如:

Vue.prototype.number = 1;

會發生什麼事情呢?

一、不論是【按值傳遞類型】仍是【按引用傳遞類型】,該變量都不會被不一樣組件所共享,更準確的說,假若有A、B兩個組件。A組件裏的number數值改變,B組件裏的number數值是不會跟着改變的。所以不要想着引用這樣一個變量,而後修改了A中的值,B裏也自動跟着改變了;
二、當組件裏沒有該屬性時,調用時,顯示的是經過插件獲取的值;
   當組件裏有該屬性時,調用時,顯示的是組件裏該屬性的值;
   由此而推,函數也是這樣的,組件裏的同名函數老是會覆蓋插件提供的函數。

也就是說,當插件提供一個屬性時,組件裏沒這個屬性,就用插件的屬性;組件有,就用組件本身的。

3.2【添加全局方法或屬性】

一、核心思想:

就是給Vue對象添加一個屬性。

初次接觸很容易和上面3.1弄混,實際上,3.1是給組件裏使用的,而3.2是給Vue對象使用的。

例如,假如添加一個方法test(),那麼:

經過3.1添加,是在組件裏,經過this.test()來調用

經過3.2添加,是在外面,經過Vue實例,如Vue.test()來調用

二、寫:

//放在哪裏參考上面 Vue.test = function () { alert("123") }

三、用:

//注意先導入Vue對象才能使用 Vue.test()

使用時會執行對應的方法,好比這裏就是alert彈窗

四、其餘:

別問我若是和Vue自己屬性同名會發生什麼事情,我沒試過=.=

3.3【注入組件】

一、核心思想:

就像寫Vue組件時,那樣寫,方法名保持一致,其會在執行組件對應的方法名以前執行。

二、寫:

例如:

Vue.mixin({ created: function () { console.log("組件開始加載") } })

而後這裏的代碼會在每一個組件(包括根組件)的created執行以前執行。

能夠自行在每一個組件的created方法裏寫一段console.log來查看測試

能夠和【實例屬性】配合使用,用於調試或者控制某些功能

// 注入組件 Vue.mixin({ created: function () { if (this.NOTICE) console.log("組件開始加載") } }) // 添加註入組件時,是否利用console.log來通知的判斷條件 Vue.prototype.NOTICE = false;

【注入給非Vue實例自己就有的方法】:

假如是寫給例如methods屬性的某個方法,例如如下注入:

Vue.mixin({ methods: { test: function () { console.log("mixin test"); } } })

那麼,組件裏若自己有test方法,並 不會 先執行插件的test方法,再執行組件的test方法。

而是隻執行其中一個,而且優先執行組件自己的同名方法。這點須要注意

三、用:

不須要手動調用,在執行對應的方法時會被自動調用的(而且先調用插件裏的,再調用組件自己的)

四、其餘:

一、若是同時有多個插件注入一個方法(例如created,那麼會先執行先注入的那個方法,再依次執行後注入的,最後執行組件自己的)
二、注意,像methods屬性下的方法,並不會在組件注入後每一個都執行,而是隻執行一個,而且優先執行組件自己的。

3.4【添加全局資源】

一、核心思想:

添加方法和正常添加方法相似,甚至幾乎同樣。

能夠添加【自定義指令】、【過濾器】、【過渡等】,這裏以【過濾器】爲例

二、寫:

例如:

//時間格式化過濾器,輸入內容是number或者Date對象,輸出是YYYY-MM-DD HH-MM-SS Vue.filter('formatTime', function (value) { Date.prototype.Format = function (fmt) { //author: meizz var o = { "M+": this.getMonth() + 1, //月份 "d+": this.getDate(), //日 "h+": this.getHours(), //小時 "m+": this.getMinutes(), //分 "s+": this.getSeconds(), //秒 "q+": Math.floor((this.getMonth() + 3) / 3), //季度 "S": this.getMilliseconds() //毫秒 }; if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length)); for (var k in o) if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length))); return fmt; } return new Date(value).Format("yyyy-MM-dd hh:mm:ss"); })

三、用:

和正常使用同樣用就好了,so easy。例如:

{{num|formatTime}}

四、其餘:

能夠用這個找各類有意思的功能,做爲插件寫好,而後須要的地方導入就行,超級方便!

四、示例demo

附一個有簡單功能的示例demo,提供參考使用

/* 說明: * 插件demo,供學習使用 * 本頁面用於提供各類處理服務 * 做者:王冬 QQ:20004604 * */ export default { install: function (Vue, options) { // 1. 添加全局方法或屬性 // 略 // 2. 添加全局資源 // 時間格式化過濾器,輸入內容是number或者Date對象,輸出是YYYY-MM-DD HH-MM-SS Vue.filter('formatTime', function (value) { Date.prototype.Format = function (fmt) { //author: meizz var o = { "M+": this.getMonth() + 1, //月份 "d+": this.getDate(), //日 "h+": this.getHours(), //小時 "m+": this.getMinutes(), //分 "s+": this.getSeconds(), //秒 "q+": Math.floor((this.getMonth() + 3) / 3), //季度 "S": this.getMilliseconds() //毫秒 }; if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length)); for (var k in o) if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length))); return fmt; } return new Date(value).Format("yyyy-MM-dd hh:mm:ss"); }) // 2. 添加全局資源 // 添加註入組件時,是否利用console.log來通知的判斷條件,也是組件實例屬性 Vue.prototype.NOTICE = true; // 3. 注入組件 // 注入組件,插件加載開始前提示 Vue.mixin({ created: function () { if (this.NOTICE) console.log("組件開始加載") }, methods: { test: function () { console.log("mixin test"); } } }) // 4. 添加實例方法 // 返回數字是輸入數字的兩倍,若是不是數字或者不能隱式轉換爲數字,則輸出null // 組件實例方法 Vue.prototype.doubleNumber = function (val) { if (typeof val === 'number') { return val * 2; } else if (!isNaN(Number(val))) { return Number(val) * 2; } else { return null } } // 4. 添加實例方法 // 服務組,將實例方法整合到$service中,避免命名衝突 Vue.prototype.$service = { //電話號碼合法性檢查 telNumberCheck: function (tel) { var pattern = /(^(([0\+]\d{2,3}-)?(0\d{2,3})-)(\d{7,8})(-(\d{3,}))?$)|(^0{0,1}1[3|4|5|6|7|8|9][0-9]{9}$)/; return pattern.test(tel) } } } };
相關文章
相關標籤/搜索