Skip to content

Commit

Permalink
更新element的children
Browse files Browse the repository at this point in the history
  • Loading branch information
jindy committed Jun 15, 2022
1 parent 4a710fe commit 9197be5
Show file tree
Hide file tree
Showing 9 changed files with 238 additions and 29 deletions.
19 changes: 19 additions & 0 deletions example/PatchChildren/ArrayToText.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { h,ref } from '../../lib/guide-mini-vue.esm.js'
const nextChildren = 'newChildren'
const prevChildren = [h('div', {}, 'A'), h('div', {}, 'B')]

export default {
name: 'ArrayToText',
setup() {
const isChange = ref(false)
window.isChange = isChange

return {
isChange
}
},
render() {
const self = this
return self.isChange ? h('div', {}, nextChildren) : h('div', {}, prevChildren)
}
}
21 changes: 21 additions & 0 deletions example/PatchChildren/TextToArray.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@


import { h,ref } from '../../lib/guide-mini-vue.esm.js'
const prevChildren = 'newChildren'
const nextChildren = [h('div', {}, 'A'), h('div', {}, 'B')]

export default {
name: 'TextToArray',
setup() {
const isChange = ref(false)
window.isChange = isChange

return {
isChange
}
},
render() {
const self = this
return self.isChange ? h('div', {}, nextChildren) : h('div', {}, prevChildren)
}
}
19 changes: 19 additions & 0 deletions example/PatchChildren/TextToText.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { h,ref } from '../../lib/guide-mini-vue.esm.js'
const nextChildren = 'newChildren'
const prevChildren = 'oldChildren'

export default {
name: 'TextToText',
setup() {
const isChange = ref(false)
window.isChange = isChange

return {
isChange
}
},
render() {
const self = this
return self.isChange ? h('div', {}, nextChildren) : h('div', {}, prevChildren)
}
}
16 changes: 16 additions & 0 deletions example/PatchChildren/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>patch children</title>
</head>

<body>
<div id="app"></div>
<script src="./mian.js" type="module"></script>
</body>

</html>
5 changes: 5 additions & 0 deletions example/PatchChildren/mian.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { createApp } from '../../lib/guide-mini-vue.esm.js'
import { App } from './App.js'

const rootContainer = document.querySelector('#app')
createApp(App).mount(rootContainer)
61 changes: 51 additions & 10 deletions lib/guide-mini-vue.cjs.js
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,7 @@ function createAppAPI(render) {
}

