在這篇文章中介紹了toast是什么,這篇文章主要介紹toast的開發與使用。
開發
Vuejs很流行,並且官方也給出了路由插件vue-router、數據管理插件vuex,但是我們僅僅停留在了使用的階段,如果能夠嘗試一下自己開發,並且npm上傳,那么對於個人的進步我想還是很大的。
什么是插件
Vue.js的插件有一個公開方法install, 這個方法的第一個參數是Vue構造器,第二個參數是一個可選的選項對象。 如// MyPlugin就是插件的名稱, 所有的插件都需要使用install這個公開方// 第一個參數是Vue構造器,因此我們可以在這個方法中使用Vue, 第二個參數是一個選項對象。
MyPlugin.install = function (Vue, options) { Vue.myGlobalMethod = function () { // 1. 添加全局方法或屬性,如: vue-custom-element // 邏輯... }
// 這里通過 Vue.directive 來進行自定義指令。
// 其中my-derective就是指令的名稱。
// bind是自定義指令提供的鈎子函數。而el、binding、vnodes、oldVnode都是鈎子函數綁定的參數
Vue.directive('my-directive', { // 2. 添加全局資源:指令/過濾器/過渡等,如 vue-touch bind (el, binding, vnode, oldVnode) { // 邏輯... } ... }) Vue.mixin({ created: function () { // 3. 通過全局 mixin方法添加一些組件選項,如: vuex // 邏輯... } ... }) Vue.prototype.$myMethod = function (options) { // 4. 添加實例方法,通過把它們添加到 Vue.prototype 上實現 // 邏輯... } }
(補充:Vue自定義指令)
下面要講的 vue-toast 插件就是通過添加實例方法來實現的, 比如下面的這個例子,首先新建一個js文件來編寫插件: speak.js
var Speak = {}; Speak.install = function (Vue, options) { Vue.prototype.$words = "Hello, John!" } module.exports = Speak;
即 Speak 就是插件的名稱,我們綁定了一個$words 屬性。 定義好了之后,導出。
在main.js中,需要導入 Speak.js 並且通過全局方法 Vue.use() 來使用插件。(比如我們所用的vuex和vue-router都是先在 main.js 中導入,然后必須使用 Vue.use)。
// The Vue build version to load with the `import` command // (runtime-only or standalone) has been set in webpack.base.conf with an alias. import Vue from 'vue' import router from './router' import store from './store/'
import Speak from './assets/js/speak.js' Vue.use(Speak) Vue.config.productionTip = false /* eslint-disable no-new */ new Vue({ el: '#app', router, store, })
最后,我們就可以在組件中來獲取到該插件定義的$words 屬性了,
// Personal.vue export default { created(){ alert(this.$words); // Hello John! } }
然后我們我就可以發現這個組件生效了。
開發 vue-toast
實現需求:
同之前舉例一樣,在main.js引入之后可以在組件中通過調用 this.$toast("網絡請求失敗") 來彈出提示, 默認在底部顯示,我們還可以通過 this.$toast.top() 或者 this.$toast.center() 等方法來實現在其他位置的顯示。
思路:
其實toast還是很簡單的,就是提示消息,並在一定時間內自動清除,所以,需要提示的時候,我們可以在body中添加一個div來顯示提示信息, 而不同的位置通過添加不同的類名定位。
start!
// toast.js var Toast = {}; Toast.install = function (Vue, options) { Vue.prototype.$toast = (tips) => { let toastTpl = Vue.extend({ // 1、創建構造器,定義好提示信息的模板 template: '<div class="vue-toast">' + tips + '</div>' }); let tpl = new toastTpl().$mount().$el; // 2、創建實例,掛載到文檔以后的地方 document.body.appendChild(tpl); // 3、把創建的實例添加到body中 setTimeout(function () { // 4、延遲2.5秒后移除該提示 document.body.removeChild(tpl); }, 2500) } } module.exports = Toast;
通過上面寥寥十幾行代碼我們就實現了this.$toast,接下來就可以顯示不同的位置。
即首先定義Toast這個插件,然后在Vue上定義實例方法 toast , 這個方法中,我們首先創建一個構造器,然后通過new來實例化一個實例並掛在到$el(即Vue掛載的元素)上, 這樣,一個定義好的模板就實現了,接着我們將它插入到DOM中,等到一段時間之后 (如2500ms) 就移除這個div。 而其中的tips可以是一個字符串,即我們希望提示的信息。這樣我們就可以通過 this.$toast("新建地址成功!") 來使用 toast 了!
補充知識:
// toast.js ['bottom', 'center', 'top'].forEach(type => { Vue.prototype.$toast[type] = (tips) => { return Vue.prototype.$toast(tips,type) } })
這里,我們將bottom、center、top所組成的數組進行遍歷來設置 $toast[type]方法,這樣就是我們就可以通過$toast.type來調用了, 而$toast[type]方法顯然都是一個函數,他們接受一個參數tips, 最后返回一個對應的方法Vue.prototype.$toast(tips,type)。
可以看到這時候我們就需要重新修改一個$toast方法了:
Vue.prototype.$toast = (tips,type) => { // 添加 type 參數 let toastTpl = Vue.extend({ // 模板添加位置類 template: '<div class="vue-toast toast-'+ type +'">' + tips + '</div>' }); ... }
這樣,如果我們不傳遞參數,那么type就是undefined, 只要在類名中我們不設置 undefined相關的就可以了,而如果type是bottom之類的時候,我們在css中定義相關的樣式,就可以正確顯示了。
OK! 到這里,其實已經完成了大體框架的大部分了! 但是如果我希望默認在頂部顯示,那么我每次都需要調用 this.$toast.top() 好像就太麻煩了, 另外,如果我們希望div停留的時間不是 2500ms 而是隨着不同的需求而改變的呢? 這時候,其實我們可以利用之前所提到過的options參數來實現了! 在Vue.use()中通過 options來傳進我們想要傳遞的參數就可以。 最終修改如下:
var Toast = {}; Toast.install = function (Vue, options) { let opt = { defaultType:'bottom', // 默認顯示位置 duration:'2500' // 持續時間 } for(let property in options){ opt[property] = options[property]; // 使用 options 的配置 } Vue.prototype.$toast = (tips,type) => { if(type){ opt.defaultType = type; // 如果有傳type,位置則設為該type } if(document.getElementsByClassName('vue-toast').length){ // 如果toast還在,則不再執行 return; } let toastTpl = Vue.extend({ template: '<div class="vue-toast toast-'+opt.defaultType+'">' + tips + '</div>' }); let tpl = new toastTpl().$mount().$el; document.body.appendChild(tpl); setTimeout(function () { document.body.removeChild(tpl); }, opt.duration) } ['bottom', 'center', 'top'].forEach(type => { Vue.prototype.$toast[type] = (tips) => { return Vue.prototype.$toast(tips,type) } }) } module.exports = Toast;
這樣,一個簡單的vue插件就完成了, 我們可以通過 npm 打包發布, 這樣下次使用時就可以通過 npm install 來安裝了!