手把手帶你(nǐ)用 Vue 3.0 寫個(gè)小程序框架 - 新聞資(zī)訊 - 雲南小程序開發|雲南軟件開發|雲南網站(zhàn)建設-西山區知普網絡科技工作室

159-8711-8523

雲南網建設/小程序開發/軟件開發

知識

不管是網站(zhàn),軟件還是小程序,都要直接或間接能為您産生價值,我們在追求其視覺表現的同時,更側重于功能的便捷,營銷的便利,運營的高效,讓網站(zhàn)成為營銷工具,讓軟件能切實提升企業(yè)内部管理水平和(hé)效率。優秀的程序為後期升級提供便捷的支持!

手把手帶你(nǐ)用 Vue 3.0 寫個(gè)小程序框架

發表時間:2021-1-4

發布人:葵宇科技

浏覽次數:44

由于小程序的開發起來比較原始複雜且繁瑣,跟我們主流的開發方式差距很大,所以為了提高我們開發小程序的效率,市面上出現過很多的小程序的框架:mpvue,Taro,uni-app 等等,這些框架或多或少(shǎo)地将我們帶到現代化的開發方式中(zhōng)來,他們可(kě)以讓你(nǐ)使用 React 或者 Vue 來開發小程序。今天就分享一個(gè)如(rú)何利用 Vue 3.0 來構建一個(gè)小程序的框架

1、Vue3 部分新特性

Vue3 的新特性主要有 Composition APITeleportFragments 和(hé) <script setup /> & <style vars /> 等。

1. Composition API

Vue2.x 基于 Option API(選項 API )構建組件,一般來說組件擁有 data、methods、computed 等選項。這是一種屬性相互隔離(lí)的模式,好處是各屬性内容分離(lí)開,對于新手來說比較友好。
但對于大型項目來說,為了修改某個(gè)功能,可(kě)能需要在一個(gè)文(wén)件中(zhōng)來回翻頁。Vue3 增加了 Composition API 方式(組合 API ),基于 reactivity(響應式)的思想進行組件構建,将邏輯封裝到函數中(zhōng),可(kě)以實現類似 React Hooks 的邏輯組合和(hé)重用。
對于大型項目,代碼按照具體功能劃分,而不是分散在不同的生命周期中(zhōng),邏輯更加一目了然。

2. Teleport(傳入)

Teleport 功能,使得我們可(kě)以将全屏的組件(例如(rú) Toast)移到 Vue APP 節點外,而不需要在 UI 界面上修改其他組件樣式,方便實現全屏蒙層、浮層彈窗等效果。

3. Fragments(碎片)

Vue2.x 版本中(zhōng),<template /> 标簽下(xià)不支持放置多個(gè)組件,這個(gè)限制在 Vue3 中(zhōng)不再存在。這點比較好理解,下(xià)述組件設計在 Vue3 中(zhōng)是沒有問(wèn)題的:
<template>
<header>...</header>

<main v-bind="$attrs">
...</main>

<footer>
...</footer>

</template>

4. 實驗性質的語法糖<script setup>、<style vars>
a<script setup>:用于在 SFC 中(zhōng)使用 Composition API 的語法糖,改善在單個(gè)文(wén)件組件中(zhōng)使用 Composition API 時的體驗。
b、<style vars>: SFC 中(zhōng)狀态驅動(dòng)的 CSS 變量,它提供了直接的 CSS 配置和(hé)封裝,支持将組件狀态驅動(dòng)的CSS變量注入到“單個(gè)文(wén)件組件”樣式中(zhōng)。
2、小程序
要開發一個(gè)小程序的頁面基本上我們隻需要四個(gè)文(wén)件:

index.js

index.js 就是我們寫代碼邏輯的地方。
  • 有一個(gè) Page 函數,裡面是對象配置,類似于 Vue 的 options 配置一樣,有一個(gè) data 屬性,存放着初始化的數據。

  • 如(rú)果想要修改數據改變視圖,又需要像react一樣,需要調用 setData 去修改視圖。


index.ttml

index.ttml 是我們寫視圖模闆的地方。
  • 類似于 vue 的 template,我們需要先定義模闆才能顯示視圖

  • 注意: 不能直接在 index.js 裡面去修改定義的模闆的 DOM,隻能先定義好,這是由于小程序架構雙線程導緻的,分為邏輯層和(hé)渲染層,我們寫的 index.js 代碼跑在邏輯層裡面,index.ttml 跑在渲染層裡面,兩個(gè)線程就通(tōng)過 setData 進行數據交換。

