@viewfly/core 1.0.0-alpha.8 → 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,45 +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
- const applyRefs = updateNativeNodeProperties(nativeRenderer, newAtom.jsxNode, oldAtom.jsxNode, newAtom.nativeNode, newAtom.isSvg);
1476
- if (newAtom.child) {
1477
- diff(nativeRenderer, parentComponent, newAtom.child, oldAtom.child, {
1478
- host: newAtom.nativeNode,
1479
- isParent: true,
1480
- rootHost: context.rootHost
1481
- });
1482
- }
1483
- else if (oldAtom.child) {
1484
- let atom = oldAtom.child;
1485
- nativeRenderer.cleanChildren(oldAtom.nativeNode, oldAtom.isSvg);
1486
- while (atom) {
1487
- cleanView(nativeRenderer, atom, false);
1488
- atom = atom.sibling;
1489
- }
1490
- }
1491
- applyRefs();
1450
+ updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComponent, context);
1492
1451
  };
1493
1452
  }
1494
- function updateComponent(newAtom, reusedAtom, expectIndex, oldIndex, nativeRenderer, context) {
1495
- return function (offset) {
1453
+ function updateComponent(newAtom, reusedAtom, nativeRenderer, context) {
1454
+ return function (offset, needMove) {
1496
1455
  const component = reusedAtom.jsxNode;
1497
1456
  const newProps = newAtom.jsxNode.props;
1498
1457
  const oldTemplate = component.template;
@@ -1502,15 +1461,16 @@ function updateComponent(newAtom, reusedAtom, expectIndex, oldIndex, nativeRende
1502
1461
  componentViewCache.set(component, Object.assign({ atom: newAtom }, context));
1503
1462
  newAtom.jsxNode = component;
1504
1463
  if (newTemplate === oldTemplate) {
1505
- reuseComponentView(nativeRenderer, newAtom, reusedAtom, context, expectIndex - offset !== oldIndex);
1506
- updateView(nativeRenderer, component);
1464
+ newAtom.child = reusedAtom.child;
1465
+ reuseComponentView(nativeRenderer, newAtom.child, context, needMove || newAtom.index - offset !== reusedAtom.index);
1466
+ component.rendered();
1507
1467
  return;
1508
1468
  }
1509
1469
  if (newTemplate) {
1510
1470
  newAtom.child = createChildChain(newTemplate, newAtom.isSvg);
1511
1471
  }
1512
1472
  if (newAtom.child) {
1513
- diff(nativeRenderer, component, newAtom.child, reusedAtom.child, context);
1473
+ diff(nativeRenderer, component, newAtom.child, reusedAtom.child, context, needMove || newAtom.index - offset !== reusedAtom.index);
1514
1474
  }
1515
1475
  else if (reusedAtom.child) {
1516
1476
  let atom = reusedAtom.child;
@@ -1522,9 +1482,7 @@ function updateComponent(newAtom, reusedAtom, expectIndex, oldIndex, nativeRende
1522
1482
  component.rendered();
1523
1483
  };
1524
1484
  }
1525
- function reuseComponentView(nativeRenderer, newAtom, reusedAtom, context, moveView) {
1526
- let child = reusedAtom.child;
1527
- newAtom.child = child;
1485
+ function reuseComponentView(nativeRenderer, child, context, moveView) {
1528
1486
  const updateContext = (atom) => {
1529
1487
  if (atom.jsxNode instanceof Component) {
1530
1488
  let child = atom.child;
@@ -1546,13 +1504,21 @@ function reuseComponentView(nativeRenderer, newAtom, reusedAtom, context, moveVi
1546
1504
  child = child.sibling;
1547
1505
  }
1548
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
+ }
1549
1515
  function cleanView(nativeRenderer, atom, needClean) {
1550
1516
  if (atom.nativeNode) {
1551
1517
  if (needClean) {
1552
1518
  nativeRenderer.remove(atom.nativeNode, atom.isSvg);
1553
1519
  needClean = false;
1554
1520
  }
1555
- if (atom.type === 'element') {
1521
+ if (atom.type === ElementAtomType) {
1556
1522
  const ref = atom.jsxNode.props[refKey];
1557
1523
  applyRefs(ref, atom.nativeNode, false);
1558
1524
  }
@@ -1581,52 +1547,26 @@ function componentRender(nativeRenderer, component, from, context) {
1581
1547
  }
1582
1548
  component.rendered();
1583
1549
  }
1584
- function createChainByJSXComponent(jsxNode, prevAtom, isSvg) {
1550
+ function createChainByJSXNode(type, jsxNode, nodeType, prevAtom, isSvg, key) {
1585
1551
  const atom = {
1586
- type: 'component',
1552
+ type,
1587
1553
  index: prevAtom.index + 1,
1588
1554
  jsxNode,
1589
1555
  sibling: null,
1590
1556
  child: null,
1591
1557
  nativeNode: null,
1592
- isSvg
1593
- };
1594
- prevAtom.sibling = atom;
1595
- return atom;
1596
- }
1597
- function createChainByJSXText(jsxNode, prevAtom, isSvg) {
1598
- const atom = {
1599
- type: 'text',
1600
- index: prevAtom.index + 1,
1601
- jsxNode,
1602
- sibling: null,
1603
- child: null,
1604
- nativeNode: null,
1605
- isSvg
1606
- };
1607
- prevAtom.sibling = atom;
1608
- return atom;
1609
- }
1610
- function createChainByJSXElement(element, prevAtom, isSvg) {
1611
- isSvg = isSvg || element.type === 'svg';
1612
- const atom = {
1613
- type: 'element',
1614
- index: prevAtom.index + 1,
1615
- jsxNode: element,
1616
- sibling: null,
1617
- child: null,
1618
- nativeNode: null,
1619
- isSvg
1558
+ isSvg,
1559
+ nodeType,
1560
+ key
1620
1561
  };
1621
1562
  prevAtom.sibling = atom;
1622
- atom.child = createChildChain(element.props.children, isSvg);
1623
1563
  return atom;
1624
1564
  }
1625
1565
  function createChainByNode(jsxNode, prevAtom, isSvg) {
1626
1566
  const type = typeof jsxNode;
1627
1567
  if (jsxNode !== null && type !== 'undefined' && type !== 'boolean') {
1628
1568
  if (typeof jsxNode === 'string') {
1629
- return createChainByJSXText(jsxNode, prevAtom, isSvg);
1569
+ return createChainByJSXNode(TextAtomType, jsxNode, jsxNode, prevAtom, isSvg);
1630
1570
  }
1631
1571
  if (Array.isArray(jsxNode)) {
1632
1572
  return createChainByChildren(jsxNode, prevAtom, isSvg);
@@ -1634,13 +1574,14 @@ function createChainByNode(jsxNode, prevAtom, isSvg) {
1634
1574
  if (type === 'object') {
1635
1575
  const nodeType = typeof jsxNode.type;
1636
1576
  if (nodeType === 'string') {
1637
- return createChainByJSXElement(jsxNode, prevAtom, isSvg);
1577
+ return createChainByJSXNode(ElementAtomType, jsxNode, jsxNode.type, prevAtom, isSvg || jsxNode.type === 'svg', jsxNode.key);
1638
1578
  }
1639
1579
  else if (nodeType === 'function') {
1640
- return createChainByJSXComponent(jsxNode, prevAtom, isSvg);
1580
+ return createChainByJSXNode(ComponentAtomType, jsxNode, jsxNode.type, prevAtom, isSvg, jsxNode.key);
1641
1581
  }
1642
1582
  }
1643
- return createChainByJSXText(String(jsxNode), prevAtom, isSvg);
1583
+ const text = String(jsxNode);
1584
+ return createChainByJSXNode(TextAtomType, text, text, prevAtom, isSvg);
1644
1585
  }
1645
1586
  return prevAtom;
1646
1587
  }
@@ -1668,12 +1609,14 @@ function insertNode(nativeRenderer, atom, context) {
1668
1609
  nativeRenderer.insertAfter(atom.nativeNode, context.host, atom.isSvg);
1669
1610
  }
1670
1611
  }
1671
- function createElement(nativeRenderer, vNode, isSvg) {
1672
- const nativeNode = nativeRenderer.createElement(vNode.type, isSvg);
1673
- 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;
1674
1616
  let bindingRefs;
1675
1617
  for (const key in props) {
1676
1618
  if (key === 'children') {
1619
+ atom.child = createChildChain(jsxNode.props.children, isSvg);
1677
1620
  continue;
1678
1621
  }
1679
1622
  if (key === 'class') {
@@ -1693,7 +1636,7 @@ function createElement(nativeRenderer, vNode, isSvg) {
1693
1636
  if (listenerReg.test(key)) {
1694
1637
  const listener = props[key];
1695
1638
  if (typeof listener === 'function') {
1696
- bindEvent(nativeRenderer, vNode, key, nativeNode, listener, isSvg);
1639
+ nativeRenderer.listen(nativeNode, key, listener, isSvg);
1697
1640
  }
1698
1641
  continue;
1699
1642
  }
@@ -1703,21 +1646,32 @@ function createElement(nativeRenderer, vNode, isSvg) {
1703
1646
  }
1704
1647
  nativeRenderer.setProperty(nativeNode, key, props[key], isSvg);
1705
1648
  }
1706
- return {
1707
- nativeNode,
1708
- applyRefs: () => {
1709
- applyRefs(bindingRefs, nativeNode, true);
1710
- }
1711
- };
1712
- }
1713
- function createTextNode(nativeRenderer, text, isSvg) {
1714
- return nativeRenderer.createTextNode(text, isSvg);
1715
- }
1716
- 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
+ }
1717
1672
  const changes = getObjectChanges(newVNode.props, oldVNode.props);
1718
1673
  let unBindRefs;
1719
1674
  let bindRefs;
1720
- newVNode.on = oldVNode.on;
1721
1675
  for (const [key, value] of changes.remove) {
1722
1676
  if (key === 'children') {
1723
1677
  continue;
@@ -1734,10 +1688,7 @@ function updateNativeNodeProperties(nativeRenderer, newVNode, oldVNode, nativeNo
1734
1688
  }
1735
1689
  if (listenerReg.test(key)) {
1736
1690
  if (typeof value === 'function') {
1737
- const type = key.replace(listenerReg, '').toLowerCase();
1738
- const oldOn = oldVNode.on;
1739
- nativeRenderer.unListen(nativeNode, type, oldOn[type].delegate, isSvg);
1740
- Reflect.deleteProperty(oldOn, type);
1691
+ nativeRenderer.unListen(nativeNode, key, value, isSvg);
1741
1692
  }
1742
1693
  continue;
1743
1694
  }
@@ -1770,8 +1721,8 @@ function updateNativeNodeProperties(nativeRenderer, newVNode, oldVNode, nativeNo
1770
1721
  continue;
1771
1722
  }
1772
1723
  if (listenerReg.test(key)) {
1773
- const listenType = key.replace(listenerReg, '').toLowerCase();
1774
- newVNode.on[listenType].listenFn = newValue;
1724
+ nativeRenderer.unListen(nativeNode, key, oldValue, isSvg);
1725
+ nativeRenderer.listen(nativeNode, key, newValue, isSvg);
1775
1726
  continue;
1776
1727
  }
1777
1728
  if (key === refKey) {
@@ -1798,7 +1749,7 @@ function updateNativeNodeProperties(nativeRenderer, newVNode, oldVNode, nativeNo
1798
1749
  }
1799
1750
  if (listenerReg.test(key)) {
1800
1751
  if (typeof value === 'function') {
1801
- bindEvent(nativeRenderer, newVNode, key, nativeNode, value, isSvg);
1752
+ nativeRenderer.listen(nativeNode, key, value, isSvg);
1802
1753
  }
1803
1754
  continue;
1804
1755
  }
@@ -1808,10 +1759,39 @@ function updateNativeNodeProperties(nativeRenderer, newVNode, oldVNode, nativeNo
1808
1759
  }
1809
1760
  nativeRenderer.setProperty(nativeNode, key, value, isSvg);
1810
1761
  }
1811
- return () => {
1812
- applyRefs(unBindRefs, nativeNode, false);
1813
- applyRefs(bindRefs, nativeNode, true);
1814
- };
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
+ }
1815
1795
  }
1816
1796
  function applyRefs(refs, nativeNode, binding) {
1817
1797
  if (refs) {
@@ -1823,21 +1803,6 @@ function applyRefs(refs, nativeNode, binding) {
1823
1803
  }
1824
1804
  }
1825
1805
  }
1826
- function bindEvent(nativeRenderer, vNode, key, nativeNode, listenFn, isSvg) {
1827
- let on = vNode.on;
1828
- if (!on) {
1829
- vNode.on = on = {};
1830
- }
1831
- const type = key.replace(listenerReg, '').toLowerCase();
1832
- const delegateObj = {
1833
- delegate(...args) {
1834
- return delegateObj.listenFn.apply(this, args);
1835
- },
1836
- listenFn
1837
- };
1838
- on[type] = delegateObj;
1839
- nativeRenderer.listen(nativeNode, type, delegateObj.delegate, isSvg);
1840
- }
1841
1806
 
1842
1807
  /**
1843
1808
  * Viewfly 根组件,用于实现组件状态更新事件通知