最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

實(shí)例教學(xué)如何寫(xiě)vue插件

 更新時(shí)間:2017年11月30日 10:10:45   投稿:laozhang  
本次小編通過(guò)一個(gè)簡(jiǎn)單的實(shí)例來(lái)教給大家如何寫(xiě)一個(gè)vue插件,以及需要注意的地方,如果有需要的讀者跟著學(xué)習(xí)一下吧。

在學(xué)習(xí)之前,先問(wèn)問(wèn)自己,為什么要編寫(xiě)vue的插件。

在一個(gè)項(xiàng)目中,尤其是大型項(xiàng)目,有很多部分需要復(fù)用,比如加載的loading動(dòng)畫(huà),彈出框。如果一個(gè)一個(gè)的引用也稍顯麻煩,而且在一個(gè)vue文件中引用的組件多了,會(huì)顯得代碼臃腫,所以才有了封裝vue插件的需求。

說(shuō)完需求,就來(lái)看看具體實(shí)現(xiàn)。目前我嘗試了兩種不一樣的插件編寫(xiě)的方法,逐個(gè)介紹。

這是我的項(xiàng)目目錄,大致的結(jié)構(gòu)解釋這樣,盡量簡(jiǎn)單,容易理解。

一個(gè)是loading插件,一個(gè)是toast插件,不同的地方在于:loading插件是作為組件引入使用,而toast插件是直接添加在掛載點(diǎn)里,通過(guò)方法改變狀態(tài)調(diào)用的。

目前使用起來(lái)是醬紫的:

toast插件

toast文件下有兩個(gè)文件,后綴為vue的文件就是這個(gè)插件的骨架,js文件一個(gè)是將這個(gè)骨架放入Vue全局中,并寫(xiě)明操作邏輯。

可以看一下toast.vue的內(nèi)容:

<template>
 <transition name="fade">
  <div v-show="show">
   {{message}}
  </div>

 </transition>
</template>

<script>
export default {
 data() {
 return {
  show: false,
  message: ""
 };
 }
};
</script>

<style lang="scss" scoped>
.toast {
 position: fixed;
 top: 40%;
 left: 50%;
 margin-left: -15vw;
 padding: 2vw;
 width: 30vw;
 font-size: 4vw;
 color: #fff;
 text-align: center;
 background-color: rgba(0, 0, 0, 0.8);
 border-radius: 5vw;
 z-index: 999;
}

.fade-enter-active,
.fade-leave-active {
 transition: 0.3s ease-out;
}
.fade-enter {
 opacity: 0;
 transform: scale(1.2);
}
.fade-leave-to {
 opacity: 0;
 transform: scale(0.8);
}
</style>

 

這里面主要的內(nèi)容只有兩個(gè),決定是否顯示的show和顯示什么內(nèi)容的message

粗看這里,有沒(méi)有發(fā)現(xiàn)什么問(wèn)題?

這個(gè)文件中并沒(méi)有props屬性,也就是無(wú)論是show也好,message也好,就沒(méi)有辦法通過(guò)父子組件通信的方式進(jìn)行修改,那他們是怎么正確處理的呢。別急,來(lái)看他的配置文件。

index.js:

import ToastComponent from './toast.vue'

const Toast = {};

// 注冊(cè)Toast
Toast.install = function (Vue) {
 // 生成一個(gè)Vue的子類(lèi)
 // 同時(shí)這個(gè)子類(lèi)也就是組件
 const ToastConstructor = Vue.extend(ToastComponent)
 // 生成一個(gè)該子類(lèi)的實(shí)例
 const instance = new ToastConstructor();

 // 將這個(gè)實(shí)例掛載在我創(chuàng)建的div上
 // 并將此div加入全局掛載點(diǎn)內(nèi)部
 instance.$mount(document.createElement('div'))
 document.body.appendChild(instance.$el)
 
 // 通過(guò)Vue的原型注冊(cè)一個(gè)方法
 // 讓所有實(shí)例共享這個(gè)方法 
 Vue.prototype.$toast = (msg, duration = 2000) => {
  instance.message = msg;
  instance.show = true;

  setTimeout(() => {
   
   instance.show = false;
  }, duration);
 }
}

export default Toast

 

這里的邏輯大致可以分成這么幾步:

