Skip to content

Commit 381c411

Browse files
committed
feat: add props and nested elements in Vue render example
1 parent 549cf4c commit 381c411

File tree

2 files changed

+54
-25
lines changed

2 files changed

+54
-25
lines changed

books/Vue.js设计与实现/2025-2/render/index-render-plus.html

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,19 @@
2525

2626
// 用于在给定的 parent 下添加指定元素
2727
insert(el, parent, anchor = null) {
28+
// eslint-disable-next-line unicorn/prefer-modern-dom-apis
2829
parent.insertBefore(el, anchor);
2930
},
3031
});
3132

3233
renderer.render(
33-
{ type: 'h1', children: 'helloo' },
34+
{
35+
type: 'h1',
36+
props: {
37+
id: 'foo',
38+
},
39+
children: [{ type: 'p', children: 'hello' }],
40+
},
3441
document.querySelector('#app')
3542
);
3643
</script>

books/Vue.js设计与实现/2025-2/render/render-plus.js

Lines changed: 46 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,54 @@
1-
/**
2-
*
3-
* @param {*} oldVnode 旧 vnode
4-
* @param {*} newVnode 新 vnode
5-
* @param {*} container 容器
6-
*/
7-
function patch(oldVnode, newVnode, container) {
8-
// 如果 n1 不存在,意味着挂载,则调用 mountElemnet 函数完成挂载
9-
if (!oldVnode) {
10-
mountElement(newVnode, container);
11-
} else {
12-
// n1 存在,意味着打补丁
1+
function createRenderer(options) {
2+
/**
3+
*
4+
* @param {*} oldVnode 旧 vnode
5+
* @param {*} newVnode 新 vnode
6+
* @param {*} container 容器
7+
*/
8+
function patch(oldVnode, newVnode, container) {
9+
// 如果 n1 不存在,意味着挂载,则调用 mountElemnet 函数完成挂载
10+
if (!oldVnode) {
11+
mountElement(newVnode, container);
12+
} else {
13+
// n1 存在,意味着打补丁
14+
}
1315
}
14-
}
1516

16-
function mountElement(vnode, container) {
17-
// 创建 DOM 元素
18-
const el = document.createElement(vnode.type);
19-
// 处理子节点,,如果子节点是字符串,代表元素具有文本节点
17+
function mountElement(vnode, container) {
18+
// 创建 DOM 元素
19+
const el = document.createElement(vnode.type);
20+
// 处理子节点,,如果子节点是字符串,代表元素具有文本节点
2021

21-
if (typeof vnode.children === 'string') {
22-
el.textContent = vnode.children;
23-
}
22+
if (typeof vnode.children === 'string') {
23+
el.textContent = vnode.children;
24+
}
2425

25-
// 将元素添加到容器中
26-
container.append(el);
27-
}
26+
// 如果 vnode.props 存在才处理下
27+
if (vnode.props) {
28+
// 遍历 vnode.props
29+
// eslint-disable-next-line no-restricted-syntax
30+
for (const key in vnode.props) {
31+
// 获取该 DOM Properties 的类型
32+
const type = typeof el[key];
33+
const value = vnode.props[key];
34+
// 如果是布尔类型,并且 value 是空字符串,则将值矫正为 truue
35+
if (type === 'boolean' && value === '') {
36+
el[key] = true;
37+
} else {
38+
el[key] = value;
39+
}
40+
// 调用 setAttribbute 将属性设置到元素上
41+
el.setAttribute(key, vnode.props[key]);
42+
}
43+
} else {
44+
// 如果要设置的属性没有对应的 DOM Properties,则使用setAttribute 函数设置属性
45+
el.setAttribute(key, vnode.props[key]);
46+
}
47+
48+
// 将元素添加到容器中
49+
options.insert(el, container);
50+
}
2851

29-
function createRenderer(options) {
3052
function render(vnode, container) {
3153
if (vnode) {
3254
// 新 vnode 存在,将其与旧 vnode 一起传递给 patch 函数,进行打补丁

0 commit comments

Comments
 (0)