it编程 > 前端脚本 > 其它脚本

Renderless 思想正在影响前端开发

149人参与 2024-08-04 其它脚本

前言

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

多元化的需求场景,对前端工程师的要求也是越来越高,他们必须掌握 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 层特性层实现。

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

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

无渲染组件 vs 公共函数

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

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

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

无渲染组件库

目前,采用无渲染组件思想设计的优秀组件库有 tinyvue[2],它目标兼容 vue、vue3、react、angular、solid 等框架,覆盖 pc 端和 mobile 端。

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

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

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

最后

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

参考资料

参考资料

[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
欢迎进入代码仓库 startinyengine、tinyvue、tinyng、tinycli~ 如果你也想要共建,可以进入代码仓库,找到 good first issue标签,一起参与开源贡献~

(0)
打赏 微信扫一扫 微信扫一扫

您想发表意见!!点此发布评论

推荐阅读

当前端谈数据时,我们在谈些什么

08-04

10个 JavaScript One-Liners 让初学者看起来很专业

08-04

Echarts + 低代码 :可视化如何赋能企业的创新之路?

08-04

TinyVue:与 Vue 交往八年的组件库

08-04

基于 Three.js 的 3D 模型加载优化

08-04

星河璀璨,uni-app 亮相华为 HDC2024 开发者大会

08-04

猜你喜欢

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论