成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

我是如何開發(fā)了一個(gè)前端庫(kù) or 框架?

開發(fā) 前端
那么框架與庫(kù)有什么區(qū)別呢?庫(kù)更多是一個(gè)封裝好的特定的集合,提供給開發(fā)者使用,而且是特定于某一方面的集合(方法和函數(shù)),庫(kù)沒有控制權(quán),控制權(quán)在使用者手中,在庫(kù)中查詢需要的功能在自己的應(yīng)用中使用,我們可以從封裝的角度理解庫(kù);框架顧名思義就是一套架構(gòu),會(huì)基于自身的特點(diǎn)向用戶提供一套相當(dāng)于叫完整的解決方案,而且控制權(quán)的在框架本身,使用者要找框架所規(guī)定的某種規(guī)范進(jìn)行開發(fā)。

前言

前端發(fā)展速度已經(jīng)遠(yuǎn)遠(yuǎn)超出了我們的預(yù)計(jì)范圍,前端基于 JS 的框架/庫(kù)更是層出不窮。

那么框架與庫(kù)有什么區(qū)別呢?庫(kù)更多是一個(gè)封裝好的特定的集合,提供給開發(fā)者使用,而且是特定于某一方面的集合(方法和函數(shù)),庫(kù)沒有控制權(quán),控制權(quán)在使用者手中,在庫(kù)中查詢需要的功能在自己的應(yīng)用中使用,我們可以從封裝的角度理解庫(kù);框架顧名思義就是一套架構(gòu),會(huì)基于自身的特點(diǎn)向用戶提供一套相當(dāng)于叫完整的解決方案,而且控制權(quán)的在框架本身,使用者要找框架所規(guī)定的某種規(guī)范進(jìn)行開發(fā)。

我們嘗試舉個(gè)例子:你想烹飪一條魚,這時(shí)你需要一些原料,比如油、鹽、醋、蔥、香料以及烹飪工具等,同時(shí)魚也是你需要的主要材料,當(dāng)你聚齊所有材料時(shí),再經(jīng)過烹飪就得到成品;現(xiàn)在我們進(jìn)行對(duì)比,其中油、鹽、醋、蔥、香料以及烹飪工具和魚其實(shí)就是庫(kù),組合到一起就成了框架,成品就是最終開發(fā)好的應(yīng)用,或者這樣能是你更好里的理解框架與庫(kù)之間的區(qū)別。

我們熟知的 React,它就是一個(gè)庫(kù),官網(wǎng)稱是一個(gè)用于構(gòu)建用戶界面的 JavaScript 庫(kù)。剛接觸 React 的時(shí)候,在 JS 文件 中寫 HTML 語法 覺得很奇妙,后來就覺得自己可不可以也搞一個(gè)庫(kù)來鍛煉下自己的能力呢!于是在業(yè)余時(shí)間自己通過各種摸索搞了一個(gè)迷你版 JSX,但是在數(shù)據(jù)驅(qū)動(dòng)層面上遇到了一些問題,幾天的輾轉(zhuǎn)反側(cè),自己終于想明白了。我為什么先要做一個(gè)仿 React 的庫(kù)呢?我能不能換一種方式來實(shí)現(xiàn)這種類 JSX 語法呢!我們知道 ES6 語法中有模板字符串,你可以在里面寫 HTML 標(biāo)簽,并且在字符串中可以嵌入變量。找到了開發(fā)方向,我就開始搜索各種資料,正式進(jìn)入開發(fā)庫(kù)的過程。這個(gè)過程是非常痛苦的,但慶幸的是庫(kù)的開發(fā)都是我一個(gè)人參與的,我可以按照我的想法去做,去完善它。

