其實就跟組件差很少意思,組件也能夠實現相關的效果,但要在用到的地方都引用
插件就能夠全局註冊,不需引用html
試着擼一個插件,有2個功能,提示和對話框vue
網上找了個toast插件的代碼,改了改,擴展加了個dialog,增長了註釋app
插件文件結構:less
在入口文件中註冊:dom
/* 自定義插件 */ import {Message,vDialog} from './components/vtoast/index' Vue.use(Message).use(vDialog)
調用方式:ide
methods:{ showtoast(){ this.$vtoast({ duration:1100, message:'哈哈哈' }); }, showdialog(){ let that = this this.$vdialog.alert({ isShow: true, //插件默認值title爲空,若是這裏不放title,則不會顯示title的dom title:'你好', message:'哈哈哈', }) .then(()=>{ that.test = '修改了' }) } },
toast.vue:函數
<template> <transition name="fade"> <div class="v-msg" v-show="isShow"> <span>{{message}}</span> </div> </transition> </template> <script> export default { data(){ return { message: '默認提示', isShow : false } }, methods:{ close(){ this.isShow = false }, show(){ this.isShow = true } } } </script> <style> .v-msg{ color:#fff;display: inline-block;background-color:rgba(0,0,0,0.8);padding:10px; border-radius: 4px; position: fixed;left:50%;bottom:10px;transform: translateX(-50%) } .fade-enter-active, .fade-leave-active { transition: all .2s; } .fade-enter, .fade-leave-to { opacity: 0; } </style>
dialog.vue:flex
<template> <transition name="fade"> <div v-show="isShow"> <div class="dialog_mask" v-show="mask" @click="close"></div> <div class="dialog"> <div class="title" v-show="title">{{title}}</div> <div class="message">{{message}}</div> <div class="btgroup"> <button class="button" @click="close" v-if="cancle">取消</button> <button class="button sure" @click="cb();close()">肯定</button> </div> </div> </div> </transition> </template> <script> export default { props:{ }, data(){ return { title:'', message:'默認內容消息', isShow : false, mask:true, cancle:false } }, methods:{ close(){ this.isShow = false; } } } </script> <style lang="less" scoped> .dialog_mask{ position: fixed;top:0;right:0;bottom: 0;left: 0;background-color:rgba(0,0,0,0.8); z-index: 100000; } .dialog{ min-width:90vw;max-width:90vw;color:#333;display: inline-block;background-color: #fff;overflow: hidden; position: fixed;left:50%;top:50%;transform: translate(-50%,-50%);z-index:100001;border-radius:5px; .title{ font-size:16px;padding:20px 0px 0px;text-align: center; } .message{ color:#999;font-size:16px;padding:25px; } .btgroup{ display:flex;align-items: center;justify-content: space-between;border-top:1px solid #eee; } .button{ font-size:16px;flex:1;padding:14px 0px;border:none;background-color: #fff; &.sure{color:#293} &:active{background-color: #eee;} &:nth-child(2){border-left:1px solid #eee;} } } .fade-enter-active, .fade-leave-active { transition: all .2s; } .fade-enter, .fade-leave-to { opacity: 0; } </style>
index.jsui
//插件的install會放入vue.use方法中運行,本文件中不用import vue // TOAST插件 import mytoast from './toast.vue' const Message = {} Message.install = function (Vue, options) { //返回一個vue實例構造器 const VUECONSTRUCTOR = Vue.extend(mytoast) let _VUEINSTANCE const initInstance = () => { //實例化vue示例 下面能夠直接調用methods裏面的方法 _VUEINSTANCE = new VUECONSTRUCTOR() // 取得通過vue裏面折騰以後生成的html let El = _VUEINSTANCE.$mount().$el //掛載到body中 document.body.appendChild(El) } Vue.prototype.$vtoast = (options)=>{ //單例模式,防止重複掛載html if (!_VUEINSTANCE) { initInstance()//建立實例 } //將調用的參數對象傳給_VUEINSTANCE對象,覆蓋組件內的初始配置 // 官方:https://cn.vuejs.org/v2/guide/list.html#對象更改檢測注意事項 Object.assign(_VUEINSTANCE, options) //調用插件裏的顯示方式 _VUEINSTANCE.show() // 注意,若是是自動消失的toast 每閃調用(顯示),都要再次聊友 // 不要使用實例裏面的方法,由於插件只掛載一次,dom便存於html中 // 因此,這裏的vue插件實例生命週期只生效一次(created,mounted) setTimeout(() => { _VUEINSTANCE.close() }, options.duration) } } // DIALOG插件 import myDialog from './dialog.vue' const vDialog = {} vDialog.install = function (Vue, options) { const VUECONSTRUCTOR = Vue.extend(myDialog) let _VUEINSTANCE const initInstance = () => { _VUEINSTANCE = new VUECONSTRUCTOR() let El = _VUEINSTANCE.$mount().$el document.body.appendChild(El) } //這裏最好用對象封裝方法的模式,調用時代碼好閱讀一些 Vue.prototype.$vdialog = { alert(options) { if (!_VUEINSTANCE) { initInstance() } //默認顯示顯示肯定按鈕,因此回調給一個默認空函數 Object.assign(_VUEINSTANCE, options,{cb:()=>{}}) //以便連續調用 return this }, then(options){ //若是不調用then只顯示肯定按鈕 //這裏的回調函數名cb,必需和插件裏面所調用的同樣 Object.assign(_VUEINSTANCE, {cancle:true,cb:options}) } } } export {Message,vDialog}
總結相關要點:this