这篇笔记整理数据驱动 UI 的基础概念:vanilla、数据驱动界面、数据与界面分离、React 状态。
什么是 Vanilla
Vanilla 本义”香草”,软件行业借指”原味的、没有额外包装的版本”。Vanilla 前端即:不依赖 React、Vue 这类框架,只用浏览器原生支持的 HTML、CSS、JavaScript 构建页面。
边界不必较真——“用了第三方库还算不算 vanilla”没有定论,理解为”没有使用前端框架的写法”即可。
数据驱动界面
核心定义:
界面长什么样,不写死在组件里,而是照着”喂进去的值”来显示。值变了,显示就变。
两个例子(示意):
// PageHeading 只负责排版,标题文字由外部传入
<PageHeading title="关于我" /> // 个人主页
<PageHeading title="文字实验室" /> // 文字实验室页
App 的页面切换同理:用户点导航栏,“当前页面”这个值变成 "home" 或 "textlab",App 据此决定渲染 HomePage 还是 TextLabPage。区别只在值的来路——前者由外部传入,后者由组件自己持有。
数据与界面分离
问题:文案直接写在组件 JSX 里,改一句”关于我”就得打开组件代码、在一堆标签中间找。而项目建成后数据的变化频率远高于界面结构。
做法:把要显示的内容集中到独立的数据文件:
// src/data/site.js
export const home = {
heroTitle: "关于我",
heroSubtitle: "项目,创意,灵感,心得,我的作品",
featuredWork: {
kicker: "作品",
title: "文字实验室",
copy: "拼音和情绪,挖掘中文里的细节",
linkLabel: "打开作品",
},
identity: {
motto: "已识乾坤大,尤怜草木青",
learning: "零到全栈",
},
};
export const textLab = {
heroTitle: "文字实验室",
heroSubtitle: "拼音和情绪,挖掘中文里的细节",
};这基本是一张纯内容清单——网站上要显示的字都在这儿。它和 JSON 很像,区别在于对象最后一个成员的结尾允许带逗号。
组件不再写死任何文案,只负责到清单里取值显示(示意):
// HomePage.jsx
import { home } from "../data/site";
<h1>{home.heroTitle}</h1>;
职责划分:
| 只管什么 | |
|---|---|
| 组件 | ”怎么显示”——排版、样式、结构 |
site.js | ”显示什么内容” |
收益:
- 改文案只动
site.js,组件一行不改; - 多语言几乎免费:再备一份英文清单,组件按当前语言读对应那张表即可,排版、结构、样式全部复用;
- 将来引入后端 API,只需把数据来源换成接口返回,组件依然不需要改动。
验证方式:改 site.js 里任意字段并保存,页面当场更新,组件文件一个字没动。
状态驱动 UI
前面例子里的值有两个局限:从外面喂进来(哪怕集中进了 site.js,也是父组件读了再传下去);本身定死,不主动改就不会变。
有些数据需要在用户操作过程中自己变。这种会变、且一变显示就跟的值,在 React 里称为组件的状态(state):
- 由组件自己持有、自己管理,不从外部传入(区别于 props);
- 有初始默认值;
- 界面显示什么,完全照着这个值;
- 允许被修改,且一改,界面当场跟着变。
典型例子:输入框下方实时显示”已输入 N 字”。输入框内容是一个 state——打字就是在改这个值,字数照着它计算,值一改数字立刻刷新。
实现原理可以先不深究:React 内部负责盯着这个值,值一变就自动刷新界面。需要认出的只有现象:state 一变,界面自动跟变。
前文的导航切换就是一例:App 里”现在在哪一页”就是一个 state。
小结
- vanilla = 不依赖框架、只用浏览器原生能力的写法;
- 数据驱动界面:界面照着”值”来显示,值变则显示变;
- 数据与界面分离:内容集中进独立数据文件,组件管”怎么显示”、数据表管”显示什么”,多语言这类需求因此近乎免费;
- 状态驱动 UI:state 是组件自己持有的可变数据,一变界面就跟,是 React 响应式更新的核心机制。
마음에 드신다면, 댓글을 남겨주세요~