iT邦幫忙

2023 iThome 鐵人賽

DAY 19
0
Vue.js

淺談vue3源碼,很淺的那種系列 第 25

[Day 24]ast抽象語法樹 - 2——前置準備及明確目標

  • 分享至 

  • xImage
  •  

書接上回,我們要接著往/src/ast/parse.ts的parse方法的方法體內寫東西。

來明確一下我們首先需要甚麼吧。遍歷嘛,指針是需要的;需要先把上標籤挑出來,所以檢測上標籤的正則也是需要的;同理,也需要檢測下標籤的正則;最後就是檢測內文的正則。

templateString = templateString.trim()
// 指針
let index = 0
// 檢測開始標籤,捕獲標籤內文字。ex:<(div)>
const startRegExp = /^\<([a-z]+[1-6]?)(\s[^\<]+)?\>/
// 檢測結束標籤,捕獲標籤內文字。ex:</(div)>
const endRegExp = /^\<\/([a-z]+[1-6]?)\>/
// 檢測文字+下標籤
const wordRegExp = /^([^\<]+)\<\/[a-z]+[1-6]?\>/

實際上上標籤的水很深,要完美匹配template中可能出現的所有上標籤,這個正則是絕對不夠用的。但還記得我們這次鐵人賽的標題嗎?我們淺談,水深的不碰(?)

一方面這水太深我也把持不住,另一方面最近太多想學習的技術積著了,時間不夠也是問題……要是真對怎麼完美匹配上標籤感興趣,請直接去翻源碼吧,恕我就只淺談了。

回歸正題,因為html標籤屬於是嵌套關係,一個套一個,先有父標籤,再有子標籤,子標籤先閉合,父標籤才閉合。先有後閉,先進後出,正所謂棧結構。

所以我們再開一個棧來裝遍歷到的標籤:

const tagStack: string[] = [];
type TagContent = {
  tag?: string;
  attrs?: Record<string, any>;
  children: (string | TagContent)[];
};
const textStack: TagContent[] = [{ children: [] }];

之後每當有標籤入棧tagStack,就給textStack入棧一個TagContent型別的對象,來裝之後我們解析出來的標籤名、屬性及內容。因為把template全部解析完以後還需要有一個對象來裝著,所以textStack默認有包含children屬性的第0項,之後textStack會維持比tagStack多一項,除去textStack的第0項以外的每一項,都和tagStack的每一項一一對應。

就是這種關係:

所以接下來我們的步驟是這樣的:

  1. 每當檢測到上標籤,就給兩個棧分別入棧,並把標籤種類放進textStack棧頂的tag屬性。
  2. 檢測到屬性,就放到textStack棧頂的props屬性。
  3. 發現標籤裡面還有標籤,就重複1.的步驟。
  4. 看到標籤內文就push進textStack棧頂的children屬性。
  5. 看到下標籤代表解析完棧頂的標籤,就讓兩個棧頂出棧,同時把textStack出棧的那項push進新棧頂的children屬性。

循環上述步驟直到遍歷完整個template以後,我們就能得到類似這種結構的樹:

{
  children: [
    {
      tag: 'h1',
      props: {},
      children: ['願望清單']
    },
    {
      tag: 'ul',
      props: { style: 'list-style: none;' },
      children: [
        {
          tag: 'li',
          props: {},
          children: '漲薪'
        },
        {
          tag: 'li',
          props: {},
          children: '準時下班'
        },
        {
          tag: 'li',
          props: {},
          children: '再和昨天提到的學姊當一回同事'
        }
      ]
    }
  ]
}

如何,是不是很像昨天提到的h函數可以接收的參數?只要把template解析成樹結構,接下來就只要遞歸調用h函數,虛擬dom就大功告成。

而這就是我們明天的課題了。

github - [Day 24]ast抽象語法樹 - 2——前置準備及明確目標


上一篇
[Day 23]ast抽象語法樹 - 1——前置準備
下一篇
[Day 25]ast抽象語法樹 - 2——解析標籤
系列文
淺談vue3源碼,很淺的那種31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言