概述
在我自己平时做项目的时候,必不可少的会用到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);
}
// 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组件的资料请关注编程网其它相关文章!