每個(gè)前端同學(xué)都可以擁有自己的框架,然后去完善它—Strvejs@3.1.0正式發(fā)布
不忘初心
從 Strve.js 正式發(fā)布到現(xiàn)在已經(jīng)將近半年了,收到很多建議,也收到很多贊揚(yáng),謝謝大家!平時(shí)抽空的時(shí)候,我也在不斷地完善這個(gè)框架,希望可以更加的健壯。
我提到很多次,大家也經(jīng)常問(wèn)我。為什么要開(kāi)發(fā)這個(gè)框架?你的初衷是什么?其實(shí),我的動(dòng)機(jī)特別簡(jiǎn)單,完全受 JSX 語(yǔ)法的影響。剛接觸 JSX 語(yǔ)法的時(shí)候,就被它那種魔法深深地吸引住了,可以在 JS 中寫(xiě) HTML。所以,我就想我自己可不可以也搞一個(gè)類似 JSX 語(yǔ)法的庫(kù)或者框架呢!一方面可以鍛煉自己的代碼能力,另一方面體驗(yàn)開(kāi)發(fā)框架的整個(gè)流程,也方便我以后更全面的學(xué)習(xí)其他框架(Vue.js、React.js 等)。
我剛開(kāi)始開(kāi)發(fā) Strve.js 時(shí),借鑒了一個(gè)迷你 JSX 的庫(kù),但是做著做著就覺(jué)得做不下去了。感覺(jué)還是偏離了方向,我決定用簡(jiǎn)單的方式去實(shí)現(xiàn)我所想要的效果。
在 JS 中可以寫(xiě) HTML,除了借助 Babel 來(lái)轉(zhuǎn)譯 JSX 語(yǔ)法外,還有一種就是利用 ES6 語(yǔ)法中 的模板字符串。利用模板字符串可以做到直接渲染到頁(yè)面中,如果是改變數(shù)據(jù)的話,也能實(shí)現(xiàn)。但是問(wèn)題是,它并不那么靈活,并且需要操作大量 DOM 節(jié)點(diǎn)。
減少操作真實(shí) Dom 帶來(lái)的性能代價(jià),目前合理的方案是利用虛擬 Dom,將 HTML 標(biāo)簽對(duì)象化,轉(zhuǎn)化成一個(gè) JS 對(duì)象。最后利用 Diff 算法進(jìn)行新舊 Dom 對(duì)比,來(lái)更新差異。雖然這樣也會(huì)操作真實(shí) Dom,但是比起之前的量級(jí)少了太多。
虛擬 Dom 的量級(jí)也得控制一定范圍,不然計(jì)算量太大,頁(yè)面也會(huì)卡頓。Vue2 相比于 Vue1 引入了虛擬 Dom,組件內(nèi)利用虛擬 Dom 來(lái)進(jìn)行更新數(shù)據(jù),把虛擬 Dom 的量級(jí)控制在組件級(jí)別;而 React.js 則引入 Fiber 架構(gòu),借鑒了操作系統(tǒng)時(shí)間分片的概念,利用空閑時(shí)間計(jì)算 Diff。所以,針對(duì)于 Strve.js,如果引入虛擬 Dom 的話,虛擬 Dom 的量級(jí)必須在考慮范圍之內(nèi)。
Strve.js@3.x之前的版本都沒(méi)有解決虛擬 Dom 量級(jí)的問(wèn)題,都是全量的對(duì)比。另外,如果想操作 Dom,必須要為其創(chuàng)建一個(gè) Dom 對(duì)象,綁定到虛擬 Dom 上,這樣才能調(diào)用 Dom API,之前的版本都是為每一個(gè) Dom 節(jié)點(diǎn)都創(chuàng)建一個(gè) Dom 對(duì)象,一些靜態(tài)節(jié)點(diǎn)沒(méi)有必要,還有它也不會(huì)進(jìn)行 Diff 算法。
Strve.js@3.1.0是 3.x 正式版本中第一個(gè)版本,也是之前 2.x 版本之后的第一次重大升級(jí)。算是給自己在 2022 年第一個(gè)禮物吧!之前聽(tīng)過(guò)尤大的一次分享,他說(shuō):“做開(kāi)源從 90%到 100%這個(gè)過(guò)程中,是特別難的”。是的,這次我親身體會(huì)到了。Strve.js 我會(huì)繼續(xù)維護(hù)下去,但是我不會(huì)逼自己去一定要做成什么樣,保持一顆初心就夠了。
Strve.js@3.1.0升級(jí)了什么
這次大方面一方面是修改了 API,更簡(jiǎn)短也容易記,減輕了心智負(fù)擔(dān);另一方面是上面提到了 Diff 算法的優(yōu)化。
以下是更新日志:
- 修改 API:
- 調(diào)整createAppAPI;
- useFkey標(biāo)記改為useFirstKey;
- 添加標(biāo)記$key、$name;
- 加入組件標(biāo)簽、空節(jié)點(diǎn)標(biāo)簽;
- 調(diào)整setDataAPI;
- 優(yōu)化 Diff 算法;
- TypeScript 重構(gòu)代碼;
官方文檔又更新了
此次對(duì)文檔內(nèi)容進(jìn)行了大的改動(dòng),主要是對(duì)使用項(xiàng)。
除了對(duì)文檔中內(nèi)容的改寫(xiě),還加入了實(shí)時(shí)代碼的功能,你可以在線編輯代碼,看到自己想看到的效果。
Strve Router 也更新了
Strve Router 這次更新也算是大版本升級(jí),升級(jí)到 2.1.0,可以通過(guò)下面這個(gè)示例簡(jiǎn)單了解下 Strve Router。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>strve-router</title>
</head>
<body>
<div id="app"></div>
<script type="module">
import {
h,
createApp,
setData,
} from 'https://cdn.jsdelivr.net/npm/strvejs@3.1.0/dist/strve.esm.min.js';
import {
initRouter,
linkTo,
} from 'https://cdn.jsdelivr.net/npm/strve-router@2.1.0/dist/strve-router.esm.js';
class Home {
constructor() {
this.state = {
count: 0,
};
}
useAdd = () => {
setData(() => {
this.state.count++;
});
};
goAbout = () => {
linkTo('/about');
};
render = () => {
return h`
<button onClick=${this.goAbout}>goAbout</button>
<h1 onClick=${this.useAdd} $key>${this.state.count}</h1>
`;
};
}
class About {
constructor() {
this.state = {
msg: 'About',
};
}
render = () => {
return h`
<button onClick=${this.goHome}>goHome</button>
<h1 onClick=${this.useChange} $key>${this.state.msg}</h1>
`;
};
useChange = () => {
setData(() => {
this.state.msg = 'Changed';
});
};
goHome = () => {
linkTo('/');
};
}
const router = initRouter(
[
{
path: '/',
template: [Home, 'render'],
},
{
path: '/about',
template: [About, 'render'],
},
],
setData
);
function App() {
return h`
<div class="main">
${router.view()}
</div>
`;
}
const app = createApp(App);
app.mount('#app');
</script>
</body>
</html>
其他詳情更新
還有很多更新,詳情內(nèi)容可以訪問(wèn)下面官方文檔地址:
https://maomincoding.gitee.io/strvejs-doc/zh/。