Renderless 思想正在影响前端开发

news2024/11/28 10:50:06

本文由前端小伙伴@方长_beezen 原创。欢迎大家踊跃投稿。
原文链接:https://juejin.cn/post/7385752495535472655

前言

截止到 2024 年,跨端应用开发所需要考虑的兼容性,已经涵盖了框架、平台和设备类型等多个方面,例如:

  • 框架:如 React、Vue、Angular、Svelte、Ember 等。
  • 平台:如 鸿蒙、Android、iOS、小程序、快应用、H5 等。
  • 设备:如 PC、移动设备、车载设备等。

多元化的需求场景,对前端工程师的要求也是越来越高,他们必须掌握 2 种以上的编程语言或者开发框架,不然就很难胜任跨端应用开发的岗位。前端开发工程师的开发日常,也因此变得愈发复杂。

在如此严峻的前端大环境下,无渲染组件 (Renderless Components[1])的概念在开发者社区逐渐兴起,频繁出现在各类流行框架中。最早,由 React 社区提出,开发者可以通过将一个 render 函数作为 prop 传递给组件,这个函数可以接收需要的数据,并返回渲染的 UI 内容。后来,在 Vue 框架中提出了 slots 概念,组件内部真实需要渲染的 UI 内容,可以通过插槽的形式控制。现在,无渲染组件被视为一种新模式,其核心理念是将组件的逻辑与表现分离,达到高可复用的效果。换句话说,无渲染组件只关注组件的内部逻辑行为,而将 UI 表现内容交由调用组件来处理。

无渲染组件通过将组件逻辑行为抽象,我们可以更轻松地在各种不同的 UI 表现上下文中重用它,它的出现不仅减轻前端工程师的工作任务,也为跨端应用的开发提供了更多的可能性。

什么是无渲染组件?

无渲染组件(Renderless Components)是一种设计模式,其核心理念是将组件的逻辑和表现分离。具体来说,无渲染组件只关注业务逻辑和状态管理,而不关心具体的 UI 渲染实现。常见的无渲染组件实现方式如下:

Render Props

通过 render prop 属性将一个函数作为子组件传递,使得父组件可以完全控制 UI 渲染。

React 无渲染组件实现,如下:

import React from "react";

class MouseTracker extends React.Component {
  constructor(props) {
    super(props);
    this.state = { x: 0, y: 0 };
  }

  // 组件内部逻辑,可复用
  handleMouseMove = (event) => {
    this.setState({
      x: event.clientX,
      y: event.clientY,
    });
  };

  render() {
    // this.props.render 渲染子组件
    return (
      <div onMouseMove={this.handleMouseMove}>
        {this.props.render(this.state)}
      </div>
    );
  }
}

在父组件调用时,(x,y) 属性值由无渲染组件提供,UI 渲染则可以自定义控制:

<MouseTracker render={ ({ x, y }) => (
<h1>The mouse position is ({x}, {y})</h1>
) } />

Scoped Slots

Scoped Slots 是一种允许父组件完全控制子组件渲染内容的模式,通过 Scoped Slots 向父子组件双向传递数据和方法,而父组件则负责具体的 UI 渲染。

Vue 无渲染组件实现,如下:

<template>
  <slot :mouse="mouse"></slot>
</template>

<script>
  export default {
    data() {
      return {
        mouse: { x: 0, y: 0 },
      };
    },
    mounted() {
      window.addEventListener("mousemove", this.handleMouseMove);
    },
    methods: {
      handleMouseMove(event) {
        this.mouse = { x: event.clientX, y: event.clientY };
      },
    },
  };
</script>

在父组件调用时,(x,y) 属性值由无渲染组件提供,UI 渲染则可以自定义控制。

<template>
  <MouseTracker v-slot="{ mouse }">
    <h1>The mouse position is ({{ mouse.x }}, {{ mouse.y }})</h1>
  </MouseTracker>
</template>

<script>
  import MouseTracker from "./MouseTracker.vue";
  export default {
    components: {
      MouseTracker,
    },
  };
</script>

无渲染组件 vs 传统组件