function createRenderer(options) {
const { createElement: hostCreateElement, patchProp: hostPatchProp, insert: hostInsert, } = options;
const { createElement: hostCreateElement, patchProp: hostPatchProp, insert: hostInsert, remove: hostRemove, setElementText: hostSetElementText, } = options;
function render(vnode, container) {
patch(null, vnode, container, null);
}
Expand Down Expand Up @@ -496,16 +496,17 @@ function createRenderer(options) {
mountElement(n2, container, parentComponent);
}
else {
patchElement(n1, n2);
patchElement(n1, n2, container, parentComponent);
}
}
function patchElement(n1, n2, container) {
console.log("n1", n1);
console.log("n2", n2);
console.log("patchElement");
function patchElement(n1, n2, container, parentComponent) {
// console.log("n1", n1)
// console.log("n2", n2)
// console.log("patchElement")
const oldProps = n1.props || EMPTY_OBJ;
const newProps = n2.props || EMPTY_OBJ;
const el = (n2.el = n1.el);
patchChildren(n1, n2, container, parentComponent);
patchProps(el, oldProps, newProps);
}
function patchProps(el, oldProps, newProps) {
Expand Down Expand Up @@ -535,7 +536,7 @@ function createRenderer(options) {
el.textContent = children;
}
else if (shapeFlag & 8 /* ShapeFlags.ARRAY_CHILDREN */) {
mountChildren(vnode, el, parentComponent);
mountChildren(vnode.children, el, parentComponent);
}
// 处理props
const { props } = vnode;
Expand All @@ -547,19 +548,48 @@ function createRenderer(options) {
// container.append(el)
hostInsert(el, container);
}
function mountChildren(vnode, container, parentComponent) {
vnode.children.forEach(function (v) {
function mountChildren(children, container, parentComponent) {
children.forEach(function (v) {
patch(null, v, container, parentComponent);
});
}
function processFragment(n1, n2, container, parentComponent) {
mountChildren(n2, container, parentComponent);
mountChildren(n2.children, container, parentComponent);
}
function processText(n1, n2, container) {
const { children } = n2;
const textNode = (n2.el = document.createTextNode(children));
container.append(textNode);
}
function patchChildren(n1, n2, container, parentComponent) {
const prevShapeFlag = n1.shapeFlag;
const { shapeFlag, children } = n2;
const child1 = n1.children;
const child2 = n2.children;
if (shapeFlag & 4 /* ShapeFlags.TEXT_CHILDREN */) {
if (prevShapeFlag & 8 /* ShapeFlags.ARRAY_CHILDREN */) {
// 1.清空old children
unmountChildren(n1.children);
// 2.设置text
// hostSetElementText(container, child2)
}
if (child1 !== child2) {
hostSetElementText(container, child2);
}
}
else {
if (prevShapeFlag & 4 /* ShapeFlags.TEXT_CHILDREN */) {
hostSetElementText(container, "");
mountChildren(child2, container, parentComponent);
}
}
}
function unmountChildren(children) {
for (let index = 0; index < children.length; index++) {
const el = children[index].el;
hostRemove(el);
}
}
return {
createApp: createAppAPI(render),
};
Expand Down Expand Up @@ -589,10 +619,21 @@ function patchProp(el, key, prevProp, nextProp) {
function insert(el, parent) {
parent.append(el);
}
function remove(child) {
const parent = child.parentNode;
if (parent) {
parent.removeChild(child);
}
}
function setElementText(el, text) {
el.textContent = text;
}
const renderer = createRenderer({
createElement,
patchProp,
insert,
remove,
setElementText,
});
function createApp(...args) {
return renderer.createApp(...args);
Expand Down
61 changes: 51 additions & 10 deletions lib/guide-mini-vue.esm.js
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ function createAppAPI(render) {
}

function createRenderer(options) {
const { createElement: hostCreateElement, patchProp: hostPatchProp, insert: hostInsert, } = options;
const { createElement: hostCreateElement, patchProp: hostPatchProp, insert: hostInsert, remove: hostRemove, setElementText: hostSetElementText, } = options;
function render(vnode, container) {
patch(null, vnode, container, null);
}
Expand Down Expand Up @@ -492,16 +492,17 @@ function createRenderer(options) {
mountElement(n2, container, parentComponent);
}
else {
patchElement(n1, n2);
patchElement(n1, n2, container, parentComponent);
}
}
function patchElement(n1, n2, container) {
console.log("n1", n1);
console.log("n2", n2);
console.log("patchElement");
function patchElement(n1, n2, container, parentComponent) {
// console.log("n1", n1)
// console.log("n2", n2)
// console.log("patchElement")
const oldProps = n1.props || EMPTY_OBJ;
const newProps = n2.props || EMPTY_OBJ;
const el = (n2.el = n1.el);
patchChildren(n1, n2, container, parentComponent);
patchProps(el, oldProps, newProps);
}
function patchProps(el, oldProps, newProps) {
Expand Down Expand Up @@ -531,7 +532,7 @@ function createRenderer(options) {
el.textContent = children;
}
else if (shapeFlag & 8 /* ShapeFlags.ARRAY_CHILDREN */) {
mountChildren(vnode, el, parentComponent);
mountChildren(vnode.children, el, parentComponent);
}
// 处理props
const { props } = vnode;
Expand All @@ -543,19 +544,48 @@ function createRenderer(options) {
// container.append(el)
hostInsert(el, container);
}
function mountChildren(vnode, container, parentComponent) {
vnode.children.forEach(function (v) {
function mountChildren(children, container, parentComponent) {
children.forEach(function (v) {
patch(null, v, container, parentComponent);
});
}
function processFragment(n1, n2, container, parentComponent) {
mountChildren(n2, container, parentComponent);
mountChildren(n2.children, container, parentComponent);
}
function processText(n1, n2, container) {
const { children } = n2;
const textNode = (n2.el = document.createTextNode(children));
container.append(textNode);
}
function patchChildren(n1, n2, container, parentComponent) {
const prevShapeFlag = n1.shapeFlag;
const { shapeFlag, children } = n2;
const child1 = n1.children;
const child2 = n2.children;
if (shapeFlag & 4 /* ShapeFlags.TEXT_CHILDREN */) {
if (prevShapeFlag & 8 /* ShapeFlags.ARRAY_CHILDREN */) {
// 1.清空old children
unmountChildren(n1.children);
// 2.设置text
// hostSetElementText(container, child2)
}
if (child1 !== child2) {
hostSetElementText(container, child2);
}
}
else {
if (prevShapeFlag & 4 /* ShapeFlags.TEXT_CHILDREN */) {
hostSetElementText(container, "");
mountChildren(child2, container, parentComponent);
}
}
}
function unmountChildren(children) {
for (let index = 0; index < children.length; index++) {
const el = children[index].el;
hostRemove(el);
}
}
return {
createApp: createAppAPI(render),
};
Expand Down Expand Up @@ -585,10 +615,21 @@ function patchProp(el, key, prevProp, nextProp) {
function insert(el, parent) {
parent.append(el);
}
function remove(child) {
const parent = child.parentNode;
if (parent) {
parent.removeChild(child);
}
}
function setElementText(el, text) {
el.textContent = text;
}
const renderer = createRenderer({
createElement,
patchProp,
insert,
remove,
setElementText,
});
function createApp(...args) {
return renderer.createApp(...args);
Expand Down
Loading

0 comments on commit 9197be5

Please sign in to comment.