Vue 封装Toast消息提示
学习Vue的道路上,封装一些自定义的组件不可避免,今天就来封装一个Toast消息提示。后面还有dialog对话框,原理差不多。
首先先看看效果图
现在才知道用qq录制gif图是真方便。(非广告,后面会多用gif图)
1 正常组件调用
2 全局注册对象调用(不知道是不是叫这个名字)
一 首先,我们先封装一个正常组件看看效果。
- 1 首先创建一个最普通的组件/toast/
Toast.vue
看看效果.
<template> <div class="Toast" v-if="showToast"> {{ message }} </div></template><script> export default { name: "Toast", props: { showToast: { // 激活 type: Boolean, default: false }, message: { type: String, required: true }, delay: { type: Number, default: 3000 } }, data() { return { } }, methods: { // Toast消失 disappear() { if (this.showToast) { setTimeout(() => { this.$emit("disappear"); }, this.delay) } }, }, watch: { showToast() { this.disappear() }, }, }</script><style scoped> .Toast { position: fixed; left: 50%; top: 50%; background: rgb(233, 233, 235); padding: 10px; border-radius: 5px; transform: translate(-50%, -50%); animation: show-toast .2s; color: #909399; overflow: hidden; display: flex; align-items: center; } @keyframes show-toast { from { opacity: 0; } to { opacity: 1; } }</style>
- 2 调用看看效果
<template> <div> <toast :showToast="true" message="测试" /> </div></template><script> import Toast from '@/components/common/toast/Toast' export default { name: 'Profile', data() { return { } }, methods:{ }, components: { Toast, } }</script><style scoped> </style>
然后就能看到这样的效果,但是样式不够好看。
- 3 稍微美化一下
我颜色搭配也没什么经验,就参考的ElementUI。
添加了type样式, 还有提示的小图标,共四种,需要自行去阿里矢量图下载。
<template> <div class="Toast" :class="type" v-if="showToast"> <span class="icon"> <!--<img :src="iconSrc"/>--> </span> {{ message }} </div></template><script> /** * 自己封装的Toast v0.1 * params: showToast Boolean 是否激活toast 默认 false * params: type String toast提示类型 共normal success,fail,warning 四个选项 默认normal * params: message String toast消息 * params: delay Number toast显示时间 默认 3000ms * */ export default { name: "Toast", props: { showToast: { // 激活 type: Boolean, default: false }, type: { // 三种弹窗提示类型 type: String, default: "normal" }, message: { type: String, required: true }, delay: { type: Number, default: 3000 } }, data() { return { } }, methods: { // Toast消失 disappear() { if (this.showToast) { setTimeout(() => { this.$emit("disappear"); }, this.delay) } }, }, watch: { showToast() { this.disappear() }, }, computed: { iconSrc() { // 这里使用的阿里矢量图 let tipType = ["normal", "success", "warning", "fail"]; if (tipType.includes(this.type)) { return require(`@/assets/img/common/${this.type}.svg`) } else { throw "Toast type数据只允许为 normal, success, warning, fail 四种其中的一种,默认为normal" } } }, }</script><style scoped> .Toast { position: fixed; left: 50%; top: 50%; background: rgb(233, 233, 235); padding: 10px; border-radius: 5px; transform: translate(-50%, -50%); animation: show-toast .2s; color: #909399; overflow: hidden; display: flex; align-items: center; } @keyframes show-toast { from { opacity: 0; } to { opacity: 1; } } .success { color: #67C23A; background: rgb(225, 243, 216); } .warning { color: #E6A23C; background: rgb(250, 236, 216); } .fail { color: #F56C6C; background: rgb(253, 226, 226); } .icon img { width: 20px; height: 20px; margin-top: 3px; margin-right: 4px; }</style>
- 4 再看看美化后的效果, 有四种类型,就只看success类型的。
对应完整代码Github地址 https://github.com/CoderCharm...
组件调用总结
调用非常不方便,使用需要导入,传入参数,回调之类的,不符合使用习惯,像ElementUI那种,使用起来就特别方便。
下一步就是超那个方向封装。
二 组件封装全局注册
- 1 这次重新创建一个/toast/
CustToast.vue
组件,里面就不怎么写逻辑.
<template> <div class="CustToast" :class="type" v-if="showToast"> <span class="icon"> <img :src="iconSrc"/> </span> {{ message }} </div></template><script> export default { /** * 自己封装的Toast v0.2 * params: showToast Boolean 是否激活toast 默认 false * params: type String toast提示类型 共normal success,fail,warning 四个选项 默认normal * params: message String toast消息 * params: duration Number toast显示时间 默认 3000ms * */ name: "CustToast", data() { return { showToast: true, type: "normal", message: "消息提示", duration: 3000 } }, computed: { iconSrc() { window.console.log("当前类型", this.type); let tipType = ["normal", "success", "warning", "fail"]; if (tipType.includes(this.type)) { return require(`@/assets/img/common/${this.type}.svg`) } else { throw "Toast type数据只允许为 normal, success, warning, fail 四种其中的一种,默认为normal" } } }, }</script><style scoped> .CustToast { position: fixed; left: 50%; top: 50%; background: rgb(233, 233, 235); padding: 10px; border-radius: 5px; transform: translate(-50%, -50%); animation: show-toast .2s; color: #909399; overflow: hidden; display: flex; align-items: center; } @keyframes show-toast { from { opacity: 0; } to { opacity: 1; } } .success { color: #67C23A; background: rgb(225, 243, 216); } .warning { color: #E6A23C; background: rgb(250, 236, 216); } .fail { color: #F56C6C; background: rgb(253, 226, 226); } .icon img { width: 20px; height: 20px; margin-top: 3px; margin-right: 4px; }</style>
- 2 然后在同级目录创建/toast/
index.js
文件组册,给Vue添加原型$toast
//import vue from 'vue'// 导入自定义到Toast组件import CustToast from './CustToast.vue'// 生成一个扩展实例构造器const ToastConstructor = vue.extend(CustToast);// 定义弹出组件的函数 接收三个参数 消息 toast类型 显示时间function showToast(message, type="normal", duration = 2000) { // 实例化一个 CustToast.vue const _toast = new ToastConstructor({ data() { return { showToast: true, type: type, message: message, duration: duration } } }); // 把实例化的 CustToast.vue 添加到 body 里 let element = _toast.$mount().$el; document.body.appendChild(element); // duration时间到了后隐藏 setTimeout(() => {_toast.showToast = false} ,duration)}// 需要在main.js 里面使用 Vue.use(showToast);showToast.install = (Vue) => { // 将组件注册到 vue 的 原型链里去, // 这样就可以在所有 vue 的实例里面使用 this.$toast() Vue.prototype.$toast = showToast};// 导出export default showToast
- 3 vue-cli
main.js
文件注册
import showToast from '@/你的路径/toast/index'Vue.use(showToast);
- 4 使用
// 封装的时候, 定义了三个参数,message必须要传// message, type="normal", duration = 2000this.$toast("测试普通")this.$toast("测试成功", "success", 5000)this.$toast("测试警告", "warning")this.$toast("测试失败", "fail")
就可以看到开头,我那个演示的gif了。
当然呢,消息提示显示的位置,我没自定义统一显示在中间,同样是按照type一样的思路,给个class样式就可以了。
还有就消失的动画没处理,多个消息弹出的时候直接折叠了。
第二个封装样式Github地址: https://github.com/CoderCharm...
封装总结
我是第一次封装自己的全局对象,Vue原型挂载, vue.extend的用法。官网Vue.extend说明https://cn.vuejs.org/v2/api/i...
感觉还行的话,就去我那个项目点个star吧????