提升 Vue 项目开发效率:高阶组件 RenderFunction 的灵活性与实战应用

Vue 3 开发中,我们常常需要创建可复用的组件,但传统的组件封装方式有时会带来限制。比如,一个表格组件可能需要支持不同的数据结构,一个弹窗组件可能需要动态更改内容。面对这种需求,我们通常会通过 slotsScoped Slots 来解决,但它们的灵活性仍然有限。

有没有更好的方法?答案是:直接让组件接受一个渲染函数,让父组件完全控制渲染逻辑,而 RenderFunction 组件仅负责调用这个函数。这样,我们就能实现 更高自由度的组件定制能力,避免重复封装多个类似的 UI 组件。

实现

tsx 复制代码
import type { PropType, VNodeTypes } from "vue";
import { defineComponent } from "vue";

export type RenderFunc = (props: Record<string, unknown>) => VNodeTypes;

export default defineComponent({
  name: "RenderFunction",
  props: {
    renderFunc: {
      type: Function as PropType<RenderFunc>,
      required: true,
    },
  },
  render() {
    return this.renderFunc(this.$attrs);
  },
});

Props

Prop 名称 类型 是否必填 说明
renderFunc (props: Record<string, unknown>) => VNodeTypes 传递自定义渲染函数,返回 Vue 虚拟 DOM 节点
v-bind="$attrs" Record<string, unknown> 组件外部传入的额外属性,作为 renderFunc 的参数

适用场景

场景 说明
动态组件渲染 让父组件决定如何渲染,而不是硬编码 UI 结构
自定义 UI 组件 适用于开发可定制的 UI 库,如动态表单、可变布局组件
高阶组件(HOC RenderFunction 作为通用的渲染容器,实现不同 UI 逻辑
JSX 支持 结合 JSX,使渲染逻辑更简洁

示例

vue 复制代码
<template>
  <RenderFunction :renderFunc="myRenderFunc" :message="'Hello, Vue!'" />
</template>

<script setup lang="ts">
import { h } from "vue";
import RenderFunction from "./RenderFunction.vue";

const myRenderFunc = (props: Record<string, unknown>) => {
  return h("div", { class: "custom-class" }, `Message: ${props.message}`);
};
</script>

说明

  • renderFunc 负责定义组件的渲染方式。
  • props 参数用于传递动态数据。

结合 JSX 语法

如果你喜欢 JSX 语法,可以这样写:

vue 复制代码
<script setup lang="tsx">
import RenderFunction from "./RenderFunction.vue";

const myRenderFunc = (props: Record<string, unknown>) => (
  <div style="color: blue;">{props.message}</div>
);
</script>

<template>
  <RenderFunction :renderFunc="myRenderFunc" :message="'Hello JSX!'" />
</template>

说明

  • JSX 语法使代码更加直观,可读性更高。
  • 适用于 Vue 3<script setup> 语法。

适用于动态 UI

可以使用 RenderFunction 渲染不同结构的 UI,比如表格:

vue 复制代码
<template>
  <RenderFunction :renderFunc="tableRender" :data="items" />
</template>

<script setup lang="ts">
import { h } from "vue";
import RenderFunction from "./RenderFunction.vue";

const items = [
  { id: 1, name: "Vue" },
  { id: 2, name: "React" },
  { id: 3, name: "Svelte" },
];

const tableRender = (props: Record<string, unknown>) => {
  return h("table", { border: 1 }, [
    h("tr", [h("th", "ID"), h("th", "Name")]),
    ...props.data.map((item: any) =>
      h("tr", [h("td", item.id), h("td", item.name)])
    ),
  ]);
};
</script>

说明

  • RenderFunction 组件使表格结构可以动态配置,无需创建新的子组件。

总结

  1. RenderFunction 组件是一种 高阶渲染组件,提供极大的灵活性。
  2. 适用于 动态 UI、JSX、自定义渲染逻辑 的场景。
  3. 避免创建多个类似的 UI 组件,提高代码复用性。

如果你的项目有 动态内容渲染需求 ,这个组件将是一个 高效且优雅的解决方案!

相关推荐
yume_sibai8 小时前
02-Flutter进阶开发
前端·flutter
a1117768 小时前
莱茵生命终端 网页 html
前端·开源
水月清辉8 小时前
CSS 常用语法详解
前端·css
梨涡泥窝9 小时前
JavaWeb——基于 Spring Boot + Vue 的图书管理系统的设计与实现
vue.js·spring boot·后端
Eric_见嘉9 小时前
打开这个 VSC 设置「组件引用位置」和数量就都清楚了
前端·typescript·visual studio code
李高钢9 小时前
Python Tornado 框架入门:从零搭建你的第一个异步 Web 应用
前端·python·tornado
宁风9 小时前
JavaScript:函数体系-1
前端·javascript
mmsx10 小时前
Android 手簿 ADB 无线调试全攻略:USB 转 WiFi 一键连接
android·前端
guwentian10 小时前
Rolldown vs esbuild vs Webpack:Rust 打包器大战我们该怎么选
前端·webpack·rust·esbuild
特立独行的猫A10 小时前
用纯 Rust 重写 Podcastfy:把网页、PDF 和一段文字,变成一档双人对话播客
前端