vue自定义简易弹窗

1,131 阅读1分钟

思路

首先准备一个notice.vue弹窗组件模板,之后通过调用弹窗函数的时候传入配置参数就显示不同的弹窗信息

vue创建组件实例的方法

1、render函数

2、Vue.extend()

准备一个简单的弹窗组件

notice.vue

<template>
  <div class="box" v-if="isShow">
    <h3>{{ title }}</h3>
    <p class="box-content">
      {{ message }}
    </p>
  </div>
</template>
<script>
export default {
  data() {
    return {
      isShow: false
    };
  },
  props: {
    title: {
      type: String,
      default: ""
    },
    message: {
      type: String,
      default: ""
    },
    duration: {
      type: Number,
      default: 1000
    }
  },
  methods: {
      show(){
          this.isShow= true
          setTimeout(this.hide,this.duration)
      },
       hide(){
          this.isShow= false
          //隐藏弹窗的时候要销毁这个组件,调用实例上的remove方法
          this.remove()
      }
  }
};
</script>
<style >
    .box{
        position: fixed;
        width: 100%;
        top: 16px;
        left: 0;
        text-align: center;
        pointer-events: none;
        background: #ffffff;
        border: gray 3px solid;
        box-sizing: border-box;
    }
    .box-content{
        width: 200px;
        margin: 10px auto;
        font-size: 14x;
        padding: 8px 16px;
        background: #ffffff;
        border-radius: 3px;
        margin-bottom: 8px;
    }
</style>

render函数创建弹窗

使用:

在main.js中引入,挂载到原型上

// 需要导入Notice
import create from './utils/create'
Vue.prototype.$create = create

组件内调用:需要导入Notice.vue

import Notice from "./notice";
//this.$create返回一个组件
const notice = this.$create(Notice,{
               title:"hhhhh成功了呢",
                message:"成功啦"
          })
//show、hide 方法是在notice组件中定义的
notice.show()

create.js:

import Vue from 'vue'
// 法一:创建组件实例
function create(Component, props){
    //组件构造函数如何获取
    //1、 Vue.extend()
    //2、render
    // 借助vue创建vue实例
    // vm实例会把Component当成根组件渲染出来 vm会是根组件 与#app是兄弟
    const vm = new Vue({
        // h是createElement 返回VNode (虚拟dom)
        // 需要挂载 才能变成真实dom
        render: h => h(Component,{props})
        // 得到 Vue 实例后,我们需要通过一个目标元素来挂载它,有人首先会想到挂载到 #app 上,这个挂载的过程是将目标元素的内容全部替换,所以一旦挂载到 #app 上,该元素的所有子元素都会消失被替换
    }).$mount() //不指定宿主元素 则会创建真实dom  但是不会追加操作  并且不能用body  界面其他元素会被覆盖
    
    //获取真实dom: vm.$el
    document.body.appendChild(vm.$el)
    
    //返回组件实例
    const comp = vm.$children[0]
    // 打印出来的comp 上面也有show和hide方法 所以也页面调用的时候可以直接调用这两个方法
    console.log("create -> comp", comp)
    //销毁组件 实例上添加remove函数
    comp.remove = function(){
        document.body.removeChild(vm.$el)
        vm.$destroy()
    }
    //返回组价实例
    return comp
}

export default create

render函数以插件的形式

使用:

在main.js中引入,注册插件

// 不需要导入Notice 直接调用this.$notice({})
import create2 from './utils/create2'
Vue.use(create2)

调用:

    const notice = this.$notice({
            title: "hhhhh失败了呢",
            message: "失败啦"
          });
          notice.show();

create2.js

import Vue from 'vue'
import Notice from '../components/notice'
// 法一:创建组件实例
function create(Component, props){
    console.log("create -> Component", Component)
    //组件构造函数如何获取
    //1、 Vue.extend()
    //2、render
    // 借助vue创建vue实例
    // vm实例会把Component当成根组件渲染出来 vm会是根组件
    const vm = new Vue({
        // h是createElement 返回VNode (虚拟dom)
        // 需要挂载 才能变成真实dom
        render: h => h(Component,{props})
    }).$mount() //不指定宿主元素 则会创建真实dom  但是不会追加操作  并且不能用body  界面其他元素会被覆盖
    
    //获取真实dom vm.$el
    document.body.appendChild(vm.$el)
    
    //返回组件实例
    const comp = vm.$children[0]

    //销毁组件
    comp.remove = function(){
        document.body.removeChild(vm.$el)
        vm.$destroy()
    }
    return comp
}

// 使用插件
export default {
    install(Vue) {
        Vue.prototype.$notice = function (option) {
            // 返回组件实例
            return create(Notice,option)
        }

        // Vue.prototype.$alert = function () {}
    }
}

Vue.extend()

使用:main.js引入:

  import create3 from './utils/create3'
  Vue.use(create3)

调用:

 const notice2 = this.$notice2({
            title: "hhhhh成功了呢",
            message: "成功啦"
          });
          notice2.show();

create3.js

// 法二
import Vue from "vue";
import Notice from "../components/notice";
function create(Component, props) {
  const ctor = Vue.extend(Component);  //继承Vue实例
  const comp = new ctor({   //创建Vue实例  实例化时可以向这个实例传入参数,但是需要注意的是 props 的值需要通过 propsData 属性来传递
    propsData: props,
  });
  comp.$mount();
  document.body.appendChild(comp.$el);
  comp.remove = () => {
    document.body.removeChild(comp.$el);
    comp.$destroy();
  };
  return comp;
}

export default {
  install(Vue) {
    Vue.prototype.$notice2 = function(option) {
      // 返回组件实例
      return create(Notice, option);
    };
    // Vue.prototype.$alert = function () {}
  },
};