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 = 2000
this.$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吧🤩
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。