怎么封装弹框组件

2,349 阅读1分钟

弹框组件有两个特点:一是弹框的元素一般是body的子元素,而不是位于#app内部;二是,使用的时候一般通过函数,比如Message("创建成功")

怎么让组件显示在#app外面

message1

其实只是信息差的事,很容易理解的。

先看普通的toast组件:

<template>
 <div class="toast">{{ text }}</div>
</template>

<script>
const Toast = {
 props: { text: String, duration: { default: 2000 } },
 mounted() {
   // 定时销毁
   setTimeout(() => {
     // 销毁组件,这个只能让组件对象消失,但节点仍然在
     this.$destroy();
     // 再移除节点
     this.$el.parentNode.removeChild(this.$el);
   }, this.duration);
 },
};

export default Toast;
</script>

一般,组件的模板编译之后,默认挂载在app里,但其实我们可以手动选择将其挂载在任意处。

需要四步:

  • 创建组件类,其实就是Vue.extend(SelfComponent)extend会自动将组件对象转化为组件类
  • 创建组件实例,可能需要传入data之类的参数,new xx({data:{...}})
  • 编译组件实例,就是将template里的字符串变成实际的dom节点,编译完之后的节点赋值给了该组件实例的$el
  • 将节点插入到文档中任意位置即可

让其支持函数的话,加上以下代码即可:

const toast = (text) => {
  // 单纯的new不行 必须是一个组件类
  const MessageConstructor = Vue.extend(Toast);
  // 创建message组件实例,传入data
  const messageInstance = new MessageConstructor({
    propsData: { text },
  });
  // 编译组件实例,编译完之后的dom存放在messageInstance.$el
  messageInstance.$mount();
  // 将dom插入到body里即可
  document.body.appendChild(messageInstance.$el);
  // 链接:https://juejin.cn/post/6899362623020597256
};
export { toast };
export default Toast;

怎么通过函数显示组件

其实上面的如果实现了,就是直接引入就好

import { toast } from './components/Toast';
toast('xxx')

怎么实现this.$toast()呢

这个就更没啥了。。。

main.js那边toast方法挂载在原型上面即可

Vue.prototype.$toast = toast

怎么给message增加类型呢

一般message有成功、错误、警告之类的,此时需要在参数那边多加一个type,当然组件内部也需要根据type显示不同的样式。

增加type之后,为了更方便使用,希望能message.success('ok'),其实也不难。

// options是 {type:xx,message:xxx}
const Message = (options) =>{
    // ...
    const messageInstance = new MessageConstructor({
        data: { options }
      });
    //   ...
}
const types =["success","error","warning"]
types.forEach(type=>{
    Message[type] = message =>{
        let options = {}
        options.message = message
        options.type = type
        Message(options)
    }
})
// 使用的时候就可以
Message.success('ok')