vue 自定义提示框(Toast)组件的实现代码
1.自定义 提示框 组件
src / components / Toast / index.js
/**
* 自定义 提示框( Toast )组件
*/
var Toast = {};
var showToast = false, // 存储toast显示状态
showLoad = false, // 存储loading显示状态
toastVM = null, // 存储toast vm
loadNode = null; // 存储loading节点元素
Toast.install = function (Vue, options) {
// 参数
var opt = {
defaultType: 'bottom',
duration: '2500',
wordWrap: false
};
for (var property in options) {
opt[property] = options[property];
}
Vue.prototype.$toast = function (tips, type) {
var curType = type ? type : opt.defaultType;
var wordWrap = opt.wordWrap ? 'lx-word-wrap' : '';
var style = opt.width ? 'style="width: ' + opt.width + '"' : '';
var tmp = '<div v-show="show" :class="type" class="lx-toast ' + wordWrap + '" ' + style + '>{{tip}}</div>';
if (showToast) {
// 如果toast还在,则不再执行
return;
}
if (!toastVM) {
var toastTpl = Vue.extend({
data: function () {
return {
show: showToast,
tip: tips,
type: 'lx-toast-' + curType
}
},
template: tmp
});
toastVM = new toastTpl()
var tpl = toastVM.$mount().$el;
document.body.appendChild(tpl);
}
toastVM.type = 'lx-toast-' + curType;
toastVM.tip = tips;
toastVM.show = showToast = true;
setTimeout(function () {
toastVM.show = showToast = false;
}, opt.duration)
};
['bottom', 'center', 'top'].forEach(function (type) {
Vue.prototype.$toast[type] = function (tips) {
return Vue.prototype.$toast(tips, type)
}
});
Vue.prototype.$loading = function (tips, type) {
if (type == 'close') {
loadNode.show = showLoad = false;
} else {
if (showLoad) {
// 如果loading还在,则不再执行
return;
}
var loadTpl = Vue.extend({
data: function () {
return {
show: showLoad
}
},
template: '<div v-show="show" class="lx-load-mark"><div class="lx-load-box"><div class="lx-loading"><div class="loading_leaf loading_leaf_0"></div><div class="loading_leaf loading_leaf_1"></div><div class="loading_leaf loading_leaf_2"></div><div class="loading_leaf loading_leaf_3"></div><div class="loading_leaf loading_leaf_4"></div><div class="loading_leaf loading_leaf_5"></div><div class="loading_leaf loading_leaf_6"></div><div class="loading_leaf loading_leaf_7"></div><div class="loading_leaf loading_leaf_8"></div><div class="loading_leaf loading_leaf_9"></div><div class="loading_leaf loading_leaf_10"></div><div class="loading_leaf loading_leaf_11"></div></div><div class="lx-load-content">' + tips + '</div></div></div>'
});
loadNode = new loadTpl();
var tpl = loadNode.$mount().$el;
document.body.appendChild(tpl);
loadNode.show = showLoad = true;
}
};
['open', 'close'].forEach(function (type) {
Vue.prototype.$loading[type] = function (tips) {
return Vue.prototype.$loading(tips, type)
}
});
}
// 向外暴露接口
module.exports = Toast;
src / components / Toast / toast.css
/**
* Toast 样式
*/
.lx-toast {
position: fixed;
bottom: 100px;
left: 50%;
box-sizing: border-box;
max-width: 80%;
height: 40px;
line-height: 20px;
padding: 10px 20px;
transform: translateX(-50%);
-webkit-transform: translateX(-50%);
text-align: center;
z-index: 9999;
font-size: 14px;
color: #fff;
border-radius: 5px;
background: rgba(0, 0, 0, 0.7);
animation: show-toast .5s;
-webkit-animation: show-toast .5s;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.lx-toast.lx-word-wrap {
width: 80%;
white-space: inherit;
height: auto;
}
.lx-toast.lx-toast-top {
top: 50px;
bottom: inherit;
}
.lx-toast.lx-toast-center {
top: 50%;
margin-top: -20px;
bottom: inherit;
}
@keyframes show-toast {
from {
opacity: 0;
transform: translate(-50%, -10px);
-webkit-transform: translate(-50%, -10px);
}
to {
opacity: 1;
transform: translate(-50%, 0);
-webkit-transform: translate(-50%, 0);
}
}
.lx-load-mark {
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
z-index: 9999;
}
.lx-load-box {
position: fixed;
z-index: 3;
width: 7.6em;
min-height: 7.6em;
top: 180px;
left: 50%;
margin-left: -3.8em;
background: rgba(0, 0, 0, 0.7);
text-align: center;
border-radius: 5px;
color: #FFFFFF;
}
.lx-load-content {
margin-top: 64%;
font-size: 14px;
}
.lx-loading {
position: absolute;
width: 0px;
left: 50%;
top: 38%;
}
.loading_leaf {
position: absolute;
top: -1px;
opacity: 0.25;
}
.loading_leaf:before {
content: " ";
position: absolute;
width: 9.14px;
height: 3.08px;
background: #d1d1d5;
box-shadow: rgba(0, 0, 0, 0.0980392) 0px 0px 1px;
border-radius: 1px;
-webkit-transform-origin: left 50% 0px;
transform-origin: left 50% 0px;
}
.loading_leaf_0 {
-webkit-animation: opacity-0 1.25s linear infinite;
animation: opacity-0 1.25s linear infinite;
}
.loading_leaf_0:before {
-webkit-transform: rotate(0deg) translate(7.92px, 0px);
transform: rotate(0deg) translate(7.92px, 0px);
}
.loading_leaf_1 {
-webkit-animation: opacity-1 1.25s linear infinite;
animation: opacity-1 1.25s linear infinite;
}
.loading_leaf_1:before {
-webkit-transform: rotate(30deg) translate(7.92px, 0px);
transform: rotate(30deg) translate(7.92px, 0px);
}
.loading_leaf_2 {
-webkit-animation: opacity-2 1.25s linear infinite;
animation: opacity-2 1.25s linear infinite;
}
.loading_leaf_2:before {
-webkit-transform: rotate(60deg) translate(7.92px, 0px);
transform: rotate(60deg) translate(7.92px, 0px);
}
.loading_leaf_3 {
-webkit-animation: opacity-3 1.25s linear infinite;
animation: opacity-3 1.25s linear infinite;
}
.loading_leaf_3:before {
-webkit-transform: rotate(90deg) translate(7.92px, 0px);
transform: rotate(90deg) translate(7.92px, 0px);
}
.loading_leaf_4 {
-webkit-animation: opacity-4 1.25s linear infinite;
animation: opacity-4 1.25s linear infinite;
}
.loading_leaf_4:before {
-webkit-transform: rotate(120deg) translate(7.92px, 0px);
transform: rotate(120deg) translate(7.92px, 0px);
}
.loading_leaf_5 {
-webkit-animation: opacity-5 1.25s linear infinite;
animation: opacity-5 1.25s linear infinite;
}
.loading_leaf_5:before {
-webkit-transform: rotate(150deg) translate(7.92px, 0px);
transform: rotate(150deg) translate(7.92px, 0px);
}
.loading_leaf_6 {
-webkit-animation: opacity-6 1.25s linear infinite;
animation: opacity-6 1.25s linear infinite;
}
.loading_leaf_6:before {
-webkit-transform: rotate(180deg) translate(7.92px, 0px);
transform: rotate(180deg) translate(7.92px, 0px);
}
.loading_leaf_7 {
-webkit-animation: opacity-7 1.25s linear infinite;
animation: opacity-7 1.25s linear infinite;
}
.loading_leaf_7:before {
-webkit-transform: rotate(210deg) translate(7.92px, 0px);
transform: rotate(210deg) translate(7.92px, 0px);
}
.loading_leaf_8 {
-webkit-animation: opacity-8 1.25s linear infinite;
animation: opacity-8 1.25s linear infinite;
}
.loading_leaf_8:before {
-webkit-transform: rotate(240deg) translate(7.92px, 0px);
transform: rotate(240deg) translate(7.92px, 0px);
}
.loading_leaf_9 {
-webkit-animation: opacity-9 1.25s linear infinite;
animation: opacity-9 1.25s linear infinite;
}
.loading_leaf_9:before {
-webkit-transform: rotate(270deg) translate(7.92px, 0px);
transform: rotate(270deg) translate(7.92px, 0px);
}
.loading_leaf_10 {
-webkit-animation: opacity-10 1.25s linear infinite;
animation: opacity-10 1.25s linear infinite;
}
.loading_leaf_10:before {
-webkit-transform: rotate(300deg) translate(7.92px, 0px);
transform: rotate(300deg) translate(7.92px, 0px);
}
.loading_leaf_11 {
-webkit-animation: opacity-11 1.25s linear infinite;
animation: opacity-11 1.25s linear infinite;
}
.loading_leaf_11:before {
-webkit-transform: rotate(330deg) translate(7.92px, 0px);
transform: rotate(330deg) translate(7.92px, 0px);
}
@-webkit-keyframes opacity-0 {
0% {
opacity: 0.25;
}
0.01% {
opacity: 0.25;
}
0.02% {
opacity: 1;
}
60.01% {
opacity: 0.25;
}
100% {
opacity: 0.25;
}
}
@-webkit-keyframes opacity-1 {
0% {
opacity: 0.25;
}
8.34333% {
opacity: 0.25;
}
8.35333% {
opacity: 1;
}
68.3433% {
opacity: 0.25;
}
100% {
opacity: 0.25;
}
}
@-webkit-keyframes opacity-2 {
0% {
opacity: 0.25;
}
16.6767% {
opacity: 0.25;
}
16.6867% {
opacity: 1;
}
76.6767% {
opacity: 0.25;
}
100% {
opacity: 0.25;
}
}
@-webkit-keyframes opacity-3 {
0% {
opacity: 0.25;
}
25.01% {
opacity: 0.25;
}
25.02% {
opacity: 1;
}
85.01% {
opacity: 0.25;
}
100% {
opacity: 0.25;
}
}
@-webkit-keyframes opacity-4 {
0% {
opacity: 0.25;
}
33.3433% {
opacity: 0.25;
}
33.3533% {
opacity: 1;
}
93.3433% {
opacity: 0.25;
}
100% {
opacity: 0.25;
}
}
@-webkit-keyframes opacity-5 {
0% {
opacity: 0.270958333333333;
}
41.6767% {
opacity: 0.25;
}
41.6867% {
opacity: 1;
}
1.67667% {
opacity: 0.25;
}
100% {
opacity: 0.270958333333333;
}
}
@-webkit-keyframes opacity-6 {
0% {
opacity: 0.375125;
}
50.01% {
opacity: 0.25;
}
50.02% {
opacity: 1;
}
10.01% {
opacity: 0.25;
}
100% {
opacity: 0.375125;
}
}
@-webkit-keyframes opacity-7 {
0% {
opacity: 0.479291666666667;
}
58.3433% {
opacity: 0.25;
}
58.3533% {
opacity: 1;
}
18.3433% {
opacity: 0.25;
}
100% {
opacity: 0.479291666666667;
}
}
@-webkit-keyframes opacity-8 {
0% {
opacity: 0.583458333333333;
}
66.6767% {
opacity: 0.25;
}
66.6867% {
opacity: 1;
}
26.6767% {
opacity: 0.25;
}
100% {
opacity: 0.583458333333333;
}
}
@-webkit-keyframes opacity-9 {
0% {
opacity: 0.687625;
}
75.01% {
opacity: 0.25;
}
75.02% {
opacity: 1;
}
35.01% {
opacity: 0.25;
}
100% {
opacity: 0.687625;
}
}
@-webkit-keyframes opacity-10 {
0% {
opacity: 0.791791666666667;
}
83.3433% {
opacity: 0.25;
}
83.3533% {
opacity: 1;
}
43.3433% {
opacity: 0.25;
}
100% {
opacity: 0.791791666666667;
}
}
@-webkit-keyframes opacity-11 {
0% {
opacity: 0.895958333333333;
}
91.6767% {
opacity: 0.25;
}
91.6867% {
opacity: 1;
}
51.6767% {
opacity: 0.25;
}
100% {
opacity: 0.895958333333333;
}
}
2.全局引入
main.js
// 全局引入Toast
import './components/Toast/toast.css';
import Toast from './components/Toast/index';
Vue.use(Toast);
3.页面调用
Toast.vue
<!-- 提示框 -->
<template>
<div>
<!-- 标题栏 -->
<mt-header title= "提示框" >
<router-link to= "/" slot= "left" >
<mt-button icon= "back" >返回</mt-button>
</router-link>
</mt-header>
<!-- 内容 -->
<button @click= "openTop()" >top</button>
<button @click= "openCenter()" >center</button>
<button @click= "openBottom()" >bottom</button>
<button @click= "openLoading()" >loading</button>
</div>
</template>
<script>
export default {
name: 'Toast' ,
data(){
return {
//
}
},
methods:{
openTop(){
this .$toast.top( 'top' );
},
openCenter(){
this .$toast.center( 'center' );
},
openBottom(){
this .$toast( 'bottom' ); // or this.$toast.bottom('bottom');
},
openLoading(){
this .$loading( 'loading...' );
let self = this ;
setTimeout( function () {
self.closeLoading()
}, 2000)
},
closeLoading(){
this .$loading.close();
}
}
}
</script>
<style lang= "less" scoped>
//
</style>
4.效果图
以上是 vue 自定义提示框(Toast)组件的实现代码 的全部内容, 来源链接: utcz.com/z/339685.html