vue 3.0 封装 Toast 组件
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue 3.0 封装 Toast 组件相关的知识,希望对你有一定的参考价值。
参考技术A也可以使用 createVNode + render 这对组合
也支持直接导入函数使用 import Toast from \'@src/components/Toast\'
注: 本篇文章使用了 typescript ,如果你是使用的 javascript,只需要把类型去掉即可
Vue开发个简单的Toast组件新手入门实例
最近体验了下Vue,Toast都是前端常用组件,顺便写个入门的实例给同是新手入门的同学一个参考吧
废话不多说,直接放码过来了。。。
Toast.vue 组件代码
<template>
<div ref="toast" class="toast" @click="fadeout" :class="classes" :style="styles"><span class="toast-icon"></span><span class="toast-message"> message </span></div>
</template>
<script>
import lodash from 'lodash'
export default
name: 'Toast',
data()
return
classes: [],
styles:
color: '#FF5500',
,
,
props:
message: String,
duration:
type: Number,
default: 2000 // 持续显示的时长,单位 ms 为 0 则不自动消失需手动点击
,
position:
// 定位,数组格式支持自定义位置,左上比较常用所以顺序为[left, top, right, bottom],
// 单位:px, 若为 0~1 之间的小数时则表示占屏幕的百分比%
// default()return [.1, .1],
// 定位,预设 topLeft|topCenter|topRight|centerLeft|center|centerRight|bottomLeft|bottomCenter|bottomRight
default: 'center',
,
zIndex:
type: Number,
default: 100000
,
maxWidth:
type: String,
default: '300px', // 最大宽度
,
offset:
type: Array,
default()
// 仅用于对预设定位点(如:topLeft|center...)坐标在 [X, Y] 轴的偏移量修正,单位 px
// 作用于 margin-top|margin-left, 可以为负数; > 0 则偏向右下角,< 0 则偏向左上角
return [0, -300]
,
computed:
,
methods:
fadeout()
this.classes.push('fadeout'); // 淡出效果直接覆盖了 fadein 的 css 设置
lodash.delay(() => this.$destroy(), 500); // 淡出动画结束后再销毁
,
show()
this.$set(this.styles, 'zIndex', this.zIndex);
this.$set(this.styles, 'maxWidth', this.maxWidth);
if (lodash.isArray(this.position))
const [left, top, right, bottom] = this.position;
const resolve = (s, n) =>
if (n !== undefined) this.$set(this.styles, s, (n > 0 && n < 1) ? (n*100) + '%' : n +'px');
;
resolve('top', top);
resolve('right', right);
resolve('bottom', bottom);
resolve('left', left);
const isPrePos = lodash.isString(this.position); // 是字符串则认定为默认的预设定位点
if (isPrePos)
const pos = this.position.toString();
const isC1 = pos.indexOf('center') > -1;
const isC2 = pos.indexOf('Center') > -1;
// 设置预设定位点样式
this.classes.push(pos.replace(/([A-Z])/, (s) => '-' + s.toLowerCase()));
// 居中定位修正
if (isC1 || isC2)
if (pos === 'center' || isC1)
this.$set(this.styles, 'marginTop',
((isPrePos ? (this.$refs.toast.clientHeight * -1 / 2) : 0) + this.offset[1]) + 'px');
if (pos === 'center' || isC2)
this.$set(this.styles, 'marginLeft',
((isPrePos ? (this.$refs.toast.clientWidth * -1 / 2) : 0) + this.offset[0]) + 'px');
// 添加淡入效果
this.classes.push('fadein');
this.duration > 0 && lodash.delay(() =>
this.fadeout();
, this.duration);
,
,
created: function ()
this.$nextTick(function()
this.show();
);
,
destroyed: function ()
this.$el.parentNode.removeChild(this.$el)
</script>
<style scoped>
.toast
display: block;
position: fixed;
padding: .5rem;
font-size: .8rem;
background-color: #FFF;
box-shadow: 0 0 5px rgba(0,0,0,.1);
opacity: 0;
word-break: break-all;
word-wrap: break-word;
.toast.top-left
top: 0;
left: 0;
.toast.top-center
top: 0;
left: 50%;
.toast.top-right
top: 0;
right: 0;
.toast.center-left
top: 50%;
left: 0;
.toast.center
top: 50%;
left: 50%;
.toast.center-right
top: 50%;
right: 0;
.toast.bottom-left
bottom: 0;
left: 0;
.toast.bottom-center
bottom: 0;
left: 50%;
.toast.bottom-right
bottom: 0;
right: 0;
.toast.fadein
opacity: 1;
transition: opacity ease-in .2s;
.toast.fadeout
opacity: 0;
transform: scale(.5);
transition: all ease-in-out .4s;
</style>
全局注册及使用方法
ToastTest.vue
<script>
import Vue from "vue"
import lodash from "lodash"
import Toast from "Toast"
let toastTimer;
let toastIndex = 0;
let toastQueueOffset = 0;
const ToastConstructor = Vue.extend(Toast);
Vue.prototype.$toast = function(data)
document.body.appendChild(new ToastConstructor(
el: document.createElement('div'),
propsData: data
).$el);
;
export default
name: "ToastTest",
components: Toast,
methods:
showToast(e)
this.$toast(
message: 'Toast index '+ toastIndex++,
duration: 2000,
position: [e.clientX, e.clientY],
);
,
showToastRand()
this.$toast(
message: 'Toast index '+ toastIndex++,
duration: 0,
position: [parseInt(Math.random()*(window.innerWidth)), parseInt(Math.random()*window.innerHeight)],
);
,
showToastQueue(e)
const duration = 2000;
clearTimeout(toastTimer);
toastTimer = setTimeout(() => toastQueueOffset = 0, duration);
this.$toast(
message: 'Toast index '+ toastIndex++,
duration: duration,
position: [e.clientX+100, 45*toastQueueOffset++],
);
,
</script>
<template>
<div class="articles-ct">
<button class="draft-btn" @click="showToast"> + 鼠标 </button>
<br><br>
<button class="draft-btn" @click="showToastRand"> + 随机 </button>
<br><br>
<button class="draft-btn" @click="showToastQueue"> + 队列 </button>
</div>
</template>
我随便写了三种使用方式示例
- 鼠标定位
- 全屏随机
- 屏幕队列
代码中有部分地方用到了 lodash 库,你可以安装下这个库或者修改下自己实现
下面看看效果图:
功能应该还是比较完善了,根据自己的需求再修改或搭配下参数就好了。
以上是关于vue 3.0 封装 Toast 组件的主要内容,如果未能解决你的问题,请参考以下文章
TypeScript(JavaScript)封装一个Toast组件
TypeScript(JavaScript)封装一个Toast组件
TypeScript(JavaScript)封装一个Toast组件