@viewfly/core 1.0.0-alpha.9 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -234,9 +234,8 @@ const THROW_IF_NOT_FOUND = {
234
234
  const nullInjectorErrorFn = (token) => {
235
235
  return makeError('NullInjector')(`No provide for \`${stringify(token)}\`!`);
236
236
  };
237
- class NullInjector extends Injector {
237
+ class NullInjector {
238
238
  constructor() {
239
- super(...arguments);
240
239
  this.parentInjector = null;
241
240
  }
242
241
  /* eslint-disable-next-line */
@@ -411,11 +410,9 @@ const provideScopeError = (token) => {
411
410
  /**
412
411
  * 反射注入器
413
412
  */
414
- class ReflectiveInjector extends Injector {
413
+ class ReflectiveInjector {
415
414
  constructor(parentInjector, staticProviders, scope) {
416
- super();
417
415
  this.parentInjector = parentInjector;
418
- this.staticProviders = staticProviders;
419
416
  this.scope = scope;
420
417
  this.recordValues = new Map();
421
418
  this.normalizedProviders = staticProviders.map(provide => {
@@ -634,6 +631,9 @@ function styleToObject(style) {
634
631
  });
635
632
  return obj;
636
633
  }
634
+ const TextAtomType = Symbol('Text');
635
+ const ElementAtomType = Symbol('Element');
636
+ const ComponentAtomType = Symbol('Component');
637
637
 
638
638
  const componentSetupStack = [];
639
639
  const signalDepsStack = [];
@@ -740,16 +740,13 @@ class Component extends ReflectiveInjector {
740
740
  portalHost: this.instance.$portalHost
741
741
  };
742
742
  }
743
- update(newProps, forceUpdate = false) {
744
- if (!forceUpdate) {
745
- const { add, remove, replace } = getObjectChanges(newProps, this.props);
743
+ update(newProps) {
744
+ const oldProps = this.props;
745
+ if (newProps !== oldProps) {
746
+ const { add, remove, replace } = getObjectChanges(newProps, oldProps);
746
747
  if (add.length || remove.length || replace.length) {
747
748
  this.invokePropsChangedHooks(newProps);
748
749
  }
749
- else if (!this.dirty) {
750
- this.props = newProps;
751
- return this.template;
752
- }
753
750
  const newRefs = toRefs(newProps.ref);
754
751
  if (this.refs) {
755
752
  for (const oldRef of this.refs) {
@@ -766,7 +763,7 @@ class Component extends ReflectiveInjector {
766
763
  }
767
764
  }
768
765
  if (typeof this.instance.$useMemo === 'function') {
769
- if (this.instance.$useMemo(newProps, this.props)) {
766
+ if (this.instance.$useMemo(newProps, oldProps)) {
770
767
  return this.template;
771
768
  }
772
769
  }
@@ -1284,15 +1281,16 @@ function withMemo(canUseMemo, render) {
1284
1281
  }
1285
1282
 
1286
1283
  const componentViewCache = new WeakMap();
1287
- const listenerReg = /^on(?=[A-Z])/;
1284
+ const listenerReg = /^on[A-Z]/;
1288
1285
  function createRenderer(component, nativeRenderer) {
1289
1286
  let isInit = true;
1290
1287
  return function render(host) {
1291
1288
  if (isInit) {
1292
1289
  isInit = false;
1293
1290
  const atom = {
1294
- type: 'component',
1291
+ type: ComponentAtomType,
1295
1292
  index: 0,
1293
+ nodeType: component.type,
1296
1294
  jsxNode: component,
1297
1295
  sibling: null,
1298
1296
  child: null,
@@ -1312,41 +1310,28 @@ function createRenderer(component, nativeRenderer) {
1312
1310
  }
1313
1311
  function buildView(nativeRenderer, parentComponent, atom, context) {
1314
1312
  const { jsxNode, type } = atom;
1315
- if (type === 'component') {
1313
+ if (type === ComponentAtomType) {
1316
1314
  const component = new Component(parentComponent, jsxNode.type, jsxNode.props, jsxNode.key);
1317
1315
  atom.jsxNode = component;
1318
1316
  componentRender(nativeRenderer, component, atom, context);
1319
1317
  }
1318
+ else if (type === ElementAtomType) {
1319
+ createElement(nativeRenderer, atom, parentComponent, context);
1320
+ }
1320
1321
  else {
1321
- let nativeNode;
1322
- let applyRefs = null;
1323
- if (type === 'element') {
1324
- const { nativeNode: n, applyRefs: a } = createElement(nativeRenderer, jsxNode, atom.isSvg);
1325
- nativeNode = n;
1326
- applyRefs = a;
1327
- }
1328
- else {
1329
- nativeNode = createTextNode(nativeRenderer, jsxNode, atom.isSvg);
1330
- }
1331
- atom.nativeNode = nativeNode;
1332
- insertNode(nativeRenderer, atom, context);
1333
- if (type === 'element') {
1334
- const childContext = {
1335
- isParent: true,
1336
- host: nativeNode,
1337
- rootHost: context.rootHost
1338
- };
1339
- let child = atom.child;
1340
- while (child) {
1341
- buildView(nativeRenderer, parentComponent, child, childContext);
1342
- child = child.sibling;
1343
- }
1344
- }
1345
- context.host = nativeNode;
1346
- context.isParent = false;
1347
- if (applyRefs) {
1348
- applyRefs();
1349
- }
1322
+ createTextNode(nativeRenderer, atom, context);
1323
+ }
1324
+ }
1325
+ function buildElementChildren(atom, nativeRenderer, parentComponent, context) {
1326
+ const childContext = {
1327
+ isParent: true,
1328
+ host: atom.nativeNode,
1329
+ rootHost: context.rootHost
1330
+ };
1331
+ let child = atom.child;
1332
+ while (child) {
1333
+ buildView(nativeRenderer, parentComponent, child, childContext);
1334
+ child = child.sibling;
1350
1335
  }
1351
1336
  }
1352
1337
  function updateView(nativeRenderer, component) {
@@ -1364,14 +1349,14 @@ function updateView(nativeRenderer, component) {
1364
1349
  function applyChanges(nativeRenderer, component) {
1365
1350
  const { atom, host, isParent, rootHost } = componentViewCache.get(component);
1366
1351
  const diffAtom = atom.child;
1367
- const template = component.update(component.props, true);
1352
+ const template = component.update(component.props);
1368
1353
  atom.child = createChildChain(template, atom.isSvg);
1369
1354
  const context = {
1370
1355
  host,
1371
1356
  isParent,
1372
1357
  rootHost
1373
1358
  };
1374
- diff(nativeRenderer, component, atom.child, diffAtom, context);
1359
+ diff(nativeRenderer, component, atom.child, diffAtom, context, false);
1375
1360
  const next = atom.sibling;
1376
1361
  if (next && next.jsxNode instanceof Component) {
1377
1362
  const view = componentViewCache.get(next.jsxNode);
@@ -1379,7 +1364,7 @@ function applyChanges(nativeRenderer, component) {
1379
1364
  view.isParent = context.isParent;
1380
1365
  }
1381
1366
  }
1382
- function diff(nativeRenderer, parentComponent, newAtom, oldAtom, context) {
1367
+ function diff(nativeRenderer, parentComponent, newAtom, oldAtom, context, needMove) {
1383
1368
  const commits = [];
1384
1369
  function changeOffset() {
1385
1370
  offset++;
@@ -1404,34 +1389,24 @@ function diff(nativeRenderer, parentComponent, newAtom, oldAtom, context) {
1404
1389
  }
1405
1390
  break;
1406
1391
  }
1407
- commit(offset);
1392
+ commit(offset, needMove);
1408
1393
  }
1409
1394
  }
1410
1395
  function createChanges(newAtom, oldAtom, nativeRenderer, commits, context, parentComponent, effect) {
1411
1396
  const startDiffAtom = oldAtom;
1412
- const { jsxNode: newJsxNode, type } = newAtom;
1413
- const key = newJsxNode.key;
1414
1397
  let prev = null;
1415
1398
  while (oldAtom) {
1416
- const diffIndex = oldAtom.index;
1417
- if (type === oldAtom.type) {
1399
+ const newAtomType = newAtom.type;
1400
+ if (oldAtom.type === newAtomType && oldAtom.nodeType === newAtom.nodeType && oldAtom.key === newAtom.key) {
1418
1401
  let commit;
1419
- if (type === 'text') {
1402
+ if (newAtomType === TextAtomType) {
1420
1403
  commit = updateText(newAtom, oldAtom, nativeRenderer, context);
1421
1404
  }
1405
+ else if (newAtomType === ComponentAtomType) {
1406
+ commit = updateComponent(newAtom, oldAtom, nativeRenderer, context);
1407
+ }
1422
1408
  else {
1423
- const { key: diffKey, type: diffType } = oldAtom.jsxNode;
1424
- if (diffKey !== key || newJsxNode.type !== diffType) {
1425
- prev = oldAtom;
1426
- oldAtom = oldAtom.sibling;
1427
- continue;
1428
- }
1429
- if (type === 'component') {
1430
- commit = updateComponent(newAtom, oldAtom, newAtom.index, diffIndex, nativeRenderer, context);
1431
- }
1432
- else {
1433
- commit = updateElement(newAtom, oldAtom, newAtom.index, diffIndex, nativeRenderer, context, parentComponent);
1434
- }
1409
+ commit = updateElement(newAtom, oldAtom, nativeRenderer, context, parentComponent);
1435
1410
  }
1436
1411
  commits.push(commit);
1437
1412
  const next = oldAtom.sibling;
@@ -1454,49 +1429,29 @@ function createNewView(start, nativeRenderer, context, parentComponent, effect)
1454
1429
  };
1455
1430
  }
1456
1431
  function updateText(newAtom, oldAtom, nativeRenderer, context) {
1457
- return function () {
1432
+ return function (offset, needMove) {
1458
1433
  const nativeNode = oldAtom.nativeNode;
1459
- if (newAtom.jsxNode !== oldAtom.jsxNode) {
1460
- nativeRenderer.syncTextContent(nativeNode, newAtom.jsxNode, newAtom.isSvg);
1461
- }
1462
1434
  newAtom.nativeNode = nativeNode;
1435
+ if (needMove || newAtom.index - offset !== oldAtom.index) {
1436
+ insertNode(nativeRenderer, newAtom, context);
1437
+ }
1463
1438
  context.host = nativeNode;
1464
1439
  context.isParent = false;
1465
1440
  };
1466
1441
  }
1467
- function updateElement(newAtom, oldAtom, expectIndex, oldIndex, nativeRenderer, context, parentComponent) {
1468
- return function (offset) {
1442
+ function updateElement(newAtom, oldAtom, nativeRenderer, context, parentComponent) {
1443
+ return function (offset, needMove) {
1469
1444
  newAtom.nativeNode = oldAtom.nativeNode;
1470
- if (expectIndex - offset !== oldIndex) {
1445
+ if (needMove || newAtom.index - offset !== oldAtom.index) {
1471
1446
  insertNode(nativeRenderer, newAtom, context);
1472
1447
  }
1473
1448
  context.host = newAtom.nativeNode;
1474
1449
  context.isParent = false;
1475
- if (newAtom.jsxNode === oldAtom.jsxNode) {
1476
- newAtom.child = oldAtom.child;
1477
- return;
1478
- }
1479
- const applyRefs = updateNativeNodeProperties(nativeRenderer, newAtom.jsxNode, oldAtom.jsxNode, newAtom.nativeNode, newAtom.isSvg);
1480
- if (newAtom.child) {
1481
- diff(nativeRenderer, parentComponent, newAtom.child, oldAtom.child, {
1482
- host: newAtom.nativeNode,
1483
- isParent: true,
1484
- rootHost: context.rootHost
1485
- });
1486
- }
1487
- else if (oldAtom.child) {
1488
- let atom = oldAtom.child;
1489
- nativeRenderer.cleanChildren(oldAtom.nativeNode, oldAtom.isSvg);
1490
- while (atom) {
1491
- cleanView(nativeRenderer, atom, false);
1492
- atom = atom.sibling;
1493
- }
1494
- }
1495
- applyRefs();
1450
+ updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComponent, context);
1496
1451
  };
1497
1452
  }
1498
- function updateComponent(newAtom, reusedAtom, expectIndex, oldIndex, nativeRenderer, context) {
1499
- return function (offset) {
1453
+ function updateComponent(newAtom, reusedAtom, nativeRenderer, context) {
1454
+ return function (offset, needMove) {
1500
1455
  const component = reusedAtom.jsxNode;
1501
1456
  const newProps = newAtom.jsxNode.props;
1502
1457
  const oldTemplate = component.template;
@@ -1506,15 +1461,16 @@ function updateComponent(newAtom, reusedAtom, expectIndex, oldIndex, nativeRende
1506
1461
  componentViewCache.set(component, Object.assign({ atom: newAtom }, context));
1507
1462
  newAtom.jsxNode = component;
1508
1463
  if (newTemplate === oldTemplate) {
1509
- reuseComponentView(nativeRenderer, newAtom, reusedAtom, context, expectIndex - offset !== oldIndex);
1510
- updateView(nativeRenderer, component);
1464
+ newAtom.child = reusedAtom.child;
1465
+ reuseComponentView(nativeRenderer, newAtom.child, context, needMove || newAtom.index - offset !== reusedAtom.index);
1466
+ component.rendered();
1511
1467
  return;
1512
1468
  }
1513
1469
  if (newTemplate) {
1514
1470
  newAtom.child = createChildChain(newTemplate, newAtom.isSvg);
1515
1471
  }
1516
1472
  if (newAtom.child) {
1517
- diff(nativeRenderer, component, newAtom.child, reusedAtom.child, context);
1473
+ diff(nativeRenderer, component, newAtom.child, reusedAtom.child, context, needMove || newAtom.index - offset !== reusedAtom.index);
1518
1474
  }
1519
1475
  else if (reusedAtom.child) {
1520
1476
  let atom = reusedAtom.child;
@@ -1526,9 +1482,7 @@ function updateComponent(newAtom, reusedAtom, expectIndex, oldIndex, nativeRende
1526
1482
  component.rendered();
1527
1483
  };
1528
1484
  }
1529
- function reuseComponentView(nativeRenderer, newAtom, reusedAtom, context, moveView) {
1530
- let child = reusedAtom.child;
1531
- newAtom.child = child;
1485
+ function reuseComponentView(nativeRenderer, child, context, moveView) {
1532
1486
  const updateContext = (atom) => {
1533
1487
  if (atom.jsxNode instanceof Component) {
1534
1488
  let child = atom.child;
@@ -1550,13 +1504,21 @@ function reuseComponentView(nativeRenderer, newAtom, reusedAtom, context, moveVi
1550
1504
  child = child.sibling;
1551
1505
  }
1552
1506
  }
1507
+ function cleanElementChildren(atom, nativeRenderer) {
1508
+ let child = atom.child;
1509
+ nativeRenderer.cleanChildren(atom.nativeNode, atom.isSvg);
1510
+ while (child) {
1511
+ cleanView(nativeRenderer, child, false);
1512
+ child = child.sibling;
1513
+ }
1514
+ }
1553
1515
  function cleanView(nativeRenderer, atom, needClean) {
1554
1516
  if (atom.nativeNode) {
1555
1517
  if (needClean) {
1556
1518
  nativeRenderer.remove(atom.nativeNode, atom.isSvg);
1557
1519
  needClean = false;
1558
1520
  }
1559
- if (atom.type === 'element') {
1521
+ if (atom.type === ElementAtomType) {
1560
1522
  const ref = atom.jsxNode.props[refKey];
1561
1523
  applyRefs(ref, atom.nativeNode, false);
1562
1524
  }
@@ -1585,52 +1547,26 @@ function componentRender(nativeRenderer, component, from, context) {
1585
1547
  }
1586
1548
  component.rendered();
1587
1549
  }
1588
- function createChainByJSXComponent(jsxNode, prevAtom, isSvg) {
1589
- const atom = {
1590
- type: 'component',
1591
- index: prevAtom.index + 1,
1592
- jsxNode,
1593
- sibling: null,
1594
- child: null,
1595
- nativeNode: null,
1596
- isSvg
1597
- };
1598
- prevAtom.sibling = atom;
1599
- return atom;
1600
- }
1601
- function createChainByJSXText(jsxNode, prevAtom, isSvg) {
1550
+ function createChainByJSXNode(type, jsxNode, nodeType, prevAtom, isSvg, key) {
1602
1551
  const atom = {
1603
- type: 'text',
1552
+ type,
1604
1553
  index: prevAtom.index + 1,
1605
1554
  jsxNode,
1606
1555
  sibling: null,
1607
1556
  child: null,
1608
1557
  nativeNode: null,
1609
- isSvg
1558
+ isSvg,
1559
+ nodeType,
1560
+ key
1610
1561
  };
1611
1562
  prevAtom.sibling = atom;
1612
1563
  return atom;
1613
1564
  }
1614
- function createChainByJSXElement(element, prevAtom, isSvg) {
1615
- isSvg = isSvg || element.type === 'svg';
1616
- const atom = {
1617
- type: 'element',
1618
- index: prevAtom.index + 1,
1619
- jsxNode: element,
1620
- sibling: null,
1621
- child: null,
1622
- nativeNode: null,
1623
- isSvg
1624
- };
1625
- prevAtom.sibling = atom;
1626
- atom.child = createChildChain(element.props.children, isSvg);
1627
- return atom;
1628
- }
1629
1565
  function createChainByNode(jsxNode, prevAtom, isSvg) {
1630
1566
  const type = typeof jsxNode;
1631
1567
  if (jsxNode !== null && type !== 'undefined' && type !== 'boolean') {
1632
1568
  if (typeof jsxNode === 'string') {
1633
- return createChainByJSXText(jsxNode, prevAtom, isSvg);
1569
+ return createChainByJSXNode(TextAtomType, jsxNode, jsxNode, prevAtom, isSvg);
1634
1570
  }
1635
1571
  if (Array.isArray(jsxNode)) {
1636
1572
  return createChainByChildren(jsxNode, prevAtom, isSvg);
@@ -1638,13 +1574,14 @@ function createChainByNode(jsxNode, prevAtom, isSvg) {
1638
1574
  if (type === 'object') {
1639
1575
  const nodeType = typeof jsxNode.type;
1640
1576
  if (nodeType === 'string') {
1641
- return createChainByJSXElement(jsxNode, prevAtom, isSvg);
1577
+ return createChainByJSXNode(ElementAtomType, jsxNode, jsxNode.type, prevAtom, isSvg || jsxNode.type === 'svg', jsxNode.key);
1642
1578
  }
1643
1579
  else if (nodeType === 'function') {
1644
- return createChainByJSXComponent(jsxNode, prevAtom, isSvg);
1580
+ return createChainByJSXNode(ComponentAtomType, jsxNode, jsxNode.type, prevAtom, isSvg, jsxNode.key);
1645
1581
  }
1646
1582
  }
1647
- return createChainByJSXText(String(jsxNode), prevAtom, isSvg);
1583
+ const text = String(jsxNode);
1584
+ return createChainByJSXNode(TextAtomType, text, text, prevAtom, isSvg);
1648
1585
  }
1649
1586
  return prevAtom;
1650
1587
  }
@@ -1672,12 +1609,14 @@ function insertNode(nativeRenderer, atom, context) {
1672
1609
  nativeRenderer.insertAfter(atom.nativeNode, context.host, atom.isSvg);
1673
1610
  }
1674
1611
  }
1675
- function createElement(nativeRenderer, vNode, isSvg) {
1676
- const nativeNode = nativeRenderer.createElement(vNode.type, isSvg);
1677
- const props = vNode.props;
1612
+ function createElement(nativeRenderer, atom, parentComponent, context) {
1613
+ const { isSvg, jsxNode } = atom;
1614
+ const nativeNode = nativeRenderer.createElement(jsxNode.type, isSvg);
1615
+ const props = jsxNode.props;
1678
1616
  let bindingRefs;
1679
1617
  for (const key in props) {
1680
1618
  if (key === 'children') {
1619
+ atom.child = createChildChain(jsxNode.props.children, isSvg);
1681
1620
  continue;
1682
1621
  }
1683
1622
  if (key === 'class') {
@@ -1697,7 +1636,7 @@ function createElement(nativeRenderer, vNode, isSvg) {
1697
1636
  if (listenerReg.test(key)) {
1698
1637
  const listener = props[key];
1699
1638
  if (typeof listener === 'function') {
1700
- bindEvent(nativeRenderer, vNode, key, nativeNode, listener, isSvg);
1639
+ nativeRenderer.listen(nativeNode, key, listener, isSvg);
1701
1640
  }
1702
1641
  continue;
1703
1642
  }
@@ -1707,21 +1646,32 @@ function createElement(nativeRenderer, vNode, isSvg) {
1707
1646
  }
1708
1647
  nativeRenderer.setProperty(nativeNode, key, props[key], isSvg);
1709
1648
  }
1710
- return {
1711
- nativeNode,
1712
- applyRefs: () => {
1713
- applyRefs(bindingRefs, nativeNode, true);
1714
- }
1715
- };
1716
- }
1717
- function createTextNode(nativeRenderer, text, isSvg) {
1718
- return nativeRenderer.createTextNode(text, isSvg);
1719
- }
1720
- function updateNativeNodeProperties(nativeRenderer, newVNode, oldVNode, nativeNode, isSvg) {
1649
+ atom.nativeNode = nativeNode;
1650
+ insertNode(nativeRenderer, atom, context);
1651
+ buildElementChildren(atom, nativeRenderer, parentComponent, context);
1652
+ context.host = nativeNode;
1653
+ context.isParent = false;
1654
+ applyRefs(bindingRefs, nativeNode, true);
1655
+ }
1656
+ function createTextNode(nativeRenderer, atom, context) {
1657
+ const nativeNode = nativeRenderer.createTextNode(atom.jsxNode, atom.isSvg);
1658
+ atom.nativeNode = nativeNode;
1659
+ insertNode(nativeRenderer, atom, context);
1660
+ context.host = nativeNode;
1661
+ context.isParent = false;
1662
+ }
1663
+ function updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComponent, context) {
1664
+ const newVNode = newAtom.jsxNode;
1665
+ const isSvg = newAtom.isSvg;
1666
+ const nativeNode = newAtom.nativeNode;
1667
+ const oldVNode = oldAtom.jsxNode;
1668
+ if (newVNode === oldVNode) {
1669
+ updateElementChildren(newAtom, oldAtom, nativeRenderer, parentComponent, context, isSvg);
1670
+ return;
1671
+ }
1721
1672
  const changes = getObjectChanges(newVNode.props, oldVNode.props);
1722
1673
  let unBindRefs;
1723
1674
  let bindRefs;
1724
- newVNode.on = oldVNode.on;
1725
1675
  for (const [key, value] of changes.remove) {
1726
1676
  if (key === 'children') {
1727
1677
  continue;
@@ -1738,10 +1688,7 @@ function updateNativeNodeProperties(nativeRenderer, newVNode, oldVNode, nativeNo
1738
1688
  }
1739
1689
  if (listenerReg.test(key)) {
1740
1690
  if (typeof value === 'function') {
1741
- const type = key.replace(listenerReg, '').toLowerCase();
1742
- const oldOn = oldVNode.on;
1743
- nativeRenderer.unListen(nativeNode, type, oldOn[type].delegate, isSvg);
1744
- Reflect.deleteProperty(oldOn, type);
1691
+ nativeRenderer.unListen(nativeNode, key, value, isSvg);
1745
1692
  }
1746
1693
  continue;
1747
1694
  }
@@ -1774,8 +1721,8 @@ function updateNativeNodeProperties(nativeRenderer, newVNode, oldVNode, nativeNo
1774
1721
  continue;
1775
1722
  }
1776
1723
  if (listenerReg.test(key)) {
1777
- const listenType = key.replace(listenerReg, '').toLowerCase();
1778
- newVNode.on[listenType].listenFn = newValue;
1724
+ nativeRenderer.unListen(nativeNode, key, oldValue, isSvg);
1725
+ nativeRenderer.listen(nativeNode, key, newValue, isSvg);
1779
1726
  continue;
1780
1727
  }
1781
1728
  if (key === refKey) {
@@ -1802,7 +1749,7 @@ function updateNativeNodeProperties(nativeRenderer, newVNode, oldVNode, nativeNo
1802
1749
  }
1803
1750
  if (listenerReg.test(key)) {
1804
1751
  if (typeof value === 'function') {
1805
- bindEvent(nativeRenderer, newVNode, key, nativeNode, value, isSvg);
1752
+ nativeRenderer.listen(nativeNode, key, value, isSvg);
1806
1753
  }
1807
1754
  continue;
1808
1755
  }
@@ -1812,10 +1759,39 @@ function updateNativeNodeProperties(nativeRenderer, newVNode, oldVNode, nativeNo
1812
1759
  }
1813
1760
  nativeRenderer.setProperty(nativeNode, key, value, isSvg);
1814
1761
  }
1815
- return () => {
1816
- applyRefs(unBindRefs, nativeNode, false);
1817
- applyRefs(bindRefs, nativeNode, true);
1818
- };
1762
+ updateElementChildren(newAtom, oldAtom, nativeRenderer, parentComponent, context, isSvg);
1763
+ applyRefs(unBindRefs, nativeNode, false);
1764
+ applyRefs(bindRefs, nativeNode, true);
1765
+ }
1766
+ function updateElementChildren(newAtom, oldAtom, nativeRenderer, parentComponent, context, isSvg) {
1767
+ /**
1768
+ * 不能仅依赖 children 是否相等的判断来确定是否要继续向下 diff
1769
+ * 如:
1770
+ * ```tsx
1771
+ * <Comp>
1772
+ * <div>
1773
+ * {props.children}
1774
+ * </div>
1775
+ * </Comp>
1776
+ * ```
1777
+ * 其中当 Comp 产生变化时,children 来自父组件,这时 children 是相等的,
1778
+ * 但,children 内可能有子组件也发生了变化,如果不继续 diff,那么,子组件
1779
+ * 的视图更新将不会发生
1780
+ */
1781
+ newAtom.child = createChildChain(newAtom.jsxNode.props.children, isSvg);
1782
+ if (!newAtom.child) {
1783
+ // 防止删除用户手动添加的元素
1784
+ if (oldAtom.child) {
1785
+ cleanElementChildren(oldAtom, nativeRenderer);
1786
+ }
1787
+ }
1788
+ else {
1789
+ diff(nativeRenderer, parentComponent, newAtom.child, oldAtom.child, {
1790
+ host: newAtom.nativeNode,
1791
+ isParent: true,
1792
+ rootHost: context.rootHost
1793
+ }, false);
1794
+ }
1819
1795
  }
1820
1796
  function applyRefs(refs, nativeNode, binding) {
1821
1797
  if (refs) {
@@ -1827,21 +1803,6 @@ function applyRefs(refs, nativeNode, binding) {
1827
1803
  }
1828
1804
  }
1829
1805
  }
1830
- function bindEvent(nativeRenderer, vNode, key, nativeNode, listenFn, isSvg) {
1831
- let on = vNode.on;
1832
- if (!on) {
1833
- vNode.on = on = {};
1834
- }
1835
- const type = key.replace(listenerReg, '').toLowerCase();
1836
- const delegateObj = {
1837
- delegate(...args) {
1838
- return delegateObj.listenFn.apply(this, args);
1839
- },
1840
- listenFn
1841
- };
1842
- on[type] = delegateObj;
1843
- nativeRenderer.listen(nativeNode, type, delegateObj.delegate, isSvg);
1844
- }
1845
1806
 
1846
1807
  /**
1847
1808
  * Viewfly 根组件,用于实现组件状态更新事件通知