模仿vue實現模板渲染和響應式資料

2021-10-05 16:38:24 字數 4398 閱讀 1881

第一次寫於: 2023年5月2日

既然要最求刺激,那就要貫徹到底. — 品如

想要模仿vue, 那就要知道vue實現了什麼功能.

以及根據我現在的個人能力,我能夠實現的功能.

為了方便區分, 我把自己實現的內容稱為jue

vue的功能

jue想要實現的功能

目前實現的只有插值表示式

其它的在日後可能更新

想要的效果

>

>

>

} }li

>

>

} }li

>

ul>

div>

能夠轉化成

>

>

>

jue maleli

>

>

18 maleli

>

ul>

div>

思路思路1.

建立乙個fragment乙個個地取出div中的元素

遇到插值表示式, 進行替換

將處理完成後的文字放入fragment中

思路2.

將html元素轉化成vnode通過vnode獲取到 render函式

通過render 函式進行渲染

這種方法實現起來比較麻煩.用到了vue ast(抽象語法樹)

我暫時還沒有太深入地了解;

聯想到webpack的作用, 我總感覺現在前端越來越有趣了.

js的執行肯定都是通過js的解析器.

而現在有各種語法,js的解析器可能還不能處理;

那麼,通過各種編譯工具去把這些**處理成js解析器可以執行**;

讓我不禁回憶起學習編譯原理的青蔥歲月.

編譯原理可是真地難.

我的實現

處理表示式的乙個類

class

jueexpr

getvalue()

,this

.data)

}text()

}

處理模板編譯的類;

注釋掉的內容, 是和下面響應式資料相關的;

可以暫時忽略.

class

compiler

loadtemplate

(el)

node.

(fragment)

}compile

(dom)

compiledbynodetype

(dom, nodetype)

if(nodetype ===1)

}compiletext

(dom)

\}/gif(

!defaulttagre.

test

(text)

)let vm =

this

.vm // let watcher = new watcher(vm, fn)

// 將更新方法使用函式包裹起來. 利用閉包, 再次更新時, 可以取到原來的textfn(

)functionfn(

))return dom.textcontent

}}updatetext

(dom, text)

\}/g

dom.textcontent = text.

replace

(defaulttagre,

(...args)

=>)}

compileelement

(dom))}

}

想要的效果當我們修改data中的資料, 在頁面中也應該會有對應的變化;

this

.*** =

'female'

對應的檢視中也會有相應的變化

實現資料驅動檢視

思路

我把響應式的資料成為state

說白了,就是說對state進行了修改, 我是需要知道, 並進行處理的;

大致的流程如上圖;

模板編譯的時候, 遇到乙個插值表示式, 就需要生成乙個watcher,

當state發生變化時, 要去更新 watcher提供的update方法

相當於觀察者模式中的觀察者(中的 watcher 和 sub);

它觀察資料的變化, 當資料一旦發生變化.

就要去更新檢視

我在開發時遇到的問題

怎麼能夠獲取資料的更新操作呢?

怎麼能夠處理更新的資料, 讓檢視中只更新發生變化的資料?

怎麼處理資料和檢視之間的依賴關係

實現

class

depnotify()

)}addsubscriber

(watcher)

this

.subscribers.

add(watcher)

dep.target =

null}}

dep.target =

null

class

watcher

setoldvalue

(oldvalue)

this

.oldvalue = oldvalue

this

.isnew =

true

}update()

}}class

observer

observe

(obj)

,set

(newval)

val = newval

dep.

notify()

},})

if(typeof val ===

'object')}

)}}class

jueexpr

getvalue()

,this

.data)

}text()

}class

compiler

loadtemplate

(el)

node.

(fragment)

}compile

(dom)

compiledbynodetype

(dom, nodetype)

if(nodetype ===1)

}compiletext

(dom)

\}/gif(

!defaulttagre.

test

(text)

)let vm =

this

.vm let watcher =

newwatcher

(vm, fn)fn(

)functionfn(

))return dom.textcontent

}}updatetext

(dom, text)

\}/g

dom.textcontent = text.

replace

(defaulttagre,

(...args)

=>)}

compileelement

(dom))}

}class

juecompiletemplate()

proxydata

(vm, obj)

,set

(v),})

})}proxymethods

(vm, methods)})

})}}

newjue(,

age:24,

***:

'male'}}

, methods:},

})

完整的**在github上

文章** github

building-a-reactivity-system-similar-to-vue

面試官:你了解 vue 的diff演算法嗎?

詳解vue的diff演算法

js-tokens

generator

深入vue2.0底層思想–模板渲染

vue 的 diff 演算法解析

diff 演算法解析

解析vue2.0的diff演算法

VUE 響應式渲染

1 插值 a.文字 b.純html v html 防止xss,csrf 1 前端過濾 2 後台轉義 3 給cookie 加上屬性 http c.表示式 2 指令 是帶有 v 字首的特殊屬性 v bind 動態繫結屬性 v if 動態建立 刪除 v show 動態顯示 隱藏 v on click 繫結...

vue的響應式系統 和響應式原理

web m v 組成 mvc 發生在後端 mvc 是一種使用 mvc model view controller 模型 檢視 控制器 設計建立 web 應用 model 模型 表示應用程式核心 比如資料庫記錄列表 view 檢視 顯示資料 資料庫記錄 controller 控制器 處理輸入 寫入資料...

Vue Vue三要素模板解析 響應式 渲染

vue 實現流程 1 把模板解析為 render 函式 運用 with 模板中的所有資訊都被 render 函式包含 模板中用到的 data 中的屬性,都變成了 js 變數 模板中的 v model v for v on 都變成了 js 邏輯 render 函式返回 vnode vue三要素之模板解...