作者:袁首京
原創文章,轉載時請保留此宣告,并給出原文連接,
作為當下的開發人員,無論是不是前端,可能都會頻繁的與 React、Vue、Svelte、Solidjs 等等打交道,也許你已經很清楚它們背后的運作原理,那不必往下看了,如果還不是很清楚,那咱們可以一起寫幾行代碼,來瞅一眼這些回應式框架背后的思路,
回應式框架最根本的功能其實只有一條:當資料發生變化時,讓界面隨之發生變化,
如何達成這一點呢?粗略的想一下就會覺得,首先要在資料和與之對應的 HTML 元素之間建立系結關系,可以以某種方式給特定的 HTML 元素打個標記,然后當與此元素相關的值發生變更時,我們就能通過這個標記找到此元素,然后動態的改變它展示出來的值,
比如如下 HTML 模板片斷:
<p>{{ current_time }}</p>
我們可以定義一個模板編譯函式:
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('<p>{{current_time}}</p>')
<p vid="current_time"></p>
這樣如果需要,我們就可以很方便的找到頁面上需要回應的元素:
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 = https://www.cnblogs.com/rockety/archive/2023/05/03/reactive({
current_time:"2023-05-03T05:14:46.176Z",
});
setInterval(() => {
data.current_time = new Date().toISOString();
}, 1000);
最終效果如下:

以下是完整代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div id="root"></div>
<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: "<p>{{ current_time }}</p>",
data: {
current_time: "2023-05-03T05:14:46.176Z",
},
mount() {
const rootEl = document.querySelector("#root");
rootEl.innerHTML = compile(this.tpl);
this.data = https://www.cnblogs.com/rockety/archive/2023/05/03/reactive(this.data);
this.mounted();
},
mounted() {
setInterval(() => {
this.data.current_time = new Date().toISOString();
}, 1000);
},
};
document.addEventListener("DOMContentLoaded", () => {
app.mount();
});
</script>
</body>
</html>
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/551572.html
標籤:其他
上一篇:寫幾行代碼,了解回應式原理
下一篇:返回列表
