Vue插件寫、用詳解(附demo)
Vue插件
1、概述
簡(jiǎn)單來說,插件就是指對(duì)Vue的功能的增強(qiáng)或補(bǔ)充。
比如說,讓你在每個(gè)單頁面的組件里,都可以調(diào)用某個(gè)方法,或者共享使用某個(gè)變量,或者在某個(gè)方法之前執(zhí)行一段代碼等
2、使用方法
總體流程應(yīng)該是:
【聲明插件】——【寫插件】——【注冊(cè)插件】——【使用插件】
寫插件和聲明插件是同步的,然后注冊(cè)到Vue對(duì)象中(不用擔(dān)心重復(fù)注冊(cè)),最后在寫Vue組件的時(shí)候使用寫的插件
聲明插件
先寫一個(gè)js文件,這個(gè)js文件就是插件文件,里面的基本內(nèi)容如下:
/* 說明:
* 插件文件:service.js
* 作者:王冬 QQ:20004604
* */
export default {
install: function (Vue, options) {
// 添加的內(nèi)容寫在這個(gè)函數(shù)里面
}
};
其中install的第一個(gè)參數(shù)Vue表示的是Vue的實(shí)例,第二個(gè)參數(shù)表示的是一些設(shè)置選項(xiàng)。
Vue實(shí)例好理解,就是Vue對(duì)象。
而options設(shè)置選項(xiàng)就是指,在調(diào)用這個(gè)插件時(shí),可以傳一個(gè)對(duì)象。
例如這個(gè)對(duì)象有一個(gè)屬性float,然后在寫插件的一個(gè)方法/變量時(shí),我需要輸出一個(gè)數(shù)字,然后寫一個(gè)if判斷語句,
假如options.float為true時(shí),輸出浮點(diǎn)數(shù);
假如為false或undefined(即沒傳參)時(shí),輸出為整數(shù)。
具體怎么添加,之后再說。
注冊(cè)插件
如果使用過Vue-router,就很好理解,通過import引入后,然后通過 Vue.use(插件名) 注冊(cè)插件;
例如,我們通常在main.js里引入各種東西,并且組件的根實(shí)例也在這里
//main.js
import Vue from 'vue'
import App from './App.vue'
//關(guān)鍵是這兩行
import service from './service.js'
Vue.use(service)
new Vue({
el: '#app',
render: (h) => h(App)
})
如代碼中注釋所說,關(guān)鍵是通過import導(dǎo)入service文件,然后在創(chuàng)建根組件之前,讓Vue對(duì)象通過use方法來注冊(cè)插件service。
通過這樣簡(jiǎn)單的兩步,就可以使用插件了。
3、寫插件、使用插件
按照官方文檔,寫插件有四種方法,先給出官方的代碼:
//以下內(nèi)容都是添加到上面install的函數(shù)里面的
// 1. 添加全局方法或?qū)傩?
Vue.myGlobalMethod = function () {
// 邏輯...
}
// 2. 添加全局資源
Vue.directive('my-directive', {
bind (el, binding, vnode, oldVnode) {
// 邏輯...
}
...
})
// 3. 注入組件
Vue.mixin({
created: function () {
// 邏輯...
}
...
})
// 4. 添加實(shí)例方法
Vue.prototype.$myMethod = function (options) {
// 邏輯...
}
先給出最常用的:【4. 添加實(shí)例方法】的寫法和使用方法
3.1【添加實(shí)例方法或?qū)傩浴?/strong>
1、核心思想:
通過prototype來添加方法和屬性。
2、寫:
//讓輸出的數(shù)字翻倍,如果不是數(shù)字或者不能隱式轉(zhuǎn)換為數(shù)字,則輸出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
}
}
3、用:
假設(shè)有這樣一個(gè)組件:
<template>
<div>
{{num}}
<button @click="double">點(diǎn)擊后讓左邊的數(shù)字翻倍</button>
</div>
</template>
<script>
export default{
data(){
return {
num: 1
}
},
methods: {
double: function () {
//這里的this.doubleNumber()方法就是上面寫的組件里的方法
this.num = this.doubleNumber(this.num);
}
}
}
</script>
我們便可以通過點(diǎn)擊button按鈕,讓num的值,在每次點(diǎn)擊都翻倍了。
4、假如添加的是屬性:
例如:
Vue.prototype.number = 1;
會(huì)發(fā)生什么事情呢?
1、不管是【按值傳遞類型】還是【按引用傳遞類型】,該變量都不會(huì)被不同組件所共享,更準(zhǔn)確的說,假如有A、B兩個(gè)組件。A組件里的number數(shù)值改變,B組件里的number數(shù)值是不會(huì)跟著改變的。因此不要想著引用這樣一個(gè)變量,然后修改了A中的值,B里也自動(dòng)跟著改變了;
2、當(dāng)組件里沒有該屬性時(shí),調(diào)用時(shí),顯示的是通過插件獲取的值;
當(dāng)組件里有該屬性時(shí),調(diào)用時(shí),顯示的是組件里該屬性的值;
由此而推,函數(shù)也是這樣的,組件里的同名函數(shù)總是會(huì)覆蓋插件提供的函數(shù)。
也就是說,當(dāng)插件提供一個(gè)屬性時(shí),組件里沒這個(gè)屬性,就用插件的屬性;組件有,就用組件自己的。
3.2【添加全局方法或?qū)傩浴?/strong>
1、核心思想:
就是給Vue對(duì)象添加一個(gè)屬性。
初次接觸很容易和上面3.1弄混,實(shí)際上,3.1是給組件里使用的,而3.2是給Vue對(duì)象使用的。
例如,假如添加一個(gè)方法test(),那么:
通過3.1添加,是在組件里,通過this.test()來調(diào)用
通過3.2添加,是在外面,通過Vue實(shí)例,如Vue.test()來調(diào)用
2、寫:
//放在哪里參考上面
Vue.test = function () {
alert("123")
}
3、用:
//注意先導(dǎo)入Vue對(duì)象才能使用 Vue.test()
使用時(shí)會(huì)執(zhí)行對(duì)應(yīng)的方法,比如這里就是alert彈窗
4、其他:
別問我如果和Vue本身屬性同名會(huì)發(fā)生什么事情,我沒試過=.=
3.3【注入組件】
1、核心思想:
就像寫Vue組件時(shí),那樣寫,方法名保持一致,其會(huì)在執(zhí)行組件對(duì)應(yīng)的方法名之前執(zhí)行。
2、寫:
例如:
Vue.mixin({
created: function () {
console.log("組件開始加載")
}
})
然后這里的代碼會(huì)在每個(gè)組件(包括根組件)的created執(zhí)行之前執(zhí)行。
可以自行在每個(gè)組件的created方法里寫一段console.log來查看測(cè)試
可以和【實(shí)例屬性】配合使用,用于調(diào)試或者控制某些功能
// 注入組件
Vue.mixin({
created: function () {
if (this.NOTICE)
console.log("組件開始加載")
}
})
// 添加注入組件時(shí),是否利用console.log來通知的判斷條件
Vue.prototype.NOTICE = false;
【注入給非Vue實(shí)例本身就有的方法】:
假如是寫給例如methods屬性的某個(gè)方法,例如以下注入:
Vue.mixin({
methods: {
test: function () {
console.log("mixin test");
}
}
})
那么,組件里若本身有test方法,并 不會(huì) 先執(zhí)行插件的test方法,再執(zhí)行組件的test方法。
而是只執(zhí)行其中一個(gè),并且優(yōu)先執(zhí)行組件本身的同名方法。這點(diǎn)需要注意
3、用:
不需要手動(dòng)調(diào)用,在執(zhí)行對(duì)應(yīng)的方法時(shí)會(huì)被自動(dòng)調(diào)用的(并且先調(diào)用插件里的,再調(diào)用組件本身的)
4、其他:
1、如果同時(shí)有多個(gè)插件注入一個(gè)方法(例如created,那么會(huì)先執(zhí)行先注入的那個(gè)方法,再依次執(zhí)行后注入的,最后執(zhí)行組件本身的)
2、注意,像methods屬性下的方法,并不會(huì)在組件注入后每個(gè)都執(zhí)行,而是只執(zhí)行一個(gè),并且優(yōu)先執(zhí)行組件本身的。
3.4【添加全局資源】
1、核心思想:
添加方法和正常添加方法類似,甚至幾乎一樣。
可以添加【自定義指令】、【過濾器】、【過渡等】,這里以【過濾器】為例
2、寫:
例如:
//時(shí)間格式化過濾器,輸入內(nèi)容是number或者Date對(duì)象,輸出是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(), //小時(shí)
"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");
})
3、用:
和正常使用一樣用就行了,so easy。例如:
{{num|formatTime}}
4、其他:
可以用這個(gè)找各種有意思的功能,作為插件寫好,然后需要的地方導(dǎo)入就行,超級(jí)方便!
4、示例demo
附一個(gè)有簡(jiǎn)單功能的示例demo,提供參考使用
/* 說明:
* 插件demo,供學(xué)習(xí)使用
* 本頁面用于提供各種處理服務(wù)
* 作者:王冬 QQ:20004604
* */
export default {
install: function (Vue, options) {
// 1. 添加全局方法或?qū)傩?
// 略
// 2. 添加全局資源
// 時(shí)間格式化過濾器,輸入內(nèi)容是number或者Date對(duì)象,輸出是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(), //小時(shí)
"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. 添加全局資源
// 添加注入組件時(shí),是否利用console.log來通知的判斷條件,也是組件實(shí)例屬性
Vue.prototype.NOTICE = true;
// 3. 注入組件
// 注入組件,插件加載開始前提示
Vue.mixin({
created: function () {
if (this.NOTICE)
console.log("組件開始加載")
},
methods: {
test: function () {
console.log("mixin test");
}
}
})
// 4. 添加實(shí)例方法
// 返回?cái)?shù)字是輸入數(shù)字的兩倍,如果不是數(shù)字或者不能隱式轉(zhuǎn)換為數(shù)字,則輸出null
// 組件實(shí)例方法
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. 添加實(shí)例方法
// 服務(wù)組,將實(shí)例方法整合到$service中,避免命名沖突
Vue.prototype.$service = {
//電話號(hào)碼合法性檢查
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)
}
}
}
};
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Vue 簡(jiǎn)單實(shí)現(xiàn)前端權(quán)限控制的示例
這篇文章主要介紹了Vue 簡(jiǎn)單實(shí)現(xiàn)前端權(quán)限控制的示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12
Vuex數(shù)據(jù)持久化的兩種方式:手動(dòng)存儲(chǔ)和vuex-persistedstate插件詳解
這篇文章主要介紹了Vuex數(shù)據(jù)持久化的兩種方式:手動(dòng)存儲(chǔ)和vuex-persistedstate插件,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-08-08
vue從一個(gè)頁面跳轉(zhuǎn)到另一個(gè)頁面并攜帶參數(shù)的解決方法
這篇文章主要介紹了vue從一個(gè)頁面跳轉(zhuǎn)到另一個(gè)頁面并攜帶參數(shù)的解決方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08
Vue通過阿里云oss的url連接直接下載文件并修改文件名的方法
這篇文章主要介紹了Vue通過阿里云oss的url連接直接下載文件并修改文件名的方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12
Vue-router結(jié)合transition實(shí)現(xiàn)app前進(jìn)后退動(dòng)畫切換效果的實(shí)例
下面小編就為大家?guī)硪黄猇ue-router結(jié)合transition實(shí)現(xiàn)app前進(jìn)后退動(dòng)畫切換效果的實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-10-10