創(chuàng)建一個(gè)空對(duì)象,這個(gè)對(duì)象就是日后要使用到的插件的名字。此外,這個(gè)對(duì)象中要有一個(gè)install的函數(shù)。使用vue的extend方法創(chuàng)建一個(gè)插件的構(gòu)造函數(shù)(可以看做創(chuàng)建了一個(gè)vue的子類(lèi)),實(shí)例化該子類(lèi),之后的所有操作都可以通過(guò)這個(gè)子類(lèi)完成。之后再Vue的原型上添加一個(gè)共用的方法。

這里需要著重提的是Vue.extend()。舉個(gè)例子,我們?nèi)粘J褂胿ue編寫(xiě)組件是這個(gè)樣子的:

Vue.component('MyComponent',{
 template:'<div>這是組件</div>'
})

 

這是全局組件的注冊(cè)方法,但其實(shí)這是一個(gè)語(yǔ)法糖,真正的運(yùn)行過(guò)程是這樣的:

let component = Vue.extend({
 template:'<div>這是組件</div>'
})

Vue.component('MyComponent',component)

 

Vue.extend會(huì)返回一個(gè)對(duì)象,按照大多數(shù)資料上提及的,也可以說(shuō)是返回一個(gè)Vue的子類(lèi),既然是子類(lèi),就沒(méi)有辦法直接通過(guò)他使用Vue原型上的方法,所以需要new一個(gè)實(shí)例出來(lái)使用。

在代碼里console.log(instance)

得出的是這樣的結(jié)果:

可以看到$el:div.toast

也就是toast組件模板的根節(jié)點(diǎn)。

疑惑的是,我不知道為什么要?jiǎng)?chuàng)建一個(gè)空的div節(jié)點(diǎn),并把這個(gè)實(shí)例掛載在上面。我嘗試注釋這段代碼,但是運(yùn)行會(huì)報(bào)錯(cuò)。

查找這個(gè)錯(cuò)誤的原因,貌似是因?yàn)?/p>

document.body.appendChild(instance.$el)

 

這里面的instance.$el的問(wèn)題,那好,我們console下這個(gè)看看。WTF?。。。〗Y(jié)果居然是undefined。

那接著

console.log(instance)

 

和上一張圖片比對(duì)一下,發(fā)現(xiàn)了什么?對(duì),$el消失了,換句話(huà)說(shuō)在我注釋了

instance.$mount(document.createElement('div'))

 

這句話(huà)之后,掛載點(diǎn)也不存在了。接著我試著改了一下這句:

instance.$mount(instance.$el)

 

$el又神奇的回來(lái)了………………

暫時(shí)沒(méi)有發(fā)現(xiàn)這種改動(dòng)有什么問(wèn)題,可以和上面一樣運(yùn)行。但無(wú)論如何,這也就是說(shuō)instance實(shí)例必須掛載在一個(gè)節(jié)點(diǎn)上才能進(jìn)行后續(xù)操作。

之后的代碼就簡(jiǎn)單了,無(wú)非是在Vue的原型上添加一個(gè)改變插件狀態(tài)的方法。之后導(dǎo)出這個(gè)對(duì)象。

接下來(lái)就是怎么使用的問(wèn)題了。來(lái)看看main.js是怎么寫(xiě)的:

import Vue from 'vue'
import App from './App'
// import router from './router'
import Toast from './components/taost'
Vue.use(Toast)

Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({

 // router,
 render: h => h(App)
}).$mount('#app')

 

這樣就可以在其他vue文件中直接使用了,像這樣:

// app.vue
<template>
 <div id="app">
 <loading duration='2s' :isshow='show'></loading>
 <!-- <button @click="show = !show">顯示/隱藏loading</button> -->
 <button @click="toast">顯示taost彈出框</button>
 </div>
</template>

<script>
export default {
 name: "app",
 data() {
 return {
  show: false
 };
 },
 methods: {
 toast() {
  this.$toast("你好");
 }
 }
};
</script>

<style>
#app {
 font-family: "Avenir", Helvetica, Arial, sans-serif;
 -webkit-font-smoothing: antialiased;
 -moz-osx-font-smoothing: grayscale;
 text-align: center;
 color: #2c3e50;
 margin-top: 60px;
}
</style>

