Vue开发学习笔记:动态渲染自定义封装的uview-plus的Toast组件

发布于:2025-06-13 ⋅ 阅读:(26) ⋅ 点赞:(0)

1.封装uview-plus的Toast组件

在src下面创建一个components,然后在创建一个HxToast(自取)文件夹,自定义封装一个uview-plus的Toast组件(多文件模式)

index.vue文件代码

<template>
  <up-toast ref="upToastRef"></up-toast>
</template>

<script lang="ts" src="./index.ts"></script>

<style lang="scss" scoped>
@import "./index.scss";
</style>

index.ts文件代码 

import { defineComponent, onMounted, ref } from "vue";
import type { Toast, ToastProps } from "uview-plus/toast"; // 直接从uview-plus导入类型
export default defineComponent({
  name: "HxToast",
  components: {},
  emits: ["showHxToast"],
  props: {
    /**
     * 层级
     * string | number;
     */
    zIndex: { type: String },
    /**
     * 是否加载中
     * @default false
     */
    loading: { type: Boolean },
    /**
     * 显示的文本
     * string | number;
     */
    message: { type: String },
    /**
     * 图标,或者绝对路径的图片
     */
    icon: { type: String },
    /**
     * toast出现的位置
     * @default "center"
     * "top" | "center" | "bottom";
     */
    position: { type: String },
    /**
     * 主题类型
     * @default "default"
     * "default" | "error" | "success" | "loading";
     */
    type: { type: String },
    /**
     * 跳转的参数
     * Record<string, any>;
     */
    params: { type: Object },
    /**
     * 展示时间,单位ms
     * @default 2000
     * string | number;
     */
    duration: { type: Number },
    /**
     * 执行完后的回调函数
     */
    complete: () => {},
  },
  setup: (props) => {
    console.log("🚀 ~ props:", props);
    // 根据ref获取up-toast对象
    const upToastRef = ref<InstanceType<typeof Toast> | null>(null);

    // 定义 Props 类型
    // const props = defineProps<{

    // }>();

    // 显示Toast
    const showHxToast = () => {
      console.log("自定义组件测试");
      // emits("showHxToast");
      // @ts-ignore 忽略错误,其实可用
      upToastRef.value.show(props);
    };
    onMounted(() => {
      showHxToast();
    });
    return { upToastRef, showHxToast };
  },
});

index.scss 文件代码 

.u-toast {
  position: fixed !important; /* 必须设置定位否则z-index无效 */
  z-index: 999999 !important;
}

1.1关键点

(1).在封装组件的.vue页面,使用uview-plus的Toast组件时,需要绑定ref属性

(2).在封装组件的.ts通过ref获取.vue中的Toast组件,定义一个与.vue页面的ref属性相同名称的变量获取对象

import type { Toast } from "uview-plus/types/comps/toast"; // 直接从uview-plus导入类型
// 根据ref获取up-toast对象
const upToastRef = ref<InstanceType<typeof Toast> | null>(null);

(3)..ts文件中通过获取的Toast对象,在方法中调用uview-plus的Toast组件自带的show方法

// 显示Toast
    const showHxToast = () => {
      console.log("自定义组件测试");
      // emits("showHxToast");
      // @ts-ignore 忽略错误,其实可用
      upToastRef.value.show(props);
    };

(3).在封装组件的.ts文件中还需要设置emits暴露showHxToast方法方便在其他的.ts文件中使用,同时设置需要在调用时传入到自定义组件的参数,设置props属性,参数名称为了方便使用设置为跟uview-plus的Toast需要的属性一致

2.创建工具类

在src创建一个文件夹utility,定义一个工具类utility,用于动态渲染自定义封装的Toast组件

import { createVNode, render } from "vue";
import HxToast from "@/components/HxToast/index.vue";

// 创建 自定义组件 容器
const container = document.createElement("div");
container.className = "hx-toast-container";
document.body.appendChild(container);

// 创建 自定义组件 实例
const createCustomCom = (options: any) => {
  // 创建 VNode
  const vnode = createVNode(HxToast, options as any);

  // 创建临时容器
  const tempContainer = document.createElement("div");

  // 渲染到临时容器
  render(vnode, tempContainer);

  // 将元素添加到主容器
  container.appendChild(vnode.el as HTMLElement);
};

// 定义静态方法
const CustomStatic = {
  // 动态创建自定义HxToast组件
  showHxToast(options: any) {
    createCustomCom(options);
  },
};

// 导出静态方法
export default CustomStatic;

// 导出组合式函数(可选)
export const customStatic = () => {
  return CustomStatic;
};

// 使用案例
// import { customStatic } from "@/utility/utility";
// const { showHxToast } = customStatic();
//           showHxToast({
//             message: "测试",
//             type: "success",
//             position: "top",
//             icon: "loading",
//             duration: 3000, // 不自动关闭
//           });

2.1关键点

(1).使用 createVNode创建一个自定义组件的节点,然后使用render方法将组件再渲染到临时容器最后挂载到主容器

const vnode = createVNode(HxToast, options as any);

3.在其他的Vue画面中使用(多文件开发)

3.1先导入工具类utility

import CustomStatic from "@/utility/utility";

3.2在需要的地方调用自定义的组件

CustomStatic.showHxToast({
            message: "测试",
            type: "success",
            position: "top",
            icon: "loading",
            duration: 3000, // 3秒关闭
          });