百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

前端 UI 框架新思考 - Himmel(前端界面设计框架)

ccwgpt 2024-09-20 13:33 34 浏览 0 评论

现代前端框架的实现原理都可以用以下公式进行概括:

UI = f(state)

其中:

  • state —— 当前的视图的状态
  • f —— 框架内部的运行机制
  • UI —— 宿主环境的视图

这个公式说明,框架内部运行机制根据当前状态渲染视图,这也能看出现代框架的两个重要特性:数据驱动和 描述 UI。

如何描述 UI 界面?

现状

现代前端 UI 框架还是沿用类 HTML 解决方案,主要理由就是“开发人员更熟悉”。但实际上,它们都已经扩展了 HTML,扩展的部分已经必不可少,实际可能远离了初衷 - “开发人员更熟悉”。

Vue 描述 UI 界面的部分代码如下:

html复制代码
<div id="app">
  <button @click="count++">
    Count is: {{ count }}
  </button>
</div>

TSX 描述 UI 界面的部分代码如下:

tsx复制代码export default function MyApp() {
  return (
    <div>
      <h1>Welcome to my app</h1>
      <MyButton onClick={{handleClick}} />
    </div>
  );
}

拥抱 Dom API

目前所有的前端 UI 框架对于描述 UI 界面的方式都是通过拓展 HTML 来实现的。因为 HTML 不支持直接运行 JS 代码,所以具体的扩展实现对开发者而言都是黑盒。同时随着框架演变,出现越来越多的魔法实现、指令和语法糖。对于开发者而言无疑增会加学习和使用成本。

通过解读框架对于描述 UI 界面的实现方法,可以发现都是通过 DOM API 来最后生成 HTML。因此,如果绕过扩展的 HTML,直接使用 DOM API 来描述 UI 界面是可行的。但 DOM API 是命令式,直接使用会产生大量样板代码,同时已经不符合当前开发者的习惯和思维。那么就需要对 DOM API 进行轻量封装,实现声明式的方法。

Himmel 描述 UI 界面的部分代码如下:

typescript复制代码function App() {
  return Div([
    Div([
      Img(himmelLogo).className("logo").attrs({ alt: "himmel Logo" }),
      Img(viteLogo).className("logo").attrs({ alt: "TypeScript Logo" }),
    ]).className("flex gap-2 justify-center"),
    H1("Himmel + TypeScript"),
    ])
}

因为不需要扩展 HTML,所有没有构建过程(当然也会损失构建中的性能优化,但这并非不可弥补),所有实现对开发者都是透明直接的。也不存在语法糖,使用 JS 便可以描述复杂且完整的 UI 界面。

如何驱动 UI 界面?

所有的前端框架都具有一套响应式机制来驱动 UI 界面。从本质而言,响应式可以认为是通过监听一系列状态,根据状态的变化来更新 UI 的过程。

React 的实现是通过订阅发布模式监听在 JSX 中通过 useState 创建的状态,然后通过 diff 算法,计算出整个 UI 界面(虚拟 dom 树)中的变化部分,然后仅更新变化的部分。存在的缺点是:

  1. JSX 内状态的订阅和 state 代码书写顺序有关(具体查阅),这非常不符合开发逻辑。
  2. 状态只能在 JSX 中被使用和更新,传递需要通过 props 或 context 等特定 API,使用成本较大。
  3. 状态变更后,需要通过 diff 算法(后面 Solid 证明 diff 算法不是必须)来知道具体变化的部分。
  4. 更新 UI 界面时,是通过 re-render 方式,需要开发者格外小心将 once-run 的代码通过各种手段避免在 re-render 时重复执行。
tsx复制代码function MyButton() {
  const [count, setCount] = useState(0); // define state

  function handleClick() {
    setCount(count + 1); // update state
  }

  return (
    <button onClick={handleClick}>
      {/* use state */}
      Clicked {count} times 
    </button>
  );
}

