Vue3 使用teleport内置组件 封装提示栏组件并实现函数化调用

目录

一;Teleport 内置组件

二;提示栏组件要实现的功能:

三;设计 Message 组件 实现基本的样式与功能

四;封装 创建 body 元素的子标签结点的函数 useDOMCreate,将 teleport 标签中的内容放入到创建的这个结点,让HTML标签结构更加合理。

五:函数化调用该提示栏

六:使用提示栏组件以及合适会被触发


一;Teleport 内置组件

官方定义:

Teleport 提供了一种干净的方法,允许我们控制在 DOM 中哪个父节点下呈现 HTML,而不必求助于全局状态或将其拆分为两个组件。

使用场景:

我们在A组件中使用B组件时,B组件中的 DOM 结构会被渲染到 A 组件中书写 B 组件的对应位置,但是有时候我们不希望它显示在该位置,而是显示到Vue app之外的其他位置: 比如移动到body元素上,或者我们有其他的div#app之外的元素上;

个人理解:

1.标签内 to 属性 指定 写在 teleport 标签中的内容被放入到指定的标签结构当中。

2.to 属性接收一个字符串,内容是选中该某一 html 的 css 选择器属性 比如 .class 类属性 #id id属性,也可以是 html 标签元素,如 body。

3.teleport 标签中的内容会被放入该 css 选择属性所在的标签当中。为了使得 html 结构更加合理。

二;提示栏组件要实现的功能:

自定义提示栏提示状态(成功,失败,默认);自定义提示栏中的内容;自定义多久后消失;允许手动关闭提示栏;

注:想要实现自定义,其实就是父组件在使用该子组件的时候动态的向子组件传递对应 prop 内容,子组件通过 props 接收并使用,所以要预先设计好要接收哪些 props 的内容。

因为要自定义实现提示栏类型和提示内容,所以该 Message 组件接收俩个prop属性,一个是 type用于设置提示栏类型,一个是 message 用于展示提示栏的提示内容。

三;设计 Message 组件 实现基本的样式与功能

模板和样式使用的 bootstrap 不做讲解

<template>
  <teleport to="#message">
    <div class="alert message-info fixed-top w-50 mx-auto d-flex justify-content-between mt-2"
      :class="classObject" v-if="isVisible">
      <span>{{message}}</span>
      <button type="button" class="close" aria-label="Close" @click.prevent="hide">
        <span aria-hidden="true">&times;</span>
      </button>
    </div>
  </teleport>
</template>

<script lang="ts">
import { defineComponent, PropType, ref } from 'vue'
import useDOMCreate from '../hooks/useDOMCreate'
// 限制 提示栏的提示类型
export type MessageType = 'success' | 'error' | 'default'
export default defineComponent({
  props: {
    // 动态接收的提示信息
    message: String,
    // 动态接收的提示类型
    type: {
      type: String as PropType<MessageType>,
      default: 'default'
    }
  },
  emits: ['close-message'],
  setup(props, context) {
    // 创建插入结点的封装方法
    useDOMCreate('message')
    // 是否显示提示栏的标志
    const isVisible = ref(true)
    // 显示哪种类型的提示栏
    const classObject = {
      'alert-success': props.type === 'success',
      'alert-danger': props.type === 'error',
      'alert-primary': props.type === 'default'
    }
    // 点击取消后调用的函数
    const hide = () => {
      isVisible.value = false
      context.emit('close-message', true)
    }
    return {
      classObject,
      isVisible,
      hide
    }
  }
})

</script>

四;封装 创建 body 元素的子标签结点的函数 useDOMCreate,将 teleport 标签中的内容放入到创建的这个结点,让HTML标签结构更加合理。

这一步完成后,提示栏组件 Message 封装完成。

// 引入卸载生命周期--当组件被卸载的时候把创建的 DOM 元素也删掉
import { onUnmounted } from 'vue'

function useDOMCreate(nodeId: string) {
// 创建 div 标签
  const node = document.createElement('div')
// 给 div 标签 绑定 id 属性
  node.id = nodeId
// 给 body 元素添加子元素
  document.body.appendChild(node)
// 当组件被卸载的时候把创建的 DOM 元素也删掉
  onUnmounted(() => {
    document.body.removeChild(node)
  })
}

export default useDOMCreate

五:函数化调用该提示栏

createApp介绍:

返回一个提供应用上下文的应用实例。应用实例挂载的整个组件树共享同一个上下文。

接收俩个参数,第一个参数是组件对象(要实例化哪个组件对象),第二个参数是这个被实例化的组件需要的 prop 属性。

1.封装一个函数,在函数中使用 createApp 方法创建一个 Message 的组件实例,创建一个新的结点,把组件实例挂载到该结点上,设置定时器,显示超过时间后卸载掉该结点。

2.函数接收参数:Message组件需要的 prpo 属性,显示时间。

import { createApp } from 'vue'
import Message from './Message.vue'
// 限制提示栏的类型
export type MessageType = 'success' | 'error' | 'default'
// 定义函数,之后调用该函数就可以在需要显示提示栏的地方显示提示信息
const createMessage = (message: string, type: MessageType, timeout = 2000) => {
  // 创建一个组件实例对象
  // 第一个参数 自定义Message组件 第二个参数 该组件需要的 prop 属性
  const messageInstance = createApp(Message, {
    message,
    type
  })
  // 创建结点
  const mountNode = document.createElement('div')
  // 把结点添加到 DOM树中
  document.body.appendChild(mountNode)
  // 调用组件实例对象的 mount 方法 把实例化的内容挂载到对应结点中
  messageInstance.mount(mountNode)
  // 定时器,到时间后卸载掉该结点
  setTimeout(() => {
    messageInstance.unmount(mountNode)
    document.body.removeChild(mountNode)
  }, timeout)
}

export default createMessage

六:使用提示栏组件以及合适会被触发

请求错误的提示信息

项目中使用 vuex 进行状态管理,vuex 中 仓库 state 中设置一个 error 字段,类型为对象,包含是否错误标志 status 和 错误提示信息 message

在 mutation 中配置 setError 回调函数,在axios的相应回调错误中进行触发 setError 改变 Vuex state 中 error 的状态。

在 App 组件中通过监听属性 watch 对 vuex error字段进行监视,若 error 对象 status 为 true 且 message 信息存在 则触发上方定义的 createMessage 函数进行 Message的挂载与展示

其他类型的提示信息:

在适当的位置调用该函数即可。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值