这篇文章主要介绍了vue中的this.$message怎么实现的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇vue中的this.$message怎么实现文章都会有所收获,下面我们一起来看看吧。
1、Message
在开发中的使用频率很高,也算是Element-UI
组件库中比较简单的,对于感兴趣的朋友可以一起探讨一下Message
组件的实现
2、组件的使用
this.$message('这是一条消息提示'); this.$message({ message: '恭喜你,这是一条成功消息', type: 'success' });
3、整体的执行过程
Vue
项目中的使用如下:
// main.js // 1.引入组件库 import ElementUI from 'element-ui'; // 2.使用组件库 Vue.use(ElementUI);
Element-UI
组件库中逻辑如下:
每次当Vue.use
的时候,在Element—UI
内部会触发Element-UI
的install
方法,然后将组件注册为全局组件,将方法放到Vue.prototype
上,本次只看Message部分即可
// 文件目录:node-modules/element-ui/src/index.js // 1.引入Message对象 import Message from '../packages/message/index.js'; // 2. 定义 install函数, const install = function(Vue, opts = {}) { // 将组件遍历注册为全局组件,例如Button组件 components.forEach(component => { Vue.component(component.name, component); }); // 将方法放到Vue原型上 Vue.prototype.$message = Message; };
经过上述两步的处理,我们可以直接在项目中通过this.$message
进行组件的展示控制,接下来继续探索Element-UI
内部如何处理的。
1、设计思路
Message
的调用方式都是通过this.$message进行调用,通过传递不同的options进行组件样式和内容的控制,展示的html是动态的插入到document中并在duration之后移除,组件的展示通过vue实例访问并控制。
组件的整体结构分为展示部分和控制部分
展示部分(main.vue):单独抽离出一个组件,将组件的展示逻辑和交互封装集中处理
控制部分(main.js):是承接vue实例和组件展示
2、展示部分,即main.vue
首先看一下删减版本之后展示部分的组件内容,代码删除了容错和边界值判断的代码,仅仅展示了基本功能。
<template> <transition name="el-message-fade" @after-leave="handleAfterLeave"> <div class="el-message" : v-show="visible"> <slot> <p>{{ message }}</p> </slot> </div> </transition> </template> <script type="text/javascript"> export default { data() { return { visible: false, message: '', duration: 3000, onClose: null, closed: false, verticalOffset: 20, timer: null }; }, computed: { positionStyle() { // 控制当前组件的显示位置 return { 'top': `${ this.verticalOffset }px` }; } }, watch: { // 监听closed的变化,设置为true时,将组件销毁 closed(newVal) { if (newVal) { this.visible = false; } } }, methods: { // transtion组件的钩子,触发after-leave时执行 handleAfterLeave() { this.$destroy(true); // 销毁组件 this.$el.parentNode.removeChild(this.$el); // 将组件的DOM移除 }, close() { this.closed = true; // 组件隐藏 if (typeof this.onClose === 'function') { this.onClose(this); } }, // 每次手动启动编译之后 设置其展示时间duration之后关闭 startTimer() { if (this.duration > 0) { this.timer = setTimeout(() => { if (!this.closed) { this.close(); } }, this.duration); } } }, mounted() { this.startTimer(); } }; </script>
使用了Vue官方封装的transition组件,不仅提供了良好的过渡效果,还提供了合适的钩子便于开发者控制,组件中使用after-leave钩子,当组件销毁时进行组件的销毁和DOM的移除,visible用于控制组件的展示与销毁,计算属性positionStyle用于设置组件的展示位置,message为组件展示的内容数据,搞明白这些变量、计算属性和方法的作用即可。
script
部分可参考注释进行理解,需要注意两个地方
(1)首先需要注意生命周期钩子mount时做的事情,为何如此做?因为不存在el选项,实例不会立即进入编译阶段,需要显示调用$mount 手动开启编译
(2)还需要注意的时close函数中做了两件事,设置closed的值触发对应的watch,关闭组件,若是存在onClose方法则调用,注意这个onClose函数的定义是在控制部分定义,稍后会说明
3、控制部分 至此已经清楚Vue
中是通过this.$message
触发组件的展示,而展示部分的组件内容也已完成,现在就需要通过控制部分将两者连接,达到期望的功能
与Vue
关联比较简单,仅仅是定义一个方法并将其导出即可
const Message = options => { // 逻辑编写.... } export default Message;
这个时候通过this.$message
即可调用,接下来便是将Message
函数与组件关联,并控制展示部分
Message
核心需要做那些事情
编译组件,使用渲染并插入到body
中
控制组件内的visible
变量,触发组件的展示
控制组件内的verticalOffset
变量,决定组件展示时的位置
手动开启组件编译,获取其实例访问内部data
和渲染到页面上
// 1. 使用基础 Vue 构造器,创建一个“子类” let MessageConstructor = Vue.extend(Main); // 2. 组件实例, 可以通过instance访问 visible和verticalOffset instance = new MessageConstructor({ data: options });
整个Message
方法其余部分就是在做容错和健壮处理,整体简洁版代码如下
let MessageConstructor = Vue.extend(Main); let instance; // 当前组件 let instances = []; // 将所有的message组件收集,用于位置的判断和销毁等 let seed = 1; // 每个message实例都有一个唯一标识 const Message = options => { options = options || { message: 'content' + Date.now(), onClose(message){ console.log('关闭时的回调函数, 参数为被关闭的 message 实例',message); } }; if (typeof options === 'string') { options = { message: options }; } // 关闭时的回调函数, 参数为被关闭的 message 实例 let userOnClose = options.onClose; let id = 'message_' + seed++; // 增加 onClose 方法,组件销毁时,在组件内部调用 options.onClose = function() { Message.close(id, userOnClose); }; // 组件实例,此时options与组件的data关联 instance = new MessageConstructor({ data: options }); instance.id = id; // 设置ID instance.$mount(); // 因为不存在el选项,实例不会立即进入编译阶段,需要显示调用$mount 手动开启编译 document.body.appendChild(instance.$el); // 将Message 组件插入到body中 // 设置组件距离顶部的距离,每个message组件会有16px的间距 let verticalOffset = options.offset || 20; instances.forEach(item => { verticalOffset += item.$el.offsetHeight + 16; }); instance.verticalOffset = verticalOffset; instance.visible = true; // 控制展示 instance.$el.style.zIndex = 99; // 控制层级 instances.push(instance); return instance; };
this.$message.error('')的实现
Message
组件支持this.$message.error('错了哦,这是一条错误消息');
调用使用,到目前为止还不支持,代码比较简单直接上代码
// 为每个 type 定义了各自的方法,如 Message.success(options),可以直接调用 ['success', 'warning', 'info', 'error'].forEach(type => { Message[type] = options => { if (typeof options === 'string') { options = { message: options }; } options.type = type; return Message(options); }; });
展示组件内部会调用this.onClose(this)
,组件内部设置this.visible=false
关闭弹框,并且移除其对应的DOM
结构,但是页面展示多个组件时需要修改其余组件的位置
onClose
函数是在Message
函数中定义
// 关闭时的回调函数, 参数为被关闭的 message 实例 let userOnClose = options.onClose; // 增加 onClose 方法,组件销毁时,在组件内部调用 options.onClose = function() { Message.close(id, userOnClose); };
onClose
函数最终调用的是Message
上的静态方法close
函数Message.close
内部主要做了几件事情
在页面显示的组件数组中找到需要关闭的组件,将其移除
重新计算剩余组件的位置
关于“vue中的this.$message怎么实现”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“vue中的this.$message怎么实现”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注亿速云行业资讯频道。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。