Vue 的实现是通过 Proxy 来监听在 Setup 方法中通过 ref 创建的状态,然后同样通过 diff 算法,计算变化部分。Vue 的实现避免 React 中 state 要注意顺序的问题,当其他缺陷是同样存在的。

typescript复制代码import { createApp, ref } from 'vue'

createApp({
  setup() {
    return {
      count: ref(0) // define state
    }
  }
}).mount('#app')
html复制代码<div id="app">
  <button @click="count++"> // update state
    Count is: {{ count }} // use state
  </button>
</div>

Solid 的实现是通过 Proxy 来监听文件通过 createSignal 方法创建的状态,然后更新状态值对应的 UI 部分,因为没有虚拟DOM,所有不存在 re-render,每次更新都是在真实的 dom 上操作。

javascript复制代码import {
        createSignal,
        onCleanup,
      } from "https://cdn.skypack.dev/solid-js";
      import { render } from "https://cdn.skypack.dev/solid-js/web";
      import html from "https://cdn.skypack.dev/solid-js/html";

      const App = () => {
        const [count, setCount] = createSignal(0), // define state
          timer = setInterval(() => setCount(count() + 1), 1000); // update state
        onCleanup(() => clearInterval(timer));
        return html`<div>${count}</div>`; // use state
        // or
        return h("div", {}, count);
      };
      render(App, document.body);

Solid 是最直观的使用响应式方式的框架,Himmel 采用了完全相同的实现,只是在 api 命名上有所区别而已。因为 Himmel 没有使用 JSX,所以无法通过构建来将状态值自动包裹进 getter 函数中。但 Himmel 使用单独的 getdispatch 两个方法来获取最新状态值和更新状态值,却同样可以减少大量定义 getter、setter 方法的代码。

typescript复制代码import { dispatch, get, signal } from "himmel/signal";

const countSignal = signal(0); // define state
const hideSignal = signal(true);

export default function App() {
  return Div(
      Button(() => `count is ${get(countSignal)}`) // use state
        .attrs({ id: "counter" })
        .onClick(() => {
          dispatch(countSignal, (old) => old + 1); // update state
        })
    )
}

总结

我们的最终目标不是编写更少的代码,而是在明确表达应用程序且提供良好维护性的前提下编写更少的代码。如果这项技术单纯强调“简单”,那可能会包含过多的魔法,而掩盖掉重要的细节,比如 Vue 的种种指令,React 的 useEffect 。但掩盖掉的细节带来的副作用最终还是会暴露在开发者面前,只是角度有所不同,开发者仍然不得不面对。

这并非劝大家直接放弃所有现成的解决方案。但对于开发人员值得思考的是,如果对那些具有严重设计缺陷的“雪花” 前端框架进行重新设计,是否有新的方式来使得实现应用程序的最终代码会更好?

但如果那些强大的前端 UI 框架还没有意识到当前实践的缺陷,反而在错误的道路上越走越远。那么有新的挑战者出现也并非坏事。

参考

GitHub - xiamu14/himmel-dev: himmel-dev is a Modern frontend framework . no build, no virtual dom, n...

Himmel + TS Demo

All your mainstream UI frameworks are lying to you

作者:夏木14 链接:https://juejin.cn/post/7347664103039336482

相关推荐

用Deepseek扩写土木工程毕业论文实操指南

用Deepseek扩写毕业论文实操指南一、前期准备整理现有论文初稿/提纲列清楚论文核心框架(背景、现状、意义、方法、数据、结论等)梳理好关键文献,明确核心技术路线二、Deepseek扩写核心思路...

985学霸亲授,DeepSeek也能绘6大科研图表,5分钟就出图

在实验数据处理中,高效可视化是每个科研人的必修课。传统绘图软件操作复杂、耗时费力,而智能工具DeepSeek的出现彻底改变了这一现状。本文将详解如何用DeepSeek一键生成六大科研常用图表,从思维导...

AI写论文刷屏?大学生正在丢掉的思考力

