Vue3 + TypeScript,使用祖先传后代模式重构父传子模式

父传子模式

父组件 SampleInput.vue

javascript 复制代码
<script setup lang="ts" name="SampleInput">
import { ref } from "vue";
import type { ApplyBasicInfo, Apply, ApplySample } from "@/interface";
import CommonApplySampleTable from "@/components/common/CommonApplySampleTable.vue";

// 定义数据
// 受理基础信息
const applyBasicInfo = ref<ApplyBasicInfo | null>(null)
// 受理样品表格数据
const applySampleTableData = ref<ApplySample[]>([]);
// 滚动到离顶部表头的距离
const applySampleTableScrollTop = ref(0);

......

</script>

<template>
  <!-- 提供数据给子类 -->
  <CommonApplySampleTable
    :apply-sample-list="applySampleTableData"
    :accept-type="applyBasicInfo.acceptType"
    :scroll-top="applySampleTableScrollTop"
    operate-command-type="info-add" />
</template>

子组件 CommonApplySampleTable.vue

javascript 复制代码
<script setup lang="ts" name="CommonApplySampleTable">
import type { ApplySample } from "@/interface";
import ApplySampleSZTable from "@/components/ApplySampleSZTable.vue";
import ApplySampleOtherTable from "@/components/ApplySampleOtherTable.vue";

// 接收父类提供的数据
const props = withDefaults(
  defineProps<{
    // 受理样品列表
    applySampleList: ApplySample[];
    // 受理类别
    acceptType: string;
    // 操作指令类型:新增删除:info-add;修改:info-modify;查看:info-view
    operateCommandType: "info-add" | "info-modify" | "info-view";
    // 滚动到离顶部表头的距离
    scrollTop?: number;
  }>(),
  {
    applySampleList: () => [],
    acceptType: "",
    operateCommandType: "info-add",
    scrollTop: 0
  }
);
</script>

<template>
  <!-- 受理样品表格,水质类 -->
  <ApplySampleSZTable
    v-if="props.acceptType.includes(`GD`)"
    :applySampleData="props.applySampleList"
    :applySampleTableScrollTop="props.scrollTop"
    :operate-command-type="props.operateCommandType" />
  <!-- 受理样品表格,其他 -->
  <ApplySampleOtherTable
    v-else
    :applySampleData="props.applySampleList"
    :applySampleTableScrollTop="props.scrollTop"
    :operate-command-type="props.operateCommandType" />
</template>

<style scoped lang="scss"></style>

祖先传后代模式

父组件 SampleInput.vue

javascript 复制代码
<script setup lang="ts" name="SampleInput">
import { ref, provide, computed } from "vue";
import type { ApplyBasicInfo, Apply, ApplySample } from "@/interface";
import CommonApplySampleTable from "@/components/common/CommonApplySampleTable.vue";

// 定义数据
// 受理基础信息
const applyBasicInfo = ref<ApplyBasicInfo | null>(null)
// 受理样品表格数据
const applySampleTableData = ref<ApplySample[]>([]);
// 滚动到离顶部表头的距离
const applySampleTableScrollTop = ref(0);

......

// 提供数据给后代
// 受理样品列表
provide("applySampleList", applySampleTableData); // applySampleTableData是个Ref对象,不需要.value,传递ref对象本身(响应式数据)
// 受理类别
provide(
  "acceptType",
  computed(() => applyBasicInfo.value.acceptType) // applyBasicInfo.value.acceptType 是派生数据(属性数据),通过computed提供响应式数据
);
// 操作指令类型:新增删除:info-add;修改:info-modify;查看:info-view
provide("operateCommandType", ref("info-add"));
// 滚动到离顶部表头的距离
provide("scrollTop", applySampleTableScrollTop); // applySampleTableScrollTop是个Ref对象,不需要.value,传递ref对象本身(响应式数据)
</script>

<template>
  <CommonApplySampleTable />
</template>

子组件 CommonApplySampleTable.vue

javascript 复制代码
<script setup lang="ts" name="CommonApplySampleTable">
import type { ApplySample } from "@/interface";
import ApplySampleSZTable from "@/components/ApplySampleSZTable.vue";
import ApplySampleOtherTable from "@/components/ApplySampleOtherTable.vue";
import { inject, type Ref, ref } from "vue";

// 接收祖先提供的数据
// 受理样品列表
const applySampleList = inject<Ref<ApplySample[]>>("applySampleList", ref([]));
// 受理类别
const acceptType = inject<Ref<string>>("acceptType", ref(""));
// 操作指令类型:新增删除:info-add;修改:info-modify;查看:info-view
const operateCommandType = inject<Ref<"info-add" | "info-modify" | "info-view">>("operateCommandType", ref("info-add"));
// 滚动到离顶部表头的距离
const scrollTop = inject<Ref<number>>("scrollTop", ref(0));
</script>

<template>
  <!-- 受理样品表格,水质类 -->
  <ApplySampleSZTable
    v-if="acceptType.includes(`GD`)"
    :applySampleData="applySampleList"
    :applySampleTableScrollTop="scrollTop"
    :operate-command-type="operateCommandType" />
  <!-- 受理样品表格,其他 -->
  <ApplySampleOtherTable
    v-else
    :applySampleData="applySampleList"
    :applySampleTableScrollTop="scrollTop"
    :operate-command-type="operateCommandType" />
</template>

<style scoped lang="scss"></style>
相关推荐
开开心心就好1 小时前
批量提取PDF中的图片,直接导出原图
前端·javascript·支持向量机·智能手机·pdf·html·启发式算法
Setsuna_F_Seiei3 小时前
前端转型 Agent 开发 05 之 Agent Hooks 与 Checkpointer(让 Agent 从全自动转变人为可掌控)
前端·agent·ai编程
百万蹄蹄向前冲5 小时前
风扇转了一晚上MVP专家团翻车事故
前端·人工智能
默_笙5 小时前
🏛 给 AI 配一间办公室:Harness Engineering 六大模块与它的实现
前端·javascript
linux_cfan6 小时前
videojs v10 源代码系列解读:14 · 谓词守卫:在运行时安全地调用能力
前端·javascript·音视频
kyriewen7 小时前
我扒了 10,221 条 JD:腾讯技术岗 75% 在要 AI
前端·人工智能·ai编程
郑州光合科技余经理7 小时前
同城外卖小程序开发:下单成功后,后台导出能不能对上用户端状态
开发语言·前端·git·后端·uni-app·php·ai编程
IT_陈寒8 小时前
Vue的响应式让我熬到凌晨三点,原来漏了这个小细节
前端·人工智能·后端
Blanche15008 小时前
利用 RAG 为答疑机器人扩展知识范围
前端
天若有情6738 小时前
【纯前端小工具】公历生日转农历,批量查询每年农历生日对应的公历日期(GitHub Pages在线直接用)
前端·javascript·github pages·农历转换·lunisolar·网页小工具