前言

ElNotification组件是Element-plus组件库中的一个通知组件,一般用来通知文本消息,但是也可以通过在message中渲染一个Vue.VNode来实现更复杂的功能。本文将会讲解如何在ElNotification组件中渲染一个ElProgress进度条。

ElNotification组件的message属性

下面是Element-plus官方文档给出的message属性的两种基本写法
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函数的常见使用方式

Logo

前往低代码交流专区

更多推荐