弹框组件有两个特点:一是弹框的元素一般是body的子元素,而不是位于#app内部;二是,使用的时候一般通过函数,比如Message("创建成功")。
怎么让组件显示在#app外面
其实只是信息差的事,很容易理解的。
先看普通的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')