我將這個(gè)庫(kù)命名為 Strve.js,為什么會(huì)這樣命名呢?它其實(shí)是字符串(String)與 視圖(View)的名稱縮寫拼接而成。它實(shí)現(xiàn)了在 JS 字符串中寫 HTML 標(biāo)簽,并且可以嵌入變量,達(dá)到了數(shù)據(jù)驅(qū)動(dòng)視圖的效果。并且你可以靈活地分離代碼塊,提高工作效率。到這里你會(huì)覺得這有什么難的,使用 innerHTML 也可以實(shí)現(xiàn)類似的效果。效果是一樣的,但是在一定場(chǎng)景下 DOM 性能是不同的。Strve.js 另一個(gè)定位就是一個(gè)輕量級(jí)的 MVVM 框架,你只需要關(guān)心數(shù)據(jù)操作,其他事情由 Strve.js 內(nèi)部的 Virtual DOM 來處理,這也是目前優(yōu)化 DOM 性能的一種常用手段。

最終,功夫不負(fù)有心人。在 2021 年 11 月 3 日發(fā)布了第一個(gè)版本 1.0.4,然后接下來就是不斷地更新迭代,讓它的生態(tài)更加完善,更加符合一個(gè)庫(kù)或者框架的要求。中途也遇到過架構(gòu)重新搭建等等情況,到目前為止,Strve.js 最新版本是 5.1.1,發(fā)布時(shí)間為 2023 年 1 月 1 日。

下面我來詳細(xì)介紹下 Strve.js。

文檔

Strve.js 文檔是基于 VitePress 搭建,分別部署到 Github 和 Gitee 上。

Github 中文網(wǎng)址:https://maomincoding.github.io/strve-doc/zh

Gitee 中文網(wǎng)址:https://maomincoding.gitee.io/strve-doc/zh

圖片

下面,將根據(jù)文檔內(nèi)容分成幾大模塊,分享我設(shè)計(jì)這個(gè)庫(kù)時(shí)的心得體會(huì)。

開始

首先,我們進(jìn)入開始頁。嘗試學(xué)習(xí)一樣新的技術(shù),最簡(jiǎn)單的就是做一個(gè)小的案例。通過這些簡(jiǎn)單的案例來進(jìn)一步學(xué)習(xí)它的用法,因?yàn)橥@些最簡(jiǎn)單之處最能體現(xiàn)出它的核心用途。

你可以通過兩種方式去使用它,一種是 ES Modules,另一種是UMD。我們先分別列舉兩種方式,然后統(tǒng)一講一下代碼結(jié)構(gòu)。

現(xiàn)代瀏覽器大多都已原生支持 ES 模塊。因此我們可以像這樣通過 CDN 以及原生 ES 模塊使用 Strve.js:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Strve.js</title>
</head>

<body>
<script type="module">
import {
h,
setData,
createApp,
} from 'https://cdn.jsdelivr.net/npm/strve-js@5.1.1/dist/strve.full-esm.js';

const state = {
count: 0,
};

function add() {
setData(() => {
state.count++;
});
}

function App() {
return h`
<h1 $key>${state.count}</h1>
<button notallow=${add}>Add</button>
`;
}

const app = createApp(App);
app.mount('#app');
</script>
</body>
</html>

UMD 叫做通用模塊定義規(guī)范(Universal Module Definition)。也是隨著大前端的趨勢(shì)所誕生,它可以通過運(yùn)行時(shí)或者編譯時(shí)讓同一個(gè)代碼模塊在使用 CommonJs、CMD 甚至是 AMD 的項(xiàng)目中運(yùn)行。未來同一個(gè) JavaScript 包運(yùn)行在瀏覽器端、服務(wù)區(qū)端甚至是 APP 端都只需要遵守同一個(gè)寫法就行了。

你也可以選擇使用 <script> 標(biāo)簽直接引入,這樣就可以直接在瀏覽器中打開了。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Strve.js</title>
</head>

<body>
<script src="https://cdn.jsdelivr.net/npm/strve-js@5.1.1/dist/strve.full.prod.js"></script>
<script>
const { h, setData, createApp } = Strve;
const state = {
count: 0,
};

function add() {
setData(() => {
state.count++;
});
}

function App() {
return h`
<h1 $key>${state.count}</h1>
<button notallow=${add}>Add</button>
`;
}

const app = createApp(App);
app.mount('#app');
</script>
</body>
</html>