除了上面提到的 render props 和 slots 之外,还有很多其他类似的无渲染组件应用场景。我们不需要关注怎样实现才算是无渲染组件,它只是一种思想,用于将传统组件的逻辑和表现进行分离,从而达到高可复用的一种状态。例如 React 中 HOC(高阶组件)、现在主流的 React Hooks 和 Vue Composition API 等方式,都为实现无渲染组件提供了有利条件。值得一提,Renderless 设计模式特别适合跨端应用的开发,将包含各端应用的特性兼容代码提取到 UI 层特性层实现。

下面是无渲染组件对比传统组件的特性对照表:

特点无渲染组件传统组件
逻辑与表现的分离1、只包含业务逻辑,不包含具体的 UI 渲染。 2、渲染由父组件或使用它的组件决定。 3、适合复用复杂的逻辑而不关心具体的 UI 表现。1、包含业务逻辑和 UI 渲染。 2、组件本身决定如何渲染 UI。 3、适合封装独立的功能模块,包含逻辑和展示。
复用性高度复用性,逻辑可以在不同的 UI 实现中复用复用性较低,逻辑和 UI 紧耦合。
灵活性更加灵活,父组件可以完全控制渲染方式和样式。灵活性较低,UI 表现固定。
测试难度1、测试相对简单,只需测试逻辑部分。 2、不涉及 UI 渲染,测试范围更集中1、测试较复杂,需要测试逻辑和 UI 渲染。 2、需要关注组件的整体行为,包括展示和交互.

无渲染组件的优势在于逻辑与表现分离,实现了高复用性和极大灵活性。它允许父组件可以自定义渲染方式和样式,增强了组件的组合能力,使开发更高效、代码更简洁。同时,无渲染组件还简化了测试过程,保障了应用的稳定性。

无渲染组件 vs 公共函数

在日常项目开发中,我们会将项目中的公共逻辑封装为纯函数,以实现代码复用,它们一般不会涉及具体的 UI 渲染和组件的生命周期管理。虽然,无渲染组件也是类似的设计思想。但是,它会利用框架提供的状态管理和数据流特性,将实现更高级的组件功能复用。总而言之,无渲染组件更专注于将组件的逻辑与 UI 分离,不仅仅只考虑公共能力的抽象。

通过无渲染组件的设计思想,我们可以显著地减少开发工作量,同时最大限度地复用组件逻辑,保障模块功能的完整性稳定性

下面的两张图,进一步展示了无渲染组件和传统公共函数在设计思想上的异同之处:

在这里插入图片描述

无渲染组件库

目前,采用无渲染组件思想设计的优秀组件库有 TinyVue[2],它目标兼容 Vue、Vue3、React、Angular、Solid 等框架,覆盖 PC 端和 Mobile 端。
在这里插入图片描述

TinyVue 充分采用了无渲染组件的设计思想,将可复用的逻辑行为抽象到 renderless 模块中,每一个组件的 UI 表现又单独抽象到 PC 模块和 Mobile 模块,实现了跨端、跨版本的高可重用性。

下面是 TinyVue 官方发布的组件架构图:

在这里插入图片描述
在这里插入图片描述

TinyVue 组件库可以在不同终端、不同技术栈的场景下使用,得益于其底层强大的兼容封装能力,暴露给用户使用的 API 接口基本相同,极大地降低了跨端应用中的学习和迁移成本。

最后

Renderless 设计模式的崛起标志着前端开发进入了更加灵活和高效的时代。通过将组件的逻辑与 UI 表现分离,Renderless 组件不仅提升了代码的复用性和可维护性,还为开发者在多平台、多技术栈下的应用开发提供了更多可能性。随着这一设计模式的逐步普及和应用,我们可以期待未来跨端开发将更加轻松和高效。

参考资料

  • Vue renderless components[3]
  • Understanding Renderless Components in Vue[4]
  • 从 0 到 1 实现 OpenTiny 组件库跨框架技术[5]
  • OpenTiny[6]

参考资料
[1]Renderless Components: https://www.patterns.dev/vue/renderless-components/

[2]TinyVue: https://github.com/opentiny/tiny-vue

[3]Vue renderless components: https://www.patterns.dev/vue/renderless-components/

[4]Understanding Renderless Components in Vue: https://www.telerik.com/blogs/understanding-renderless-components-vue