index.json
配置小程序頁面和(hé)組件的地方,暫時不列出參數,但是一定要有這個(gè)文(wén)件。

index.ttss

顧名思義,就是寫樣式的地方,類似于 CSS。

模闆

小程序為了封裝的方便,可(kě)以先提前定義一個(gè)模闆,然後再需要的地方引入模闆即可(kě),有點像 ejs 和(hé) pug 的 import template 的用法

動(dòng)态模闆
上面說到,小程序裡面不能動(dòng)态的修改 DOM 節點,隻能提前定義好 template,然後通(tōng)過 setData 的形式去修改視圖。
但是小程序又有個(gè)比較動(dòng)态的特性,叫做動(dòng)态選擇模闆

// 使用這個(gè)模闆 <template is="{{type}}" data="http://www.wxapp-union.com/{{item: item}}"/>
上面 is 屬性的 type 就是動(dòng)态的,它是個(gè)變量可(kě)以根據 type 的值來選擇不同的模闆,比如(rú) type 為 view 時,就會渲染我們提前定義好的 view template。

自定義渲染層

重頭戲來了,我們該如(rú)何利用 Vue 3.0 方便的自定義渲染層 結合小程序的動(dòng)态選擇模闆的特性來去寫一個(gè)小程序的框架呢(ne)?

我們可(kě)以看到`createRenderer`函數需要兩個(gè)參數,一個(gè)是patchProp,一個(gè)是nodeOps。

nodeOps

nodeOps 代表着修改 node 節點的一些操作,從而可(kě)以去改變視圖,比如(rú)在 Vue 3.0 的浏覽器(qì)環境中(zhōng),是這麼寫的:

實際上 Vue 不管數據怎麼變化,要将數據顯示到視圖上都是調用了 DOM 的一些 API,像上面的 doc.createElement 和(hé) doc.createTextNode 等等。

VNode

是由于小程序的限制,我們不能直接像浏覽器(qì)環境一樣去修改 DOM,那我們可(kě)以先模仿浏覽器(qì)的環境,創造出一個(gè)虛拟的DOM,我們叫做 VNode
可(kě)以看到我們創建的 VNode 類似于 DOM,也有一些操作 Node 節點的方法,最終生成一個(gè) Node 樹(shù)。我們就可(kě)以仿照vue 浏覽器(qì)環境的 nodeOps 寫法,先去修改我們的 VNode,在修改 Node 節點的同時裡面我們可(kě)以去調用小程序的 setData 方法。

toJSON()

光是創造出 VNode 還不夠,我們得讓它渲染到小程序裡面去,小程序要先渲染出數據必須是提前在 data 屬性裡面定義的數據,而且隻能是普通(tōng)的數據類型。

toJSON 方法就是可(kě)以将一個(gè) VNode 給格式化成普通(tōng)的對象,讓小程序可(kě)以渲染出數據。
接口類型如(rú)下(xià):

是不是跟 VDOM 的結構很熟悉?

path()

我們可(kě)以看到在我們定義的 VNode 裡面,裡面有個(gè) path() 方法,這個(gè)方法就是獲取 Node 節點在整個(gè)節點樹(shù)的一個(gè)路(lù)徑,然後可(kě)以利用 path 去修改某一個(gè)特定的 Node 節點。

編譯層

我們寫的代碼肯定是Vue的代碼,不是上面的模闆代碼,那麼Vue的代碼改怎麼樣去編譯到上面的模闆代碼呢(ne)?
先看一下(xià)整體架構圖:

Template

如(rú)果我們寫的業(yè)務代碼是常見的 vue 指令模闆模式,那麼我們可(kě)以在底層使用 @vue/compile-core parse Vue 的 template,然後遍曆 parse 後的 AST,收集其中(zhōng)用到的 tag 和(hé) props。

JSX/TSX

如(rú)果我們寫的業(yè)務代碼是 JSX/TSX,那麼這邊可(kě)以寫個(gè)收集 Tag 和(hé) props 的 babel plugin,在 babel plugin 裡面去遍曆 AST,收集 Tag 和(hé) props。

最終生成的 ttml

假如(rú)我們有一個(gè) .vue 文(wén)件:

會生成下(xià)面的模闆:

可(kě)以看到,從 $_TPL 的 root 節點出發,可(kě)以根據每個(gè) item.type 來去選擇下(xià)面生成的每個(gè)模闆,每個(gè)模闆裡面又有循環,這樣就可(kě)以結合VNode 無限的遞歸的渲染。

相關(guān)案例查看更多