写几行代码,了解响应式原理-环球新资讯
发稿时间:2023-05-03 17:11:32 来源: 博客园
作者:袁首京
原创文章,转载时请保留此声明,并给出原文连接。
【资料图】
作为当下的开发人员,无论是不是前端,可能都会频繁的与 React、Vue、Svelte、Solidjs 等等打交道。也许你已经很清楚它们背后的运作原理,那不必往下看了。如果还不是很清楚,那咱们可以一起写几行代码,来瞅一眼这些响应式框架背后的思路。
响应式框架最根本的功能其实只有一条:当数据发生变化时,让界面随之发生变化。
如何达成这一点呢?粗略的想一下就会觉得,首先要在数据和与之对应的 HTML 元素之间建立绑定关系。可以以某种方式给特定的 HTML 元素打个标记,然后当与此元素相关的值发生变更时,我们就能通过这个标记找到此元素,然后动态的改变它展示出来的值。
比如如下 HTML 模板片断:
{{ current_time }}
我们可以定义一个模板编译函数:
function compile(tpl) { const re = /(\{\{\s+)(\w+)(\s+\}\})/m; const mg = tpl.match(re); return tpl.replace(">{{", " vid="" + mg[2] + "">{{").replace(mg[0], "");}
执行该函数,就会给相关元素打上 vid 标记:
> compile("{{current_time}}
")
这样如果需要,我们就可以很方便的找到页面上需要响应的元素:
const vel = document.querySelector("[vid=current_time]");
接下来是数据部分。如何监测数据的变化呢?一种方案是使用代理。假如我们有如下数据对象:
{ current_time: "2023-05-03T05:14:46.176Z";}
可以使用如下函数,为其生成一个代理,拦截其赋值操作:
function reactive(data) { return new Proxy(data, { set(target, property, value) { const prev = target[property]; target[property] = value; if (prev !== value) { const vel = document.querySelector(`[vid=${property}]`); vel.innerHTML = value; } return true; }, });}
接下来,就可以面向数据编程了:
const data = reactive({ current_time: "2023-05-03T05:14:46.176Z",});setInterval(() => { data.current_time = new Date().toISOString();}, 1000);
最终效果如下:
以下是完整代码:
Document <script> function compile(tpl) { const re = /(\{\{\s+)(\w+)(\s+\}\})/m; const mg = tpl.match(re); return tpl.replace(">{{", " vid="" + mg[2] + "">{{").replace(mg[0], ""); } function reactive(data) { return new Proxy(data, { set(target, property, value) { const prev = target[property]; target[property] = value; if (prev !== value) { const vel = document.querySelector(`[vid=${property}]`); vel.innerHTML = value; } return true; }, }); } const app = { tpl: "{{ current_time }}
", data: { current_time: "2023-05-03T05:14:46.176Z", }, mount() { const rootEl = document.querySelector("#root"); rootEl.innerHTML = compile(this.tpl); this.data = reactive(this.data); this.mounted(); }, mounted() { setInterval(() => { this.data.current_time = new Date().toISOString(); }, 1000); }, }; document.addEventListener("DOMContentLoaded", () => { app.mount(); }); </script>
- 写几行代码,了解响应式原理-环球新资讯
- 隆扬电子:拟发行可转债募资11亿元 投建复合铜箔生产基地
- 深交所:深市公司的内生增长动力将进一步释放
- 欧洲经济增长疲弱 面临下行风险
- 山东省成立聊城鲁西化工“5·1”爆炸着火事故调查组
- 【全球热闻】4月英国平均房价单月上涨0.5%!英王加冕礼细节大曝光
- 泽连斯基:糟糕!我通过新闻才得知泄密消息
- 当前看点!岁日送王十三判官之松州幕
- 五一热经济 | 成都潮玩运动消费受青睐 多元化产业形态扮靓假日经济-热议
- 当前热议!108平现代三居室敞亮大方,眺望远方美丽的风景开启一整天的美好
- 丽尚国潮最新公告:控股股东拟增持公司0.5%至1%股份
- 泰安医学学校怎么样院是个什档次的山东院是几本 全球百事通
- 泛海控股提示风险:股票收盘价已连续11个交易日低于1元|世界微速讯
- 富瀚微:筹划收购眸芯科技49%股权 明日停牌
- 天天即时:佩蒂股份:拟5000万元至7000万元回购
- 鲁西化工:子公司双氧水装置发生爆炸着火事故
- 对话未来丨营销传播的本质没有变 借助AIGC能产生“一分钱做出五分钱”的效果
- 当前观点:鸡肝的做法大全_爆炒鸡肝怎么做
- 四川宜宾接连发生4.0级4.5级地震详细内容 每日热门
- 天天热文:全球“街”力丨北美民众如何看中国?这些回答亮了
- 共青团中央:截至2022年底全国共有共青团员7358.3万名
- 今年全国电力供需将呈紧平衡态势|世界讯息
- 热文:凯尔特人VS76人G2前瞻:大帝出战成疑,哈登继续PK獭兔布朗
- 《保卫萝卜4》绿野奇缘第十四关怎么过
- 国产新车品鉴:本田2020款缤智正式上市 售价12.78-17.68万元
- 2013山东高考英语听力_2013山东高考英语|环球报资讯
- 最新!两女子插队被制止后当场发飙!景区回应:平移换队仍算插队 焦点热讯
- 欧盟禁止乌克兰向五国出口部分粮食 最新资讯
- 鲜银耳有毒吗能吃吗(新鲜的银耳有毒吗)
- 全球视点!罚球出手数:施罗德10次,戴维斯8次,勇士全队6次
延伸阅读
创业