[5]从 0 到 1 实现 OpenTiny 组件库跨框架技术: https://www.cnblogs.com/huaweiyun/p/17776415.html

[6]OpenTiny: https://github.com/opentiny/tiny-vue/blob/dev/README.zh-CN.md

关于OpenTiny

OpenTiny 是一套企业级 Web 前端开发解决方案,提供跨端、跨框架、跨版本的 TinyVue 组件库,包含基于 Angular+TypeScript 的 TinyNG 组件库,拥有灵活扩展的低代码引擎 TinyEngine,具备主题配置系统TinyTheme / 中后台模板 TinyPro/ TinyCLI 命令行等丰富的效率提升工具,可帮助开发者高效开发 Web 应用。

欢迎加入 OpenTiny 开源社区。添加微信小助手:opentiny-official 一起参与交流前端技术~
OpenTiny 官网:https://opentiny.design/
OpenTiny 代码仓库:https://github.com/opentiny/
TinyVue 源码:https://github.com/opentiny/tiny-vue
TinyEngine 源码: https://github.com/opentiny/tiny-engine
欢迎进入代码仓库 Star🌟TinyEngine、TinyVue、TinyNG、TinyCLI~ 如果你也想要共建,可以进入代码仓库,找到 good first issue标签,一起参与开源贡献~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1896990.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AI学习与实践6_AI解场景Agent应用预研demo

前言 学习大模型Agent相关知识&#xff0c;使用llama_index实现python版的Agent demo&#xff0c;根据AI解题场景知识密集型任务特点&#xff0c;需要实现一个偏RAG的Agent WorkFlow&#xff0c;辅助AI解题。 使用Java结合Langchain4j支持的RAG流程一些优化点以及自定义图结构…

基于工业互联网的智能制造:未来制造业的新引擎

随着科技的飞速发展&#xff0c;工业互联网通过提供强大的数据支撑和通信基础&#xff0c;成为智能制造的重要基石。智能制造的引入&#xff0c;不仅显著提升了制造业的生产效率、降低了成本&#xff0c;而且提高了产品质量&#xff0c;满足了市场的多样化、个性化需求。 智能制…

创建react的脚手架

Create React App 中文文档 (bootcss.com) 网址&#xff1a;creat-react-app.bootcss.com 主流的脚手架&#xff1a;creat-react-app 创建脚手架的方法&#xff1a; 方法一&#xff08;JS默认&#xff09;&#xff1a; 1. npx create-react-app my-app 2. cd my-app 3. …

(三十一)Flask之wtforms库【剖析源码下篇】

每篇前言&#xff1a; &#x1f3c6;&#x1f3c6;作者介绍&#xff1a;【孤寒者】—CSDN全栈领域优质创作者、HDZ核心组成员、华为云享专家Python全栈领域博主、CSDN原力计划作者 &#x1f525;&#x1f525;本文已收录于Flask框架从入门到实战专栏&#xff1a;《Flask框架从入…

ESP32CAM物联网教学08

ESP32CAM物联网教学08 本地网页控制小车 小智制作的物联网小车,在与云台监控摄像头的PK中,一路攻城掠地、勇往直前。突然有一天,他觉得似乎忘了最开始时的初衷,忘了一路走来的首发站:这个不就是一辆遥控车吗?我能不能就做一辆快乐的、纯粹的遥控车。 CameraWebServer转换…

相关款式1111

一、花梨木迎客松 1. 风速打单 发现只有在兄弟店铺有售卖 六月份成交订单数有62笔 2. 生意参谋 兄弟店铺商品访客数&#xff1a;3548&#xff0c;支付件数&#xff1a;95件 二. 竹节茶刷&#xff08;引流&#xff09; 1. 风速打单 六月订单数有165笔 兄弟&#xff1a;…

【技术支持】console控制台输出美化(腾讯文档)

