zoukankan      html  css  js  c++  java
  • vue插件开发实践与要点

    其实就跟组件差不多意思,组件也可以实现相关的效果,但要在用到的地方都引用
    插件就可以全局注册,不需引用

    试着撸一个插件,有2个功能,提示和对话框

    网上找了个toast插件的代码,改了改,扩展加了个dialog,增加了注释

    插件文件结构

     

    在入口文件中注册:

    /* 自定义插件 */
    import {Message,vDialog} from './components/vtoast/index'
    Vue.use(Message).use(vDialog)

    调用方式

        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:

    <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-90vw;max-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.js

    //插件的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}

    总结相关要点:

    • 绑定多个事件使用  @click="cb();close()"
    • Object.assign(_VUEINSTANCE, options) ,把调用时的参数(包括值,方法)合并进基于vue构造器创建的插件实例中
      vue会自动把参数放到对应的地方,数据放data,方法放methods,但本实践没有把回调方法也放进同一个参数中
      而是为了代码清晰,另起一个连续调用的方法来处理
  • 相关阅读:
    protobuf自解释message
    protobuf编码
    proto3语法
    proto2语法
    protobuf简介
    poi处理大EXCEL文件总结
    POI-处理大Excel文件(xlsx写)
    POI-处理大Excel文件(xlsx)
    POI-处理大Excel文件(xls)
    RedHat 6.4 RHCS GFS2安装
  • 原文地址:https://www.cnblogs.com/vbyzc/p/9516825.html
Copyright © 2011-2022 走看看