一、宿舍深夜:当论文变成"Ctrl+C+V"凌晨两点的大学宿舍,小王对着电脑屏幕叹气。本该三天前开始写的近代史论文,此刻还一片空白。他熟练打开某AI写作网站,输入"论五四运动的...

Grok在辅助论文写作上能不能既“聪明”又“可怕”?!

AcademicIdeas-学境思源AI初稿写作随着人工智能技术的飞速发展,论文写作这一学术任务正迎来新的助力。2025年2月18日,美国xAI公司推出了备受瞩目的Grok3模型,其创始人埃隆·...

大四论文沟通场景!音频转文字难题听脑AI来化解

大四学生都知道,写论文时和导师沟通修改意见,简直是“过关斩将”。电话、语音沟通完,想把导师说的修改方向、重点要求记下来,麻烦事儿可不少。手写记不全,用普通录音转文字工具,转完还得自己慢慢找重点,稍不注...

论文写作 | 技术路线图怎么画?(提供经典优秀模板参考)

技术路线图是一种图表或文字说明,用于描述研究目标、方法和实施计划。它展示了研究的整体框架和步骤,有助于读者理解研究的逻辑和进展。在课题及论文中,技术路线图是常见的一部分,甚至是一个类似心脏一样的中枢器...

25年信息系统项目管理师考试第2批论文题目写作建议思路框架

25年信息系统项目管理师考试第2批论文题目写作建议思路框架--马军老师

微信购物应尽快纳入法律框架(微信购物管辖)

符向军近日,甘肃省工商行政管理局发布《2016年上半年信息分析报告》。报告显示,微信网购纠纷迅猛增长,网络购物投诉呈上升趋势。投诉的主要问题有出售的商品质量不过关、消费者通过微信付款后对方不发货、购买...

泛珠三角区域网络媒体与腾讯微信签署《战略合作框架协议》

新海南客户端、南海网7月14日消息(记者任桐)7月14日上午,参加第四届泛珠三角区域合作网络媒体论坛的区域网络媒体负责人及嘉宾一行到腾讯微信总部座谈交流,并签署《战略合作框架协议》(以下简称《框架协...

离线使用、植入微信-看乐心Mambo手环如何打破框架

从2014年开始智能手环就成功进入人们的生活,至今已经演变出数据监测、信息推送、心率监测等诸多五花八门的功能,人们选择智能手环并不指望其能够改变身体健康情况,更多的是通过数据来正视自身运动情况和身体健...

微信私域电商运营策略与框架(微信私域怎么做)

...

华专网络:如何零基础制作一个网站出来?

#如何零基础制作一个网站出来?#你是不是觉得网站建设很复杂,觉得自己是小白,需求不明确、流程搞不懂、怕被外包公司坑……这些问题我都懂!今天华专网络就用大白话给你捋清楚建站的全流程,让你轻松get网站制...

WAIC2024丨明日上午9点,不见不散!共同探讨智能社会与全球治理框架

大咖云集,硕果闪耀WAIC2024世界人工智能大会智能社会论坛将于7月5日9:00-12:00与你相约直播间WAIC2024上海杨浦同济大学哔哩哔哩多平台同步直播探讨智能社会与全球治理框架WAIC...

约基奇:森林狼换来戈贝尔时大家都在嘲笑 他们的阵容框架很不错

直播吧5月4日讯西部季后赛半决赛,掘金将迎战森林狼,约基奇赛前接受采访。约基奇说道:“当蒂姆-康纳利(森林狼总经理、前掘金总经理&曾选中约基奇)做了那笔交易(换来戈贝尔)时,每个人都在嘲笑他...

视频号带货为什么一个流量都没有?顶级分析框架送给你

视频号带货为什么一个流量都没有?遇到问题,一定是步步来分析内容,视频号带货一个流量都没有,用另外一个意思来讲,就可以说是零播放。为什么视频号带货一个流量都没有?跟你说再多,都不如来个分析框架。1、是否...

取消回复欢迎 发表评论: