美文网首页
vue自定义插件

vue自定义插件

作者: 团猫咪爱吃玉米 | 来源:发表于2022-12-15 15:09 被阅读0次

一、定义插件的目的是为了使用函数式调用某个全局组件,方便直接在js中调用,
不需要在任何组件中声明,大概是这样的效果

this.$toast({
            title: '我是toast',
            closeButton: {
                text: '知道了',
                callback () {
                    console.log('用户说他知道了');
                }
            }
       })

二、实现过程:
1.准备好需要的组件

<template>
  <div>
    <div>{{title}}</div>
    <!-- <slot></slot> -->
  </div>
</template>
<script>
export default {
  data() {
    return {};
  },
  props: {
    title: {
        type: String,
        default: ''
    },
    closeButton: {
        type: Object,
        default () {
            return {
                text: '关闭',
                callback: undefined
            }
        }
    }
  },
  methods: {
    close() {
      // 删除组件方法,将真实的dom节点删掉
      this.$el.remove();
      // 将虚拟节点占的内存也释放掉
      this.$destroy();
    },
    onClickClose () {
        this.close();
        if (this.closeButton && typeof this.closeButton.callback === 'function') {
           this.closeButton.callback(this) // this === toast实例
        }
    }
  },
};
</script>

这里:如果我们想在js调用组件的时候,拿到组件实例,并调用组件里的方法,可以把this传出去, this === toast实例,然后在调用的地方这样使用:

this.$toast({
            title: '我是toast',
            closeButton: {
                text: '知道了',
                callback (toast) {
                    toast.log() //调用组件内部方法
                    console.log('用户说他知道了');
                }
            }
       })
  1. 将组件实例化,并转化成真实dom
    这里:Vue.extend()其实就是用来创建组件的构造函数的,然后使用这个构造函数创建出Vue的虚拟节点Vnode
import Toast from './demoPage'
export default {
    install(Vue, options) {
        Vue.prototype.$toast = function (options) {
            // 1.使用Vue.extend创建构造函数,MyComponent是自定义的vue组件(MyComponent.vue)
            let Constructor = Vue.exend(Toast)
            // 构造函数的参数,propsData相当于我们组件MyComponent.vue里需要的props,
            // 这里为了和vue文件中的props冲突,所以官方取了个别名 
            // 2.然后实例化后,会生成一个vue组件对应的虚拟节点
            let toast = new Constructor({
                propsData: options
            })
            // toast.$slot.default = [options.message]
            // 3.将vm转化成真实dom
            toast.$mount();
            // 4.将真实dom,挂载到body上
            document.body.appendChild(toast.$el)
        }
    }
}

进一步可以封装成:

import Toast from './demoPage';
function createToast({ Vue, propsData }) {
    // 1.使用Vue.extend创建构造函数,MyComponent是自定义的vue组件(MyComponent.vue)
    let Constructor = Vue.exend(Toast)
    // 构造函数的参数,propsData相当于我们组件MyComponent.vue里需要的props,
    // 这里为了和vue文件中的props冲突,所以官方取了个别名 
    // 2.然后实例化后,会生成一个vue组件对应的虚拟节点
    let toast = new Constructor({
        propsData
    })
    // toast.$slot.default = [propsData.message]
    // 3.将vm转化成真实dom
    toast.$mount();
    // 4.将真实dom,挂载到body上
    document.body.appendChild(toast.$el)
}


export default {
    install(Vue, options) {
        Vue.prototype.$toast = funtion(options) {
            createToast({ Vue, propsData: options })
        }
    }
}

优化,避免创建多次:

import Toast from './demoPage';
function createToast({ Vue, propsData }) {
    // 1.使用Vue.extend创建构造函数,MyComponent是自定义的vue组件(MyComponent.vue)
    let Constructor = Vue.exend(Toast)
    // 构造函数的参数,propsData相当于我们组件MyComponent.vue里需要的props,
    // 这里为了和vue文件中的props冲突,所以官方取了个别名 
    // 2.然后实例化后,会生成一个vue组件对应的虚拟节点
    let toast = new Constructor({
        propsData
    })
    // toast.$slot.default = [propsData.message]
    // 3.将vm转化成真实dom
    toast.$mount();
    // 4.将真实dom,挂载到body上
    document.body.appendChild(toast.$el)
}

let currentToast;
export default {
    install(Vue, options) {
        Vue.prototype.$toast = funtion(options) {
            if (currentToast) {
                currentToast.close()
            }
            currentToast = createToast({ Vue, propsData: options })
        }
    }
}

继续优化:

 methods: {
    close() {
      // 删除组件方法,将真实的dom节点删掉
      this.$el.remove();
      this.$emit('close')
      // 将虚拟节点占的内存也释放掉
      this.$destroy();
    }
  },
import Toast from './demoPage';
function createToast({ Vue, propsData, onClose }) {
    // 1.使用Vue.extend创建构造函数,MyComponent是自定义的vue组件(MyComponent.vue)
    let Constructor = Vue.exend(Toast)
    // 构造函数的参数,propsData相当于我们组件MyComponent.vue里需要的props,
    // 这里为了和vue文件中的props冲突,所以官方取了个别名 
    // 2.然后实例化后,会生成一个vue组件对应的虚拟节点
    let toast = new Constructor({
        propsData
    })
    // toast.$slot.default = [propsData.message]
    // 3.将vm转化成真实dom
    toast.$mount();
    toast.$on('close', onClose)
    // 4.将真实dom,挂载到body上
    document.body.appendChild(toast.$el)
}
let currentToast

export default {
    install(Vue, options) {
        Vue.prototype.$toast = funtion(options) {
            if (currentToast) {
                currentToast.close()
            }
            currentToast = createToast({
                Vue, propsData: options, onClose: () => {
                    currentToast = null
                }
            })
        }
    }
}

3.在入口文件main.js中调用插件:

// 导入插件
import noticePlugin from '@/notice/index'
// 使用插件
Vue.use(noticePlugin)

相关文章

  • Vue2.0双向绑定源码分析

    A:vue的双向绑定 B:vue自定义插件 C:vue混入

  • Vue插件

    官网插件地址官网自定义指令参考文章参考文章 一、Vue插件介绍 理解插件与组件 一个Vue插件可以是一堆Vue组件...

  • Vue.js插件书写规范

    Vue插件书写规范,导出install方法 使用时,可以通过以上主流写法将自定义插件挂载到Vue上面: 闭包里ex...

  • Vuex 原理

    1、Vue.use(Vuex):将Vuex 应用到Vue中 use是一个自定义插件,这个插件里有一个固定方法ins...

  • Vue3.x

    一. 项目搭建及自定义脚手架模板 二. 添加插件 vue add eg:vue add vuetify 2.x版...

  • vue全局API和使用方法

    Vue.use(plugins) 注册一个插件 例子: Vue.directive()创建或者获取自定义指令 一个...

  • VSCODE配置vue模板

    VSCode -vue项目,自定义.vue模版 1.安装vscode vscode官网地址: 2.安装一个插件,识...

  • Capacitor实现WebView中访问的自定义Android

    前言 Capacitor 自定义插件 实现WebView中访问的自定义Android代码 最近在工作中使用Vue+...

  • vue高级用法

    Vue 插件 plugin 1, Vue 插件 plugin 安装 Vue.js 插件。如果插件是一个对象,必须提...

  • vue 高级功能

    主要可以分为4part: 过渡 自定义指令 mixins 插件 过渡 transition 是vue提供的内置的组...

网友评论

      本文标题:vue自定义插件

      本文链接:https://www.haomeiwen.com/subject/rijrqdtx.html