Vue实现custom-message
前言
之前在项目中使用vue框架中的element-UI时,使用element-UI的弹窗非常的nice,但在最近的项目中,要求项目体积小,且高度自定义,所以不能把element-UI的message的组件引进来再改样式,于是决定自己封装一个,来满足需求。
基本原理
使用Vue.extend(options)创建一个Vue构造器,再将构造器实例化,挂载到body中
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14... const MessageBox = Vue.extend(MessageMain); ... const Message = function (options = {}) { ... let instance = new MessageBox({ data: options }); //在文档之外渲染并且随后挂载 instance.vm = instance.$mount(); document.body.appendChild(instance.vm.$el); ... }
通过构造器,将组件挂载到body上
实现步骤
- 创建messageMain.vue组件
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39<template> <transition name="taataa"> <div :class="['plugins-message-box',type]" v-if="visible"> <div :class="['message-icon','iconfont',iconClass]"></div> <div class="message-container">{{message}}</div> </div> </transition> </template> <script> const typeClass = { success: "icon-success", error: "icon-error", warn: "icon-warn", }; export default { name: "messageMain", data() { return { visible: false, // 控制DOM显示隐藏 type: "success", // 默认type值为default icon: "", // 默认使用icon为空,则使用type值对应的icon message: "", // 默认的message为空,由外部传入 duration: 2000, // 默认显示时间为2000ms }; }, computed: { // 如果外部传入icon则使用外部的icon,如果没有。则使用type值对应的icon iconClass() { if (this.icon) { return this.icon; } else { return typeClass[this.type]; } }, }, }; </script>
- 创建构造器
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58import Vue from 'vue'; // 引入Vue import MessageMain from './messageMain'; // 引入上边定义好的message模板 const MessageBox = Vue.extend(MessageMain); // 使用Vue.extend来创建一个构造器 let instance; // instance 变量用来保存实例 let timer = null; // timer 变量用来保存定时器 // 定义一个function,参数为options,默认为一个对象 const Message = function (options = {}) { // 如果当前处在服务器端,则直接返回 if (Vue.prototype.$isServer) return; // 如果当前定时器已开启,说明页面上已经有一个message-box了,则不能再继续创建新的message-box if (timer) return; // 对options做处理,如果直接传入string,则使其保存在options的message属性上 if (typeof options === 'string') { options = { message: options } } // 初始化实例,并将options作为新的data传入,Vue会将options合并到原有的data上,覆盖原有的默认值,但是,在options中没有设置的是不会被改变的 instance = new MessageBox({ data: options }); // 调用$mount方法,将当前实例渲染为真实DOM,生成$el,如果不执行这一步,将拿不到 $el 的值,但是不指定DOM节点接管当前实例 instance.vm = instance.$mount(); // 使用原生js的API将当前实例的真实DOM追加到body中 document.body.appendChild(instance.vm.$el); // 实例上的vm就是我们的Vue组件,所以我们可以通过vm访问到当前实例中的所有属性 // 将visible设置为true,即显示当前message-box instance.vm.visible = true; // 开启定时器 timer = setTimeout(() => { instance.vm.visible = false; // setTimeout(() => { //延迟卸载和删除,使得结束动画能够实现 这块地方有bug,待完善。。。 // instance.vm.$destroy(); // 在时间结束后将当前实例手动卸载 // instance.vm.$el.parentNode.removeChild(instance.vm.$el); // 使用原生API将当前实例生成的DOM节点在真实的DOM树中删除 // }, 1000) // 清除定时器 timer = null; }, instance.vm.duration); // 定时器的时间使用vm中定义的时间 return instance.vm; }; // 最终抛出一个对象,对象上我们可以使用 install 来扩展Vue的插件 // 当我们的对象上有install方法的时候,它接收第一个参数为Vue, // 我这里为了方便使用,还在当前抛出的对象上定义了一个message方法,为了方便在axios的拦截器中使用; export default { message: Message, install(Vue) { Vue.prototype.$message = Message; Vue.message = Message; } };
- 在main.js上将插件安装到Vue实例中
复制代码
1
2
3import Message from '.component/messageMain'; Vue.use(Message);
- 使用
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51<template> <div class="hello"> <h2>Custom Message</h2> <div> <button @click="successMessage">success</button> <button @click="errorMessage">error</button> <button @click="warnMessage">warn</button> </div> </div> </template> <script> export default { name: 'HelloWorld', data () { return { msg: 'Welcome to Your Vue.js App' } }, methods: { successMessage() { this.$message({ type: 'success', message: '操作成功', duration: '2000', }) }, errorMessage() { this.$message({ type: 'error', message: '操作失败', duration: '2000', }) }, warnMessage() { this.$message({ type: 'warn', message: '异常警告', duration: '2000', }) }, }, } </script> <!-- Add "scoped" attribute to limit CSS to this component only --> <style scoped> </style>
注:这了的icon是使用iconfont-阿里巴巴中Font class,
总结
完整的demo可以到我的GitHub上clone,欢迎star
完整代码链接:
GitHub链接
码云链接
参考链接
最后
以上就是清新电话最近收集整理的关于Vue实现自定义Message的全部内容,更多相关Vue实现自定义Message内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复