Skip to content

Commit e80ae07

Browse files
committed
demo: mount&update
1 parent 5cdca0e commit e80ae07

File tree

1 file changed

+77
-0
lines changed

1 file changed

+77
-0
lines changed

slides.md

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1795,8 +1795,85 @@ function compileToFunction(template) {
17951795

17961796
---
17971797

1798+
## 挂载&更新
1799+
1800+
前面我们实现了 **响应式系统****编译**(丐中丐版),现在我们将它们整合起来,同时为了能将代码跑起来,我们还需要稍微简单实现下 **挂载和更新** (这里不涉及 patch)。
1801+
1802+
---
1803+
1804+
<div grid="~ cols-2 gap-2">
1805+
1806+
```js
1807+
function createApp(options = {}) {
1808+
const app = {
1809+
mount(container) {
1810+
if (isString(container)) {
1811+
container = document.querySelector(container)
1812+
}
1813+
const template = container.innerHTML
1814+
const render = compileToFunction(template)
1815+
const setupFn = options.setup || noop
1816+
const setupResult = setupFn() || {}
1817+
const data = proxyRefs(setupResult)
1818+
1819+
const reload = () => {
1820+
const vnode = render(data, { h, _toDisplayString: function toString(val) { return val && val.toString() } })
1821+
container.innerHTML = ''
1822+
_mount(vnode, container)
1823+
}
1824+
// 副作用函数
1825+
effect(() => {
1826+
reload()
1827+
})
1828+
}
1829+
}
1830+
return app
1831+
}
1832+
```
1833+
1834+
```js
1835+
// 挂载
1836+
function _mount(vnode, container) {
1837+
const el = document.createElement(vnode.tag)
1838+
if (vnode.props) {
1839+
for (let key in vnode.props) {
1840+
if (key.startsWith('on')) { // 事件绑定
1841+
const eventName = key.slice(2).toLowerCase()
1842+
el.addEventListener(eventName, vnode.props[key])
1843+
} else {
1844+
el.setAttribute(key, vnode.props[key])
1845+
}
1846+
}
1847+
}
1848+
if (Array.isArray(vnode.children)) {
1849+
if (vnode.children.length === 1 && typeof vnode.children[0] != 'object') {
1850+
el.textContent = vnode.children[0]
1851+
} else {
1852+
vnode.children.forEach(child => {
1853+
_mount(child, el)
1854+
})
1855+
}
1856+
} else { // string
1857+
el.textContent = vnode.children
1858+
}
1859+
container.appendChild(el)
1860+
}
1861+
```
1862+
1863+
</div>
1864+
1865+
---
1866+
1867+
现在代码应该可以跑起来了,并且能够响应式更新。
1868+
1869+
接下来来看一个 **计数器 demo**
1870+
1871+
---
1872+
17981873
## counter 计数器 demo
17991874

1875+
demo: `22-counter.html`
1876+
18001877
<div grid="~ cols-2 gap-2">
18011878

18021879
```html

0 commit comments

Comments
 (0)