兩種不同的方式其中相同的代碼無非是這幾行,通過數(shù)據(jù)與視圖頁面的綁定,操作業(yè)務(wù)邏輯,你會(huì)發(fā)現(xiàn)Strve.js更加關(guān)注結(jié)果,至于如何實(shí)現(xiàn)這個(gè)結(jié)果的,我們并不關(guān)心。換句話說,Strve.js幫我們封裝了過程。

const state = {
count: 0,
};

function add() {
setData(() => {
state.count++;
});
}

function App() {
return h`
<h1 $key>${state.count}</h1>
<button notallow=${add}>Add</button>
`;
}

const app = createApp(App);
app.mount('#app');

通過上面的案例你會(huì)發(fā)現(xiàn)一切代碼邏輯都是在JS中,可以說離 All in JS 更近了一步。

安裝

我們簡(jiǎn)單快速地了解 Strve.js 的使用,那么我們?cè)谶@一篇詳細(xì)說明下 Strve.js 有哪些安裝方法。

CDN

使用CDN在上面也提到了,一種是ES Modules,另一種是UMD。因?yàn)槠脑颍@里就不再?gòu)?fù)述了。

包管理器

當(dāng)你構(gòu)建大型應(yīng)用時(shí),推薦使用 包管理器 安裝。

> npm install strve-js
> yarn add strve-js

命令行工具

當(dāng)你構(gòu)建大型應(yīng)用時(shí),推薦使用 Strve.js 提供的官方項(xiàng)目腳手架來搭建項(xiàng)目。為單頁面應(yīng)用 (SPA) 快速搭建繁雜的腳手架。它為現(xiàn)代前端工作流提供了開箱即用的構(gòu)建設(shè)置。

目前有兩款工具:

  • CreateStrveApp
  • CreateStrve

下面會(huì)再詳細(xì)介紹。

對(duì)不同構(gòu)建版本的解釋

在 NPM 包的 dist/ 目錄你將會(huì)找到很多不同的 Strve.js 構(gòu)建版本。這里列出了它們之間的差別:


ES Module (基于構(gòu)建工具使用)

ES Module (直接用于瀏覽器)

UMD

完整版

-

strve.full-esm.js

strve.full.js

完整版(生產(chǎn)環(huán)境)

-

strve.full-esm.prod.js

strve.full.prod.js

運(yùn)行時(shí)版

strve.runtime-esm.js

-

-

運(yùn)行時(shí)版(生產(chǎn)環(huán)境)

strve.runtime-esm.prod.js

-

-

不同的版本:

  • 完整版本:包括編譯器(用于將模板字符串編譯為 JavaScript 呈現(xiàn)函數(shù)的代碼)和運(yùn)行時(shí)版本;
  • 運(yùn)行時(shí)版:用于創(chuàng)建實(shí)例、渲染和處理虛擬 DOM 的代碼。基本上,它是從編譯器中刪除所有其他內(nèi)容;

在Strve.js@5.1.1發(fā)布之前,用戶可以提供 HTML 字符串,我們將其編譯為數(shù)據(jù)對(duì)象后再交給運(yùn)行時(shí)處理。準(zhǔn)確地說,上面的代碼其實(shí)是運(yùn)行時(shí)編譯,意思是代碼運(yùn)行的時(shí)候才開始編譯,而這會(huì)產(chǎn)生一定的性能開銷,因此我們也可以在構(gòu)建的時(shí)候就執(zhí)行編譯程序?qū)⒂脩籼峁┑膬?nèi)容編譯好,等到運(yùn)行時(shí)就無須編譯了,這對(duì)性能是非常友好的。 這也是為什么我們發(fā)布了不同的構(gòu)建版本,以適用于不同場(chǎng)景。

API

API目前總共有10個(gè)。

createApp、h、setData這三個(gè)為基本API,主要用于渲染頁面;onMounted、onUnmounted這兩個(gè)API為生命周期鉤子函數(shù);nextTick、domInfo這兩個(gè)API則為與DOM相關(guān)的API;version則為輔助API,用于獲取Strve.js版本號(hào);propsData、defineCustomElement則為特性API,為適配一些特性而設(shè)計(jì)。

