vue3和vue2挂载实例到全局(自定义消息提示框组件方式)
作者:Jyann~
这篇文章主要介绍了vue3和vue2挂载实例到全局(自定义消息提示框组件方式),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
vue2
入口文件中引入JS文件及css样式
//入口文件:main.js import Vue from 'vue' import App from './App.vue' import router from './router' import store from './store' import TMessage from '@/components/TMessage/TMessage.js'; import '@/assets/css/css.css' Vue.config.productionTip = false Vue.prototype.$message = TMessage; new Vue({ router, store, render: h => h(App) }).$mount('#app')
//TMessage.js文件 import { createApp, createVNode, render } from 'vue' import TMessage from '@/components/TMessage/TMessage.vue' // 用于储存多个实例 let instances = []; function Message(data) { // 使用该方法组件(如Login)传过来的数据没有传的变量需要有默认值,否则是undefined传给TMessage if (typeof data === 'string') { // Message("这是错误的"),除了message,其他的设置默认值 data = { message: data, type: 'info', } } data = { ...data, // 设置具体data参数,根据传入的显示不同 message: data.message ? data.message : '默认提示信息', type: data.type ? data.type : 'info', center: data.center ? data.center : true, offset: data.offset ? data.offset : 20, duration: data.duration ? data.duration : 1000 } // 用于处理所有消息提示框消失后,其他提示框的位置(需要在TMessage.vue中调用) data.onClose = function() { Message.close(msgNode); } // 处理多个实例之间间距 let offset = data.offset || 20; // 用于改变后的offset值记录 let offsetTop = offset; console.log(instances.length); // * 0: 20 // * 1: 20 40 20(第0个的offset + 第0个的div高度(offsetHeight) + 第1个的offset 20) instances.forEach((item) => { // 直接通过item获取的实例offsetHeight不准确 offsetTop += item.offsetHeight + offset + 26; }); // 设置offset及TMessage.vue中的top值 data.offset = offsetTop; // 创建实例 const app = createApp(TMessage, data); // 准备dom容器 const msgNode = document.createElement('div'); // 添加到body上 app.mount(msgNode); document.body.appendChild(msgNode); msgNode.style.top = offsetTop + 'px'; msgNode.style.height = '20px'; // 将当前实例加入instances instances.push(msgNode); } // 消息类型:success,info,error,warning ['error', 'info', 'success', 'warning'].forEach(item => { Message[item] = function(data) { if (typeof data === 'string') { data = { message: data }; } data.type = item; return Message(data); }; }); // // * 获取当前这个instance的高度 // * 把这个instance后面的所有实例的top减去这个高度,再减去偏移 // * Message.close = function(msgNode) { // 获取到DOM结构中所有新创建的Node let curMessage = document.querySelectorAll("div.message"); // 找到当前div是在instances数组的下标 let index = instances.findIndex(item => item === msgNode); instances = instances.filter(item => item !== msgNode); // 获取需要减去的高度(66=自身高度+offset高度);curMessage[0].offsetHeight才能得到真正解析后的高度 let removeHeight = msgNode.offsetHeight + curMessage[0].offsetHeight; for (let i = index; i < curMessage.length; i++) { curMessage[i].style.top = parseInt(curMessage[i].style.top.split('px')[0]) - removeHeight + 'px'; } // curMessage.length=1时是最后一次调用close方法,此时清空instances,则再次点击offsetTop不会一直累加 if (curMessage.length == 1) { instances = []; } } export default Message; Message;
//TMessage.vue <template> <!-- 动画效果 --> <transition name="message-fade"> <!-- 使用数据绑定class --> <div v-if="!closed" :class="['message', 'message-' + type, center ? 'is-center' : '']" :style="{ top: offset + 'px' }" > <p class="message-content">{{ type }}:{{ message }}</p> <i class="icon icon-close" @click="closeTip"></i> </div> </transition> </template> <script> export default { name: 'TMessage', props: { message: '默认提示信息', type: 'info', center: true, offset: 20, duration: 2000, // 用于处理所有消息提示框消失后,其他提示框的位置 onClose: null }, data () { return { // 定时器 timer: null, closed: false, } }, mounted () { this.timer = setTimeout(() => { if (!this.closed) { this.close(); } }, this.duration); }, methods: { close () { this.closed = true; if (typeof this.onClose === 'function') { this.onClose(); } } } } </script>
在任何其他组件中使用:通过this.即可简单使用
this.$message.error('用户名和密码不能为空'); // this.$message({ // duration: 1000, // message: '1111', // type: 'warning', // }) // this.$message({ // duration: 5000, // message: '5555', // type: 'error', // }) // this.$message({ // duration: 3000, // message: '3333', // type: 'warning', // }) // this.$message({ // duration: 4000, // message: '4444', // type: 'info', // }) // this.$message({ // duration: 2000, // message: '2222', // type: 'success', // })
vue3
TMessage.js和TMessage.vue文件同上
//入口文件:main.js import { createApp } from 'vue' import App from './App.vue' // css文件直接引入 import '@/assets/css/css.css' import router from '@/route/route' import store from '@/store/store' import Message from '@/components/TMessage/TMessage.js' // Vue3将自定义组件加载到全局方法 const app = createApp(App); app.config.globalProperties.$message = Message; // 4.创建一个vue应用,将App组件和定义的路由放入到vue应用,并挂载到模板页面id为app的元素上。 app.use(router).use(store).mount('#app')
使用:
this直接引用
this.$message.error("这是测试错误");
问题:
消息提示框的消失有点问题,点击多个时不连续
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。