通過(guò)在methods中增加一個(gè)方法控制寫(xiě)在Vue原型上的$toast對(duì)toast組件進(jìn)行操作。

這樣toast組件的編寫(xiě)過(guò)程就結(jié)束了,可以看到一開(kāi)始gif圖里的效果。

loading插件

經(jīng)過(guò)上一個(gè)插件的講解,這一部分就不會(huì)那么細(xì)致了,畢竟大多數(shù)都沒(méi)有什么不同,我只指出不一樣的地方。

<template>
 <div class='wrapper' v-if="isshow">
  <div class='loading'>
   <img src="./loading.gif">
  </div>
 </div>
</template>

<script>
export default {
 props: {
 duration: {
  type: String,
  default: "1s" //默認(rèn)1s
 },
 isshow: {
  type: Boolean,
  default: false
 }
 },
 data: function() {
 return {};
 }
};
</script>

<style lang="scss" scoped>

</style>

這個(gè)就只是一個(gè)模板,傳入兩個(gè)父組件的數(shù)據(jù)控制顯示效果。

那再來(lái)看一下該插件的配置文件:

import LoadingComponent from './loading.vue'

let Loading = {};

Loading.install = (Vue) => {
 Vue.component('loading', LoadingComponent)
}

export default Loading;

這個(gè)和taoat的插件相比,簡(jiǎn)單了很多,依然是一個(gè)空對(duì)象,里面有一個(gè)install方法,然后在全局注冊(cè)了一個(gè)組件。

比較

那介紹了這兩種不同的插件編寫(xiě)方法,貌似沒(méi)有什么不一樣啊,真的是這樣么?

來(lái)看一下完整的main.js和app.vue這兩個(gè)文件:

// main.js
import Vue from 'vue'
import App from './App'
// import router from './router'
import Toast from './components/taost'
import Loading from './components/loading'

Vue.use(Toast)

Vue.use(Loading)

Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({

 // router,
 render: h => h(App)
}).$mount('#app')

// app.vue
<template>
 <div id="app">
 <loading duration='2s' :isshow='show'></loading>
 <!-- <button @click="show = !show">顯示/隱藏loading</button> -->
 <button @click="toast">顯示taost彈出框</button>
 </div>
</template>

<script>
export default {
 name: "app",
 data() {
 return {
  show: false
 };
 },
 methods: {
 toast() {
  this.$toast("你好");
 }
 }
};
</script>

<style>
#app {
 font-family: "Avenir", Helvetica, Arial, sans-serif;
 -webkit-font-smoothing: antialiased;
 -moz-osx-font-smoothing: grayscale;
 text-align: center;
 color: #2c3e50;
 margin-top: 60px;
}
</style>

可以看出來(lái),loading是顯示的寫(xiě)在app.vue模板里的,而toast并沒(méi)有作為一個(gè)組件寫(xiě)入,僅僅是通過(guò)一個(gè)方法控制顯示。

來(lái)看一下html結(jié)構(gòu)和vue工具給出的結(jié)構(gòu):

看出來(lái)了么,toast插件沒(méi)有在掛載點(diǎn)里面,而是獨(dú)立存在的,也就是說(shuō)當(dāng)執(zhí)行

vue.use(toast)

之后,該插件就是生成好的了,之后的所有操作無(wú)非就是顯示或者隱藏的問(wèn)題了。