其中,值得一提的是defineCustomElement。這個(gè)API用于支持 Web Components 的引入,它可以傳兩個(gè)參數(shù)。

第一個(gè)參數(shù)是對(duì)象類型,對(duì)象屬性如下:

屬性

類型

必選

含義

id

??String??

原生自定義組件ID,應(yīng)保持其唯一性

template

??Function??

返回一個(gè)模版字符串函數(shù)

styles

??Array<string>??

原生自定義組件樣式集合

attributeChanged

??Array<string>??

原生自定義組件監(jiān)聽屬性集合

immediateProps

??Boolean??

原生自定義組件是否開啟立即監(jiān)聽屬性變化

lifetimes

??Object??

原生自定義組件生命周期,與Web Components生命周期一致

第二個(gè)參數(shù)是字符串類型,原生自定義組件的名稱,名稱中必須含有-字段。

示例1:

const data = {
count1: 1
}

const myCom1 = {
id: "myCom1",
template: () => {
return h`
<p class="msg" $key>${data.count1}</p>
`
},
styles: [`.msg { color: red; }`],
}

defineCustomElement(myCom1, 'my-com1')

function App() {
return h`
<my-com1></my-com1>
`
}

示例2:

const myCom1 = {
id: "myCom1",
template: (props) => {
return h`
<p class="msg" $key>${props.value}</p>
<p class="msg" $key>${props.msg}</p>
`
},
styles: [`.msg { color: red; }`],
attributeChanged: ['value', 'msg'],
immediateProps: true,
lifetimes: {
attributeChangedCallback(v) {
console.log(v);
}
}
}

defineCustomElement(myCom1, 'my-com1');

const data = {
count1: 1,
count2: '1',
}

function add() {
setData(() => {
data.count1++;
})
}

function App() {
return h`
<button @click="${add}">btn</button>
<my-com1 value=${data.count1} msg="${data.count2}" $key></my-com1>
`
}

下面,我發(fā)布了一個(gè)Web Components的案例。

預(yù)覽鏈接:https://codepen.io/maomincoding/pen/RwBBZpr

用法

目前共有11種用法,有些用法是對(duì)一些API的補(bǔ)充。

其中數(shù)據(jù)綁定、屬性綁定、條件渲染、列表渲染、事件處理 這五種用法為基本用法。詳細(xì)用法可以去文檔中查閱,這里就不做贅述。

其余6種則為拓展用法,比如里面提到的靜態(tài)標(biāo)簽中$key,比如我們?cè)诟臄?shù)據(jù)時(shí),Strve.js內(nèi)部需要用到Diff算法進(jìn)行差異對(duì)比,但是也不是所有的節(jié)點(diǎn)都需要進(jìn)行差異對(duì)比,像一些靜態(tài)文本,前后變化都一樣,就不需要再參與對(duì)比。那么用戶在一些需要變化的動(dòng)態(tài)節(jié)點(diǎn)上提供$key靜態(tài)標(biāo)記,標(biāo)識(shí)這需要?jiǎng)討B(tài)變化。

還有我們也可以自己封裝自定義組件,我將其命名為命名功能組件,比如像下面這樣。另外,你需要父子傳值,也可以通過搭配$props實(shí)現(xiàn)。

const state1 = {
count: 0,
};

function add1() {
setData(
() => {
state1.count++;
},
{
name: Component1,
}
);
}

function Component1() {
return h`
<h1>Component1</h1>
<h1 $key>${state1.count}</h1>
<button notallow=${add1}>add1</button>
`;
}

function App() {
return h`
<h2>txt1</h2>
<div>
<p>txt2</p>
<component $name=${Component1.name}>
${Component1()}
</component>
</div>
`;
}

我們也內(nèi)置了很多組件,比如fragment標(biāo)簽,它創(chuàng)建一個(gè)文檔片段標(biāo)簽。它不是真實(shí) DOM 樹的一部分,它的變化不會(huì)觸發(fā) DOM 樹的重新渲染,且不會(huì)對(duì)性能產(chǎn)生影響。

