Vue自定义Toast插件

10

图片描述

基于vue全家桶

目录结构:

├── components
│   ├── Toast
│   ├── ├── index.js
│   └── └── index.css
└── main.js

components/Toast/index.js

/*
    自定义 toast 组件
    调用
    this.$toast('hello world~', {duration: 1500})
*/
let _TOAST = {
        show: false,    // Boolean toast显示状态
        component: null // Object toast组件
    };
export default {
    install(Vue) {
        /*
            text: String*
            opts: Object {}
        */
        Vue.prototype.$toast = function(text, opts) {
            let defaultOpts = {
                position: 'center', // String
                duration: 1000,     // Number
                wordWrap: false,    // Boolean
                // width: '90%'     // String/Number
            };
            opts = Object.assign(defaultOpts, opts);
            let wordWrap = opts.wordWrap ? 'zh-word-wrap' : '',
                style = opts.width ? `style="width: ${opts.width}"` : '';
            if (_TOAST.show) {
                return;
            }
            if (!_TOAST.component) {
                let ToastComponent = Vue.extend({
                    data: function() {
                        return {
                            show: _TOAST.show,
                            text: text,
                            position: `zh-toast-${opts.position}`
                        }
                    },
                    template: `<div v-show="show" :class="position" class="zh-toast ${wordWrap}" ${style}>{{text}}</div>`
                });
                _TOAST.component = new ToastComponent();
                let element = _TOAST.component.$mount().$el;
                document.body.appendChild(element);
            }
            _TOAST.component.position = `zh-toast-${opts.position}`;
            _TOAST.component.text = text;
            _TOAST.component.show = _TOAST.show = true;
            setTimeout(function() {
                _TOAST.component.show = _TOAST.show = false;
            }, opts.duration)
        };
    }
}

components/Toast/index.css

.zh-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;
}
.zh-toast.zh-word-wrap {
    width: 80%;
    white-space: inherit;
    height: auto;
}
.zh-toast.zh-toast-top {
    top: 50px;
    bottom: inherit;
}
.zh-toast.zh-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);
    }
}

main.js

// Toast
import './components/Toast/index.css';
import Toast from './components/Toast/index';
Vue.use(Toast);

调用

this.$toast('hello world~', {duration: 1500})

参考链接:
https://www.cnblogs.com/crazycode2/p/7927473.html

你可能感兴趣的

Demo_Hu · 1月21日

请教一下,我运用vue-cli3.x 写了一个类似ElementUI这样的UI组件库,现在里面有几个标签形式的组件,但是像Toast这样通过Vue.prototype调用的全局组件,请问怎么集成????

回复

0

还没写过组件库,对于这个集中封装集成,经验不足,可以尝试统一import到一个文件里,然后统一export出去试试。

zhangqh 作者 · 1月21日
载入中...