相關(guān)文章

  • vue實(shí)現(xiàn)的封裝全局filter并統(tǒng)一管理操作示例

    vue實(shí)現(xiàn)的封裝全局filter并統(tǒng)一管理操作示例

    這篇文章主要介紹了vue實(shí)現(xiàn)的封裝全局filter并統(tǒng)一管理操作,結(jié)合實(shí)例形式詳細(xì)分析了vue封裝全局filter及相關(guān)使用技巧,需要的朋友可以參考下
    2020-02-02
  • vue3中實(shí)現(xiàn)異步組件的方法實(shí)例

    vue3中實(shí)現(xiàn)異步組件的方法實(shí)例

    前端開(kāi)發(fā)經(jīng)常遇到異步的問(wèn)題,請(qǐng)求函數(shù)、鏈接庫(kù)等,下面這篇文章主要給大家介紹了關(guān)于vue3中實(shí)現(xiàn)異步組件的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-06-06
  • Vue.js -- 過(guò)濾器使用總結(jié)

    Vue.js -- 過(guò)濾器使用總結(jié)

    本篇文章主要介紹了Vue.js -- 過(guò)濾器使用總結(jié),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-02-02
  • VUE中操作dom元素的幾種方法(最新推薦)

    VUE中操作dom元素的幾種方法(最新推薦)

    本文給大家總結(jié)了Vue中操作dom元素的多種方法,每種方法結(jié)合實(shí)例代碼給大家講解的非常詳細(xì),需要的朋友參考下吧
    2022-12-12
  • vue實(shí)現(xiàn)單點(diǎn)登錄的方式匯總

    vue實(shí)現(xiàn)單點(diǎn)登錄的方式匯總

    最近項(xiàng)目停工了,RageFrame的學(xué)習(xí)暫時(shí)告一段落,這一篇給大家分享下有關(guān)單點(diǎn)登錄的相關(guān)知識(shí),并提供一些demo給大家參考,對(duì)vue單點(diǎn)登錄的實(shí)現(xiàn)方式感興趣的朋友一起看看吧
    2021-11-11
  • vue3表單參數(shù)校驗(yàn)及正則表達(dá)式舉例詳解

    vue3表單參數(shù)校驗(yàn)及正則表達(dá)式舉例詳解

    最近項(xiàng)目中有一個(gè)校驗(yàn)身份證號(hào)手機(jī)號(hào)的業(yè)務(wù),索性給大家總結(jié)下,這篇文章主要給大家介紹了關(guān)于vue3表單參數(shù)校驗(yàn)及正則表達(dá)式的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-04-04
  • vue+intro.js插件實(shí)現(xiàn)引導(dǎo)功能

    vue+intro.js插件實(shí)現(xiàn)引導(dǎo)功能

    使用 intro.js這個(gè)插件,來(lái)實(shí)現(xiàn)一個(gè)引導(dǎo)性的效果,經(jīng)常在一些新手引導(dǎo)頁(yè)遇到這樣的需求,下面通過(guò)本文給大家分享vue+intro.js插件實(shí)現(xiàn)引導(dǎo)功能,感興趣的朋友一起看看吧
    2024-06-06
  • 如何使用el-table實(shí)現(xiàn)純前端導(dǎo)出(適用于el-table任意表格)

    如何使用el-table實(shí)現(xiàn)純前端導(dǎo)出(適用于el-table任意表格)

    我們?nèi)粘W鲰?xiàng)目,特別是后臺(tái)管理系統(tǒng),常常需要導(dǎo)出excel文件,這篇文章主要給大家介紹了關(guān)于如何使用el-table實(shí)現(xiàn)純前端導(dǎo)出的相關(guān)資料,本文適用于el-table任意表格,需要的朋友可以參考下
    2024-03-03
  • vue打包優(yōu)化時(shí)配置webpack的8大方案小結(jié)

    vue打包優(yōu)化時(shí)配置webpack的8大方案小結(jié)

    vue-cli?生成的項(xiàng)目通常集成Webpack?,在打包的時(shí)候,需要webpack來(lái)做一些事情,這里我們希望它可以壓縮代碼體積,提高運(yùn)行效率,本文為大家整理了8大webpack配置方案,希望對(duì)大家有所幫助
    2024-02-02
  • vue腳手架搭建項(xiàng)目的兼容性配置詳解

    vue腳手架搭建項(xiàng)目的兼容性配置詳解

    這篇文章主要介紹了vue腳手架搭建項(xiàng)目的兼容性配置詳解,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-07-07

最新評(píng)論

安化县| 宜都市| 乐安县| 汝州市| 惠安县| 崇信县| 建阳市| 烟台市| 肥城市| 黄骅市| 治多县| 利辛县| 汝州市| 油尖旺区| 锡林浩特市| 湖南省| 西宁市| 内江市| 垦利县| 漳浦县| 泉州市| 吉安市| 祁阳县| 天等县| 新源县| 凭祥市| 娱乐| 东兴市| 开封县| 宜阳县| 新昌县| 新郑市| 台江县| 垦利县| 肥乡县| 石狮市| 寻乌县| 满洲里市| 公主岭市| 杨浦区| 和林格尔县|