function style(color, size 12){return display:inline-block;background-color:${color};color:#fff;padding:2px 4px;font-size:${size}px; } const dataVersion 3.0.0 const codeVersion 3.0.28657969 const branchVersion release-20240617-f98487dc //注意此处%c后面…

CDC实时同步进行时遇到不可抗力中断了怎么办?

目录 一、CDC技术的概念 二、CDC技术的应用场景 1.数据复制和同步 2.实时数据仓库 3.业务过程监控和审计 4.ETL 进程优化 三、CDC与数据管道的关系 1.区别 CDC&#xff08;Change Data Capture&#xff09; 数据管道&#xff08;Data Pipeline&#xff09; 2.联系 CDC是数据管道…

【pycharm】 Virtualenv创建venv报错

一、背景 在启动django项目时&#xff0c;需要创建venv环境&#xff0c;有时候能顺利创建成功&#xff0c;当python版本换成3.8时&#xff0c;会报错 ImportError: DLL load failed while importing _ssl: 找不到指定的模块。 二、原因和解决措施 之所以执行这个报错&#…

六西格玛绿带培训如何告别“走过场”?落地生根

近年来&#xff0c;六西格玛绿带培训已经成为了众多企业提升管理水平和员工技能的重要途径。然而&#xff0c;不少企业在实施六西格玛绿带培训时&#xff0c;往往陷入形式主义的泥潭&#xff0c;导致培训效果大打折扣。那么&#xff0c;如何避免六西格玛绿带培训变成“走过场”…

前端面试项目细节重难点(十)(已工作|做分享)

面试官&#xff1a;现场出需求&#xff1a;我想让一个左侧盒子可以进行拉伸、缩小、展示或隐藏这些功能&#xff0c;你会如何实现&#xff1f; 答&#xff1a;&#xff08;1&#xff09;分析问题&#xff1a;其实&#xff0c;我听到这个问题后&#xff1a; 我的第一种想法&am…

化学合成水热釜 加热反应釜 实验室高温高压设备

水热釜&#xff0c;也称为高压消解罐或高压釜&#xff0c;是一种能够在高温高压条件下进行化学反应的实验室设备。它广泛应用于化学、地质、材料科学、环境科学等领域&#xff0c;特别是在需要在高压环境下加速化学反应或溶解难溶物质的实验中。以下是水热釜的一些关键特性和用…

Android14之获取包名/类名/服务名(二百二十三)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

短链接学习day2

用户敏感信息脱敏展示&#xff1a; RequestParam 和 PathVariable的区别 注解是用于从request中接收请求的&#xff0c;两个都可以接收参数&#xff0c;关键点不同的是RequestParam 是从request里面拿取值&#xff0c;而 PathVariable 是从一个URI模板里面来填充。 PathVari…

3033. 修改矩阵 Easy

给你一个下标从 0 开始、大小为 m x n 的整数矩阵 matrix &#xff0c;新建一个下标从 0 开始、名为 answer 的矩阵。使 answer 与 matrix 相等&#xff0c;接着将其中每个值为 -1 的元素替换为所在列的 最大 元素。 返回矩阵 answer 。 示例 1&#xff1a; 输入&#xff1a;…

达梦数据库小技巧

达梦数据库小技巧 一&#xff1a; 时间类型TIMESTAMP使用1.1 建表1.2 插入1.3按时间戳查询&#xff0c;返回某一列不重复的值 二&#xff1a;存储过程创建和调用2.1建表2.2 创建存储过程&#xff0c;循环100插入拼接字符串2.3调用存储过程 一&#xff1a; 时间类型TIMESTAMP使用…

Word取消自动编号

设置Word更正选项 1、 点击文件——word选项——校对——自动更正选项 2、点击自动更正——键入时自动套用格式——取消”自动编号”前面的勾选——点击确定即可

第十四届蓝桥杯省赛C++B组F题【岛屿个数】题解(AC)

题目大意 给定一个 01 地图&#xff0c;分别表示陆地和海&#xff0c;问地图中一共有多少块岛屿&#xff1f;另外&#xff0c;若一个岛屿在另一个岛屿的内部&#xff0c;则不统计。如下图中的大岛屿包含着内部的小岛屿&#xff0c;故内部小岛屿不计算&#xff0c;最终输出 1。…

10种有效提高电子设备可靠性的PCB散热技术

在现代电子领域&#xff0c;随着器件尺寸的不断缩小和性能的不断提高&#xff0c;热管理问题日益凸显&#xff0c;不容忽视。电子设备在运行过程中产生的热量&#xff0c;如果处理不当&#xff0c;散发不了&#xff0c;就会像潜移默化的威胁一样&#xff0c;悄无声息地危及设备…