前言
ElNotification组件是Element-plus组件库中的一个通知组件,一般用来通知文本消息,但是也可以通过在message中渲染一个Vue.VNode来实现更复杂的功能。本文将会讲解如何在ElNotification组件中渲染一个ElProgress进度条。
ElNotification组件的message属性
下面是Element-plus官方文档给出的message属性的两种基本写法
ElMessage('this is a message.') // message为一个字符串
ElMessage({ // message为一个h函数构造的VNode
message: h('p', null, [
h('span', null, 'Message can be '),
h('i', { style: 'color: teal' }, 'VNode'),
]),
})
如果要在消息组件中渲染复杂的内容,就需要使用h函数构造一个VNode,下面先来介绍h函数。
h函数
h函数是一个辅助创建虚拟DOM的工具函数,它接收3个参数,分别是type, props, children,其中只有type是必传参数,h函数的返回值类型是VNode。关于h函数更详细的说明可以看渲染函数API
function h(
type: string | Component, // 第一个参数,原生DOM元素的字符串或组件
props?: object | null, // 第二个参数,要传递给子组件的prop
children?: Children | Slot | Slots // 第三个参数,子节点
): VNode
实现代码
在notiBox中调用ElNotification组件,并借助h函数向ElNotification组件传入一个progress组件。
notiBox.vue
<script>
import { ElNotification } from 'element-plus'
import { h } from 'vue'
import progress from './progress.vue'
export default {
name: 'CalculationBook',
setup() {
let a = 1
let notice = ElNotification({
title: '下载进度',
position: 'bottom-right',
duration: 0,
message: h(progress, {
propA: a, // 传递给子组件progress的prop
// 事件要以onXxx的形式书写
onFinish: (status) => {
if (status.value == 'ok') {
notice.close() // 关闭ElNotification
}
}
})
})
}
</script>
progress.vue
<template>
<div class="task-list">
<div class="task-item">
<i class="iconfont icon-file-folder"></i>
<span>下载任务列表</span>
<el-progress
:percentage="progress"
/>
<span>{{ propA }}</span>
</div>
</div>
</template>
<script>
import { ref } from 'vue'
import { ElProgress } from 'element-plus'
export default {
name: 'progress',
props: ['propA'], // 接收父组件传递的prop
emits: ['finish'], // 接收父组件传递的事件
setup(props, { emit }) {
let progress = ref(0)
let status = ref('')
// 改变进度条状态的相关逻辑代码
function changeProgress() {
...
if (progress.value >= 100 || status.value == 'ok') {
emit('finish', status.value) // 发射事件,并传递一个参数
}
...
}
return {
progress,
status,
}
}
}
</script>
<style scoped>
.task-item {
width: 290px;
display: grid;
grid-template-columns: 50px 1fr;
grid-template-rows: 2fr 1fr 2fr;
align-items: center;
}
.task-item i {
font-size: 30px;
color: rgb(252, 203, 66);
grid-column-start: 1;
grid-column-end: 2;
grid-row-start: 1;
grid-row-end: 4;
}
</style>
实现效果
参考资料
vue3中h函数的常见使用方式