组件分析
三种样式,priamry,error,info->三种样式->三种类名
无需事件。 组件特殊性:其他组件引用该组件时一般是用js调用,该组件调用后需要销毁。
代码
message/index.vue
<template>
<transition name="down" @after-leave="destroy">
<div v-show="isVisable"
class="min-w-[420px] fixed top-[20px] left-[50%] translate-x-[-50%] z-50 flex items-center px-3 py-1.5 rounded-sm border cursor-pointer"
:class="styles[type].containerClass">
<m-svg-icon :name="styles[type].icon" :fillClass="styles[type].fillClass"
class="h-1.5 w-1.5 mr-1.5"></m-svg-icon>
<span class="text-sm" :class="styles[type].textClass">
{{ content }}
</span>
</div>
</transition>
</template>
<script>
import mSvgIcon from '../svg-icon/index.vue'
/**
* 消息类型可选项
*/
const typeEnum = ['success', 'warn', 'error']
</script>
<script setup>
import { ref, onMounted } from 'vue'
const props = defineProps({
/**
* message 的消息类型
*/
type: {
type: String,
required: true,
validator(val) {
const result = typeEnum.includes(val)
if (!result) {
throw new Error(`你的 type 必须是 ${typeEnum.join('、')} 中的一个`)
}
return result
}
},
/**
* 描述文本
*/
content: {
type: String,
required: true
},
/**
* 展示时长
*/
duration: {
type: Number
},
/**
* 关闭时的回调
*/
destroy: {
type: Function
}
})
// 样式表数据
const styles = {
// 警告
warn: {
icon: 'warn',
fillClass: 'fill-warn-300',
textClass: 'text-warn-300',
containerClass:
'bg-warn-100 border-warn-200 hover:shadow-lg hover:shadow-warn-100'
},
// 错误
error: {
icon: 'error',
fillClass: 'fill-error-300',
textClass: 'text-error-300',
containerClass:
'bg-error-100 border-error-200 hover:shadow-lg hover:shadow-error-100'
},
// 成功
success: {
icon: 'success',
fillClass: 'fill-success-300',
textClass: 'text-success-300',
containerClass:
'bg-success-100 border-success-200 hover:shadow-lg hover:shadow-success-100'
}
}
// 控制显示处理
const isVisable = ref(false)
/**
* 保证动画展示,需要在 mounted 之后进行展示
*/
onMounted(() => {
isVisable.value = true
/**
* 延迟时间关闭
*/
setTimeout(() => {
isVisable.value = false
}, props.duration)
})
</script>
<style lang="scss" scoped>
.down-enter-active,
.down-leave-active {
transition: all 0.5s;
}
.down-enter-from,
.down-leave-to {
opacity: 0;
transform: translate3d(-50%, -100px, 0);
}
</style>
message/index.js
import { h, render } from 'vue'
import messageComponent from './index.vue'
export const message = (type, content, duration = 3000) => {
/**
* 动画结束时的回调
*/
const onDestroy = () => {
// 3. message 销毁
render(null, document.body)
}
// 1. 返回 vnode
const vnode = h(messageComponent, {
type,
content,
duration,
destroy: onDestroy
})
// 2. render
render(vnode, document.body)
}
在其他组件下用JS调用该组件
message('success','图片下载完成')