const state = {
x: 0,
y: 0,
};

function App() {
return h`
<fragment>
<h1 $key>Mouse position is at: ${state.x}, ${state.y}</h1>
</fragment>
`;
}

最后,我們?cè)谏衔闹刑岬街С諻eb Components,這里做一下補(bǔ)充。

自定義元素的主要好處是,它們可以在使用任何框架,甚至是在不使用框架的場(chǎng)景下使用。當(dāng)你面向的最終用戶可能使用了不同的前端技術(shù)棧,或是當(dāng)你希望將最終的應(yīng)用與它使用的組件實(shí)現(xiàn)細(xì)節(jié)解耦時(shí),它們會(huì)是理想的選擇。

工具

到目前為止,Strve.js不僅僅是一個(gè)渲染頁面的庫(kù),它可以搭配其他工具為你生成一個(gè)項(xiàng)目搭建框架。

現(xiàn)在有4款工具,分別是CreateStrveApp、CreateStrve、StrveRouter、BabelPluginStrve。

CreateStrveApp與 CreateStrve 都是快速構(gòu)建 Strve.js 項(xiàng)目的命令行工具,與早期的腳手架 CreateStrve 相比,CreateStrveApp 更好,可以直接輸入命令快速創(chuàng)建 Strve 項(xiàng)目。CreateStrveApp 是使用 Vite 構(gòu)建的,這是一個(gè)新的前端構(gòu)建工具,可以顯著提升前端開發(fā)體驗(yàn)。

當(dāng)我們使用Strve.js構(gòu)建單頁面應(yīng)用時(shí),一旦頁面加載完畢,整個(gè)頁面就不會(huì)因?yàn)橛脩舻牟僮鞫匦录虞d或者頁面跳轉(zhuǎn),沒有頁面的跳轉(zhuǎn),是如何實(shí)現(xiàn)頁面跳轉(zhuǎn)的效果呢?使用路由機(jī)制,實(shí)現(xiàn)內(nèi)容的切換,實(shí)現(xiàn)不同內(nèi)容的展示。

StrveRouter 是 Strve.js 的官方路由管理器。它與 Strve.js 的核心深度集成,輕松構(gòu)建單頁應(yīng)用程序。你可以通過下面代碼快速了解StrveRouter的使用。

<!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/strve-js@5.1.1/dist/strve.full-esm.prod.js';
import {
initRouter,
linkTo,
} from 'https://cdn.jsdelivr.net/npm/strve-router@2.3.1/dist/strve-router.esm.js';

class Home {
constructor() {
this.state = {
count: 0,
};
}

useAdd = () => {
setData(() => {
this.state.count++;
});
};

goAbout = () => {
linkTo('/about');
};

render = () => {
return h`
<button notallow=${this.goAbout}>goAbout</button>
<h1 notallow=${this.useAdd} $key>${this.state.count}</h1>
`;
};
}

class About {
constructor() {
this.state = {
msg: 'About',
};
}

useChange = () => {
setData(() => {
this.state.msg = 'Changed';
});
};

goHome = () => {
linkTo('/');
};

render = () => {
return h`
<button notallow=${this.goHome}>goHome</button>
<h1 notallow=${this.useChange} $key>${this.state.msg}</h1>
`;
};
}

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>

我們?cè)谏衔闹械奶岬降木幾g器就是指的是BabelPluginStrve,BabelPluginStrve是一款babel 插件,將 HTML 模板字符串轉(zhuǎn)化為 Virtual Dom。從之前的運(yùn)行時(shí)轉(zhuǎn)移到編譯時(shí),大幅度提高渲染性能。

// input:
const state = {
count: 0,
};

h`<h1 $key>${state.count}</h1>`;

// output:
{
children: [0],
props: {"$key": true},
tag: "h1"
}

相關(guān)安裝與使用方式可以參照文檔。

其他

目前總共分為5個(gè)模塊,分別為更新日志、IDE支持、UI 框架、瀏覽器兼容性、關(guān)于。

