概述
在我自己平时做项目的时候,必不可少的会用到message组件,用来对用户友好反馈,总之使用频率还是挺高的,刚开始工作的时候,经常用的就是组件库的现成的,想想也不能总是用别人现成的,最近模拟组件库调用方式自己写了一个消息提示组件,支持过渡效果,支持自己进行扩展。
目录结构
- .src/component/MessageBox/MessageBox.vue代码:
<template> //css实现过渡 <transition name="fade-in" mode="out-in"> <div :class="['message-box', 'message-box-' + type]" v-if="show" :style="{ transform: 'translate(-50%,' + offset + 'px)' }" > <p>{{ message }}</p> </div> </transition> //方法2:js实现过渡,用到了Velocity <transition name="fade-in" mode="out-in" v-bind:css="false" v-on:before-enter="beforeEnter" v-on:enter="enter" v-on:leave="leave" > <div :class="['message-box', 'message-box-' + type]" v-if="show" :style="{ top: offset + 'px' }" > <p>{{ message }}</p> </div> </transition> </template> <script> //动画组件用到了Velocity,详细用法可以看官网 import Velocity from "velocity-animate"; export default { name: "MessageBox", props: { message: { type: String, default: "", }, type: { type: String, default: "default", }, showClose: { type: Boolean, default: false, }, center: { type: Boolean, default: false, }, onClose: { type: Function, default: () => {}, }, offset: { type: Number, default: 20, }, }, data() { return { show: false, }; }, methods: { setShow(status) { this.show = status; }, //以下是js实现动画效果逻辑 beforeEnter: function (el) { el.style.opacity = 0; }, enter: function (el, done) { Velocity(el, { opacity: 1 }, { duration: 300 }, { complete: done }); }, leave: function (el, done) { Velocity( el, { top: 0, opacity: 0, }, { duration: 300 ,easing: "ease-in"}, { complete: done } ); }, }, }; </script> <style lang="less"> .message-box { width: 380px; height: 48px; position: fixed; left: 50%; transform: translate(-50%); top: 20px; line-height: 48px; padding-left: 20px; } .message-box-default { background-color: #edf2fc; color: #cccc; } .message-box-success { background-color: #bcdbae; color: green; } .message-box-warning { background-color: #fdf6ec; color: orange; } .message-box-error { background-color: #f3f0f0; color: red; } .fade-in-enter-active, .fade-in-leave-active { transition: all 0.5s; } .fade-in-enter, .fade-in-leave-to { top: 0; opacity: 0; transform: translate(-50%, 0); } </style>
- .src/component/MessageBox/index.js代码:
//这里主要是为了按需注册导出当前组件 import MessageBox from "./MessageBox.vue"; export default MessageBox;
- .src/component/index.js代码:
import MessageBox from "./MessageBox/index"; const componetns = [MessageBox]; export { MessageBox }; //保存所有提示组件的偏移量队列 const messageQueen = []; export default { install(Vue) { //注册全局组件 componetns.forEach((compoennt) => { Vue.component(compoennt.name, compoennt); }); //挂载实例化消息组件对象 Vue.prototype.$message = { warning(message) { Vue.prototype.$show({ message, type: "warning" }); }, success(message) { Vue.prototype.$show({ message, type: "success" }); }, error(message) { Vue.prototype.$show({ message, type: "error" }); }, default(message) { Vue.prototype.$show({ message, type: "default" }); }, }; Vue.prototype.$show = function (props) { // 向弹窗队列添加当前组件的偏移量(入栈) if (!messageQueen.length) { messageQueen.push(20); } else { messageQueen.push(messageQueen[messageQueen.length - 1] + 20 + 48); } /* *方法1:直接返回一个vnode组件虚拟dom也可以 */ // let MessageBoxConstructor = Vue.extend({ // render(h) { // return h("message-box", { // props: { // ...props, // show: true, // }, // }); // }, // }); let MessageBoxConstructor = Vue.extend(MessageBox); // 方法2:实例化组件的时候传递配置项也是可以的 let messageBoxInstance = new MessageBoxConstructor({ // 向组件传递props数据,具体参考vue官方propsData propsData: { ...props, offset: !messageQueen.length ? 20 : messageQueen[messageQueen.length - 1], }, }).$mount(); document.body.appendChild(messageBoxInstance.$el); // 显示弹窗(增加过渡效果) messageBoxInstance.setShow(true); setTimeout(() => { // 当前弹窗出栈 messageQueen.shift(); // 销毁弹窗(增加过渡效果) messageBoxInstance.setShow(false); }, 1500); }; }, };
- .src/App/index.js代码:
<template> <div id="app"> <button @click="handleSuccess">成功</button> <button @click="handleWarning">警告</button> <button @click="handleDefault">消息</button> <button @click="handleError">错误</button> </div> </template> <script> export default { name: "App", methods: { handleSuccess() { this.$message.success("这是一条成功消息"); }, handleWarning() { this.$message.warning("这是一条警告消息"); }, handleDefault() { this.$message.default("这是一条消息提示"); }, handleError() { this.$message.error("这是一条失败消息"); }, }, }; </script> <style lang="less"> button { width: 70px; height: 45px; border: 1px solid #000; margin: 5px!important; } </style>
- 效果图:
总结
类似这种我们脱离模板动态生成组件插入到页面当中,在实际项目中用的还是不怎么多的,需要重点掌握Vue.extend方法,不知道这个方法用法的,建议先去官网学习这个aip的用法,更多关于vue过渡动画Message组件的资料请关注阿兔在线工具其它相关文章!