adpater里写toast_写一个 Vue 插件 toast

本人在造轮子过程中遇到写 toast 组件时为考虑方便用户调用,因此采用插件方式写 toast,

最终用户调用代码为

export default {

methods: {

showToast() {

this.$toast(`您的余额为 ${parseInt(Math.random() * 100)}. 需要充值`, {

enableHtml: false, // 是否开启内嵌html元素

autoClose: false, // 是否自动关闭

position: 'top', // 展示位置

closeButton: { // 关闭按钮配置

text: '充值',

callback: (toast) => {

toast.log() // 关闭后触发 toast 中的方法

}

}

})

}

}

展示效果为

toast.gif

插件代码

import Toast from './toast.vue'

let currentToast

export default {

install(Vue, options) {

Vue.prototype.$toast = (message, toastOptions) => {

// 避免出现多个 toast 重叠

if(currentToast) {

currentToast.close()

}

currentToast = createToast({

Vue,

message,

propsData: toastOptions,

onClose: () => {

currentToast = null

}

})

}

}

}

function createToast({ Vue, message, propsData, onClose }) {

const Constructor = Vue.extend(Toast)

let toast = new Constructor({

propsData

})

toast.$slots.default = [message]

toast.$mount()

toast.$on('close', onClose)

document.body.appendChild(toast.$el)

return toast

}

toast 组件代码

{{closeButton.text}}

export default {

name: "WheelToast",

props: {

autoClose: {

type: [Boolean, Number],

default: 5,

validator(value) {

return typeof value === 'boolean' || typeof value === 'number'

}

},

closeButton: {

type: Object,

// 传 object 时得用函数返回,不然属性会被覆盖,跟 data 一个道理

default() {

return {

text: "关闭",

// 点击关闭按钮的回调函数

callback: undefined

}

}

},

enableHtml: {

type: Boolean,

default: false

},

position: {

type: String,

default: "middle",

validator(value) {

return ["top", "middle", "bottom"].indexOf(value) >= 0;

}

}

},

computed: {

toastClasses() {

return [`position-${this.position}`];

}

},

mounted() {

this.updateStyle();

this.execAutoClose();

},

methods: {

updateStyle() {

// 实现多行文字父元素需要用到 min-height,此时子元素 height 为 100% 获取不到父元素 height,因此异步获取父元素高

this.$nextTick(() => {

this.$refs.line.style.height = `${this.$refs.toast.getBoundingClientRect().height}px`;

});

},

execAutoClose() {

if (this.autoClose) {

setTimeout(() => {

this.close();

}, this.autoClose * 1000);

}

},

close() {

this.$el.remove();

this.$emit("close");

this.$destroy();

},

log() {

console.log("调用了 toast 的 log 方法");

},

onClickClose() {

this.close();

if (this.closeButton && typeof this.closeButton.callback === "function") {

// 调用 callback 传入 this 可让调用回调时拿到 toast 实例,从而调用实例里的方法

this.closeButton.callback(this);

}

}

}

};

备注:为了简洁去掉了 css 代码

使用插件

import Vue from 'vue'

import plugin from './plugin'

Vue.use(plugin)

之后便可以在组件中用this.$toast(MESSAGE, OPTIONS)的方式调用 toast插件啦

总结

制作toast插件的详细过程可以查看我的造轮子项目Echo Wheeltoast分支下的commit记录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值