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

回到顶部