其中值得一提的是,在使用編輯器時(shí),如何使HTML標(biāo)簽在模版字符串中高亮顯示。比如這里我們使用Visual Studio Code時(shí),下載es6-string-html插件后,在h``中間添加 /* html */。

function App() {
return h/* html */ `
<div class='inner'>
<p>${state.msg}</p>
</div >
`;
}

另外,UI框架除了支持Bootstrap5、Tailwindcss、還支持Quark,Quark 是一款基于 Web Components 的跨框架 UI 組件庫(kù)。它可以同時(shí)在任意框架或無框架中使用。

這是基于Quark的預(yù)覽地址:??https://codepen.io/maomincoding/pen/MWOmyLW??

圖片

然后,Strve.js也可以跟Three.js搭配使用,以下是預(yù)覽鏈接:??https://codepen.io/maomincoding/pen/GRBYzzM??

圖片

結(jié)語

至此,關(guān)于Strve.js的介紹到這里就結(jié)束了,感謝閱讀。如果大家想進(jìn)一步了解Strve.js,可以到官方文檔查閱。Strve.js我也會(huì)繼續(xù)維護(hù)下去,雖然路很長(zhǎng),很難走,但是我也不會(huì)放棄。

Strve.js 源碼倉(cāng)庫(kù):https://github.com/maomincoding/strve

Strve.js 中文文檔:??https://maomincoding.gitee.io/strve-doc/zh/??

本文轉(zhuǎn)載自微信公眾號(hào)「前端歷劫之路」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系前端歷劫之路公眾號(hào)。


責(zé)任編輯:武曉燕 來源: 前端歷劫之路
相關(guān)推薦

2022-11-10 09:28:40

框架開發(fā)

2021-02-06 23:26:25

聊天室開發(fā)WebSocket

2023-07-10 09:53:59

console開發(fā)插件

2021-04-26 07:31:22

SpringMVCweb框架

2015-09-01 09:53:04

Java Web開發(fā)者

2022-03-07 05:53:41

線程CPU代碼

2016-07-25 18:09:29

2025-02-26 13:07:57

2014-03-12 10:00:26

移動(dòng)開發(fā)跨平臺(tái)

2016-08-04 14:08:57

前端javascripthtml

2025-03-11 01:28:16

2013-05-21 09:32:11

ChromebookChrome OS

2012-06-27 10:16:12

開源項(xiàng)目CodePlex

2021-11-01 11:08:28

鴻蒙HarmonyOS應(yīng)用

2012-11-28 13:25:27

程序員

2014-04-17 10:42:50

DevOps

2016-08-11 17:09:14

Javascripthtml前端

2016-11-07 21:15:12

前后端分離expressJavascript

2016-11-07 21:24:08

HtmlNode.jsJavascript

2013-05-13 10:24:44

谷歌開發(fā)團(tuán)隊(duì)開發(fā)管理
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 中文天堂在线一区 | 丝袜美腿一区二区三区动态图 | 奇色影视| 欧美日韩综合一区 | 一区二区三区四区在线视频 | 国产在线看片 | 国产亚洲网站 | 欧美videosex性极品hd | 一区二区三区四区在线 | 国产在线中文 | 久久国内精品 | 国产精品入口麻豆www | 国产91综合一区在线观看 | 成人午夜影院 | 午夜视频在线观看网址 | 日韩中出 | 国产精品中文在线 | 自拍偷拍小视频 | 亚洲视频在线观看 | 日韩 欧美 综合 | 国产精品久久久久不卡 | 美女黄色在线观看 | 免费影视在线观看 | 视频三区 | 人人爽人人爽 | 日本久久精品视频 | 久久一二区| 免费久久网 | 国产精品久久久久久久一区二区 | 日韩一区二区在线视频 | 国产激情第一页 | 亚洲国产免费 | www.免费看片.com | 欧美一级观看 | 久久激情视频 | 国产免费又色又爽又黄在线观看 | 国产日韩欧美综合 | 国产人成精品一区二区三 | 欧美激情久久久 | 美美女高清毛片视频免费观看 | 99久久精品国产一区二区三区 |