vnode.js 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. import _extends from "@babel/runtime/helpers/esm/extends";
  2. import { filterEmpty } from './props-util';
  3. import { cloneVNode, isVNode, Comment, Fragment, render as VueRender } from 'vue';
  4. import warning from './warning';
  5. export function cloneElement(vnode) {
  6. let nodeProps = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  7. let override = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
  8. let mergeRef = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
  9. let ele = vnode;
  10. if (Array.isArray(vnode)) {
  11. ele = filterEmpty(vnode)[0];
  12. }
  13. if (!ele) {
  14. return null;
  15. }
  16. const node = cloneVNode(ele, nodeProps, mergeRef);
  17. // cloneVNode内部是合并属性,这里改成覆盖属性
  18. node.props = override ? _extends(_extends({}, node.props), nodeProps) : node.props;
  19. warning(typeof node.props.class !== 'object', 'class must be string');
  20. return node;
  21. }
  22. export function cloneVNodes(vnodes) {
  23. let nodeProps = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  24. let override = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
  25. return vnodes.map(vnode => cloneElement(vnode, nodeProps, override));
  26. }
  27. export function deepCloneElement(vnode) {
  28. let nodeProps = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  29. let override = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
  30. let mergeRef = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
  31. if (Array.isArray(vnode)) {
  32. return vnode.map(item => deepCloneElement(item, nodeProps, override, mergeRef));
  33. } else {
  34. // 需要判断是否为vnode方可进行clone操作
  35. if (!isVNode(vnode)) {
  36. return vnode;
  37. }
  38. const cloned = cloneElement(vnode, nodeProps, override, mergeRef);
  39. if (Array.isArray(cloned.children)) {
  40. cloned.children = deepCloneElement(cloned.children);
  41. }
  42. return cloned;
  43. }
  44. }
  45. export function triggerVNodeUpdate(vm, attrs, dom) {
  46. VueRender(cloneVNode(vm, _extends({}, attrs)), dom);
  47. }
  48. const ensureValidVNode = slot => {
  49. return (slot || []).some(child => {
  50. if (!isVNode(child)) return true;
  51. if (child.type === Comment) return false;
  52. if (child.type === Fragment && !ensureValidVNode(child.children)) return false;
  53. return true;
  54. }) ? slot : null;
  55. };
  56. export function customRenderSlot(slots, name, props, fallback) {
  57. var _a;
  58. const slot = (_a = slots[name]) === null || _a === void 0 ? void 0 : _a.call(slots, props);
  59. if (ensureValidVNode(slot)) {
  60. return slot;
  61. }
  62. return fallback === null || fallback === void 0 ? void 0 : fallback();
  63. }