背景
vue是啥,有哪些基本功能,模板,script, style, 雙向綁定一大堆,太多東西了,太難了,直接開始動(dòng)手吧
倉(cāng)庫(kù)
https://github.com/listen80/two-way-binding
體驗(yàn)一下(pc上使用)
https://listen80.github.io/two-way-binding/public/
單文件
通過ajax獲取類似.vue .html .tpl文件
| const parser = new DOMParser(); |
|
| export default (template) => { |
| const doc = parser.parseFromString(`<body>${template}</body>`, 'text/html'); |
| const body = doc.querySelector('body') |
| return { |
| template: body.querySelector('template')?.content, |
| script: body.querySelector('script'), |
| style: body.querySelector('style'), |
| } |
| }; |
構(gòu)建vue實(shí)例
- 把script文本變成script運(yùn)行
- 把原始data變成reactive的形式,增加依賴收集
- 解析template,扣出來指令,屬性,方法,子組件等為了區(qū)分指令前綴使用@而不是v-
- 掛載style樣式增加
- 替換當(dāng)前實(shí)例掛載的元素,目前為止所有的元素(html, script, style)都已經(jīng)使用上來了
| |
| |
|
|
| create() { |
| |
| const { el, props = {} } = this.options |
| |
| const { script, template, style } = this.componentProperties |
| |
| |
| const es6ModuleCode = script.textContent; |
|
| |
| |
| const blob = new Blob([es6ModuleCode], { type: 'text/javascript' }); |
| |
| const url = URL.createObjectURL(blob); |
|
| |
| |
| import(url).then(module => { |
| |
| document.head.append(style) |
| |
| |
| const data = module.default.data || {}; |
| |
| const methods = module.default.methods || {}; |
| |
| const components = module.default.components || {}; |
| |
| Object.assign(this, props, data); |
| |
| observe(this); |
| |
| |
| compile(template, this, methods, components); |
| |
| |
| el.replaceWith(template) |
| }).catch(err => { |
| |
| console.error('加載模塊失敗', err); |
| }); |
| } |
總結(jié)
就這么結(jié)束了,是不是很簡(jiǎn)單,當(dāng)然其中的細(xì)節(jié)很多,上文主要是描述核心思想點(diǎn)
本demo是沒有使用虛擬dom,是dom跟數(shù)據(jù)直接綁定的,跟進(jìn)vue3.6 vapor
水平有限,本文只是為了學(xué)習(xí)分享簡(jiǎn)單的示例,目的是為了了解運(yùn)作機(jī)制
轉(zhuǎn)自https://www.cnblogs.com/listen80/p/19026582
該文章在 2025/8/7 15:25:02 編輯過