vue 3.2.22 → 3.2.26

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.
@@ -107,7 +107,7 @@ const specialBooleanAttrs = `itemscope,allowfullscreen,formnovalidate,ismap,nomo
107
107
  const isSpecialBooleanAttr = /*#__PURE__*/ makeMap(specialBooleanAttrs);
108
108
  /**
109
109
  * Boolean attributes should be included if the value is truthy or ''.
110
- * e.g. <select multiple> compiles to { multiple: '' }
110
+ * e.g. `<select multiple>` compiles to `{ multiple: '' }`
111
111
  */
112
112
  function includeBooleanAttr(value) {
113
113
  return !!value || value === '';
@@ -341,7 +341,7 @@ const isIntegerKey = (key) => isString(key) &&
341
341
  '' + parseInt(key, 10) === key;
342
342
  const isReservedProp = /*#__PURE__*/ makeMap(
343
343
  // the leading comma is intentional so empty string "" is also included
344
- ',key,ref,' +
344
+ ',key,ref,ref_for,ref_key,' +
345
345
  'onVnodeBeforeMount,onVnodeMounted,' +
346
346
  'onVnodeBeforeUpdate,onVnodeUpdated,' +
347
347
  'onVnodeBeforeUnmount,onVnodeUnmounted');
@@ -530,7 +530,7 @@ const targetMap = new WeakMap();
530
530
  let effectTrackDepth = 0;
531
531
  let trackOpBit = 1;
532
532
  /**
533
- * The bitwise track markers support at most 30 levels op recursion.
533
+ * The bitwise track markers support at most 30 levels of recursion.
534
534
  * This value is chosen to enable modern JS engines to use a SMI on all platforms.
535
535
  * When recursion depth is greater, fall back to using a full cleanup.
536
536
  */
@@ -851,7 +851,7 @@ const shallowSet = /*#__PURE__*/ createSetter(true);
851
851
  function createSetter(shallow = false) {
852
852
  return function set(target, key, value, receiver) {
853
853
  let oldValue = target[key];
854
- if (!shallow) {
854
+ if (!shallow && !isReadonly(value)) {
855
855
  value = toRaw(value);
856
856
  oldValue = toRaw(oldValue);
857
857
  if (!isArray(target) && isRef(oldValue) && !isRef(value)) {
@@ -1436,21 +1436,25 @@ function toRefs(object) {
1436
1436
  return ret;
1437
1437
  }
1438
1438
  class ObjectRefImpl {
1439
- constructor(_object, _key) {
1439
+ constructor(_object, _key, _defaultValue) {
1440
1440
  this._object = _object;
1441
1441
  this._key = _key;
1442
+ this._defaultValue = _defaultValue;
1442
1443
  this.__v_isRef = true;
1443
1444
  }
1444
1445
  get value() {
1445
- return this._object[this._key];
1446
+ const val = this._object[this._key];
1447
+ return val === undefined ? this._defaultValue : val;
1446
1448
  }
1447
1449
  set value(newVal) {
1448
1450
  this._object[this._key] = newVal;
1449
1451
  }
1450
1452
  }
1451
- function toRef(object, key) {
1453
+ function toRef(object, key, defaultValue) {
1452
1454
  const val = object[key];
1453
- return isRef(val) ? val : new ObjectRefImpl(object, key);
1455
+ return isRef(val)
1456
+ ? val
1457
+ : new ObjectRefImpl(object, key, defaultValue);
1454
1458
  }
1455
1459
 
1456
1460
  class ComputedRefImpl {
@@ -2767,7 +2771,8 @@ const BaseTransitionImpl = {
2767
2771
  const rawProps = toRaw(props);
2768
2772
  const { mode } = rawProps;
2769
2773
  // check mode
2770
- if (mode && !['in-out', 'out-in', 'default'].includes(mode)) {
2774
+ if (mode &&
2775
+ mode !== 'in-out' && mode !== 'out-in' && mode !== 'default') {
2771
2776
  warn$1(`invalid <transition> mode: ${mode}`);
2772
2777
  }
2773
2778
  // at this point children has a guaranteed length of 1.
@@ -3407,7 +3412,7 @@ function registerKeepAliveHook(hook, type, target = currentInstance) {
3407
3412
  }
3408
3413
  current = current.parent;
3409
3414
  }
3410
- hook();
3415
+ return hook();
3411
3416
  });
3412
3417
  injectHook(type, wrappedHook, target);
3413
3418
  // In addition to registering it on the target instance, we walk up the parent
@@ -4069,7 +4074,7 @@ function setFullProps(instance, rawProps, props, attrs) {
4069
4074
  }
4070
4075
  }
4071
4076
  else if (!isEmitListener(instance.emitsOptions, key)) {
4072
- if (value !== attrs[key]) {
4077
+ if (!(key in attrs) || value !== attrs[key]) {
4073
4078
  attrs[key] = value;
4074
4079
  hasAttrsChanged = true;
4075
4080
  }
@@ -4709,6 +4714,102 @@ function createAppAPI(render, hydrate) {
4709
4714
  };
4710
4715
  }
4711
4716
 
4717
+ /**
4718
+ * Function for handling a template ref
4719
+ */
4720
+ function setRef(rawRef, oldRawRef, parentSuspense, vnode, isUnmount = false) {
4721
+ if (isArray(rawRef)) {
4722
+ rawRef.forEach((r, i) => setRef(r, oldRawRef && (isArray(oldRawRef) ? oldRawRef[i] : oldRawRef), parentSuspense, vnode, isUnmount));
4723
+ return;
4724
+ }
4725
+ if (isAsyncWrapper(vnode) && !isUnmount) {
4726
+ // when mounting async components, nothing needs to be done,
4727
+ // because the template ref is forwarded to inner component
4728
+ return;
4729
+ }
4730
+ const refValue = vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */
4731
+ ? getExposeProxy(vnode.component) || vnode.component.proxy
4732
+ : vnode.el;
4733
+ const value = isUnmount ? null : refValue;
4734
+ const { i: owner, r: ref } = rawRef;
4735
+ if (!owner) {
4736
+ warn$1(`Missing ref owner context. ref cannot be used on hoisted vnodes. ` +
4737
+ `A vnode with ref must be created inside the render function.`);
4738
+ return;
4739
+ }
4740
+ const oldRef = oldRawRef && oldRawRef.r;
4741
+ const refs = owner.refs === EMPTY_OBJ ? (owner.refs = {}) : owner.refs;
4742
+ const setupState = owner.setupState;
4743
+ // dynamic ref changed. unset old ref
4744
+ if (oldRef != null && oldRef !== ref) {
4745
+ if (isString(oldRef)) {
4746
+ refs[oldRef] = null;
4747
+ if (hasOwn(setupState, oldRef)) {
4748
+ setupState[oldRef] = null;
4749
+ }
4750
+ }
4751
+ else if (isRef(oldRef)) {
4752
+ oldRef.value = null;
4753
+ }
4754
+ }
4755
+ if (isFunction(ref)) {
4756
+ callWithErrorHandling(ref, owner, 12 /* FUNCTION_REF */, [value, refs]);
4757
+ }
4758
+ else {
4759
+ const _isString = isString(ref);
4760
+ const _isRef = isRef(ref);
4761
+ if (_isString || _isRef) {
4762
+ const doSet = () => {
4763
+ if (rawRef.f) {
4764
+ const existing = _isString ? refs[ref] : ref.value;
4765
+ if (isUnmount) {
4766
+ isArray(existing) && remove(existing, refValue);
4767
+ }
4768
+ else {
4769
+ if (!isArray(existing)) {
4770
+ if (_isString) {
4771
+ refs[ref] = [refValue];
4772
+ }
4773
+ else {
4774
+ ref.value = [refValue];
4775
+ if (rawRef.k)
4776
+ refs[rawRef.k] = ref.value;
4777
+ }
4778
+ }
4779
+ else if (!existing.includes(refValue)) {
4780
+ existing.push(refValue);
4781
+ }
4782
+ }
4783
+ }
4784
+ else if (_isString) {
4785
+ refs[ref] = value;
4786
+ if (hasOwn(setupState, ref)) {
4787
+ setupState[ref] = value;
4788
+ }
4789
+ }
4790
+ else if (isRef(ref)) {
4791
+ ref.value = value;
4792
+ if (rawRef.k)
4793
+ refs[rawRef.k] = value;
4794
+ }
4795
+ else {
4796
+ warn$1('Invalid template ref type:', ref, `(${typeof ref})`);
4797
+ }
4798
+ };
4799
+ if (value) {
4800
+ doSet.id = -1;
4801
+ queuePostRenderEffect(doSet, parentSuspense);
4802
+ }
4803
+ else {
4804
+ doSet();
4805
+ }
4806
+ }
4807
+ else {
4808
+ warn$1('Invalid template ref type:', ref, `(${typeof ref})`);
4809
+ }
4810
+ }
4811
+ }
4812
+
4712
4813
  let hasMismatch = false;
4713
4814
  const isSVGContainer = (container) => /svg/.test(container.namespaceURI) && container.tagName !== 'foreignObject';
4714
4815
  const isComment = (node) => node.nodeType === 8 /* COMMENT */;
@@ -5341,12 +5442,15 @@ function baseCreateRenderer(options, createHydrationFns) {
5341
5442
  const oldProps = n1.props || EMPTY_OBJ;
5342
5443
  const newProps = n2.props || EMPTY_OBJ;
5343
5444
  let vnodeHook;
5445
+ // disable recurse in beforeUpdate hooks
5446
+ parentComponent && toggleRecurse(parentComponent, false);
5344
5447
  if ((vnodeHook = newProps.onVnodeBeforeUpdate)) {
5345
5448
  invokeVNodeHook(vnodeHook, parentComponent, n2, n1);
5346
5449
  }
5347
5450
  if (dirs) {
5348
5451
  invokeDirectiveHook(n2, n1, parentComponent, 'beforeUpdate');
5349
5452
  }
5453
+ parentComponent && toggleRecurse(parentComponent, true);
5350
5454
  if (isHmrUpdating) {
5351
5455
  // HMR updated, force full diff
5352
5456
  patchFlag = 0;
@@ -5626,7 +5730,7 @@ function baseCreateRenderer(options, createHydrationFns) {
5626
5730
  const { el, props } = initialVNode;
5627
5731
  const { bm, m, parent } = instance;
5628
5732
  const isAsyncWrapperVNode = isAsyncWrapper(initialVNode);
5629
- effect.allowRecurse = false;
5733
+ toggleRecurse(instance, false);
5630
5734
  // beforeMount hook
5631
5735
  if (bm) {
5632
5736
  invokeArrayFns(bm);
@@ -5636,7 +5740,7 @@ function baseCreateRenderer(options, createHydrationFns) {
5636
5740
  (vnodeHook = props && props.onVnodeBeforeMount)) {
5637
5741
  invokeVNodeHook(vnodeHook, parent, initialVNode);
5638
5742
  }
5639
- effect.allowRecurse = true;
5743
+ toggleRecurse(instance, true);
5640
5744
  if (el && hydrateNode) {
5641
5745
  // vnode has adopted host node - perform hydration instead of mount.
5642
5746
  const hydrateSubTree = () => {
@@ -5718,7 +5822,7 @@ function baseCreateRenderer(options, createHydrationFns) {
5718
5822
  pushWarningContext(next || instance.vnode);
5719
5823
  }
5720
5824
  // Disallow component effect recursion during pre-lifecycle hooks.
5721
- effect.allowRecurse = false;
5825
+ toggleRecurse(instance, false);
5722
5826
  if (next) {
5723
5827
  next.el = vnode.el;
5724
5828
  updateComponentPreRender(instance, next, optimized);
@@ -5734,7 +5838,7 @@ function baseCreateRenderer(options, createHydrationFns) {
5734
5838
  if ((vnodeHook = next.props && next.props.onVnodeBeforeUpdate)) {
5735
5839
  invokeVNodeHook(vnodeHook, parent, next, vnode);
5736
5840
  }
5737
- effect.allowRecurse = true;
5841
+ toggleRecurse(instance, true);
5738
5842
  // render
5739
5843
  {
5740
5844
  startMeasure(instance, `render`);
@@ -5780,13 +5884,13 @@ function baseCreateRenderer(options, createHydrationFns) {
5780
5884
  }
5781
5885
  };
5782
5886
  // create reactive effect for rendering
5783
- const effect = new ReactiveEffect(componentUpdateFn, () => queueJob(instance.update), instance.scope // track it in component's effect scope
5784
- );
5887
+ const effect = (instance.effect = new ReactiveEffect(componentUpdateFn, () => queueJob(instance.update), instance.scope // track it in component's effect scope
5888
+ ));
5785
5889
  const update = (instance.update = effect.run.bind(effect));
5786
5890
  update.id = instance.uid;
5787
5891
  // allowRecurse
5788
5892
  // #1801, #2043 component render effects should allow recursive updates
5789
- effect.allowRecurse = update.allowRecurse = true;
5893
+ toggleRecurse(instance, true);
5790
5894
  {
5791
5895
  effect.onTrack = instance.rtc
5792
5896
  ? e => invokeArrayFns(instance.rtc, e)
@@ -6310,85 +6414,8 @@ function baseCreateRenderer(options, createHydrationFns) {
6310
6414
  createApp: createAppAPI(render, hydrate)
6311
6415
  };
6312
6416
  }
6313
- function setRef(rawRef, oldRawRef, parentSuspense, vnode, isUnmount = false) {
6314
- if (isArray(rawRef)) {
6315
- rawRef.forEach((r, i) => setRef(r, oldRawRef && (isArray(oldRawRef) ? oldRawRef[i] : oldRawRef), parentSuspense, vnode, isUnmount));
6316
- return;
6317
- }
6318
- if (isAsyncWrapper(vnode) && !isUnmount) {
6319
- // when mounting async components, nothing needs to be done,
6320
- // because the template ref is forwarded to inner component
6321
- return;
6322
- }
6323
- const refValue = vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */
6324
- ? getExposeProxy(vnode.component) || vnode.component.proxy
6325
- : vnode.el;
6326
- const value = isUnmount ? null : refValue;
6327
- const { i: owner, r: ref } = rawRef;
6328
- if (!owner) {
6329
- warn$1(`Missing ref owner context. ref cannot be used on hoisted vnodes. ` +
6330
- `A vnode with ref must be created inside the render function.`);
6331
- return;
6332
- }
6333
- const oldRef = oldRawRef && oldRawRef.r;
6334
- const refs = owner.refs === EMPTY_OBJ ? (owner.refs = {}) : owner.refs;
6335
- const setupState = owner.setupState;
6336
- // dynamic ref changed. unset old ref
6337
- if (oldRef != null && oldRef !== ref) {
6338
- if (isString(oldRef)) {
6339
- refs[oldRef] = null;
6340
- if (hasOwn(setupState, oldRef)) {
6341
- setupState[oldRef] = null;
6342
- }
6343
- }
6344
- else if (isRef(oldRef)) {
6345
- oldRef.value = null;
6346
- }
6347
- }
6348
- if (isString(ref)) {
6349
- const doSet = () => {
6350
- {
6351
- refs[ref] = value;
6352
- }
6353
- if (hasOwn(setupState, ref)) {
6354
- setupState[ref] = value;
6355
- }
6356
- };
6357
- // #1789: for non-null values, set them after render
6358
- // null values means this is unmount and it should not overwrite another
6359
- // ref with the same key
6360
- if (value) {
6361
- doSet.id = -1;
6362
- queuePostRenderEffect(doSet, parentSuspense);
6363
- }
6364
- else {
6365
- doSet();
6366
- }
6367
- }
6368
- else if (isRef(ref)) {
6369
- const doSet = () => {
6370
- ref.value = value;
6371
- };
6372
- if (value) {
6373
- doSet.id = -1;
6374
- queuePostRenderEffect(doSet, parentSuspense);
6375
- }
6376
- else {
6377
- doSet();
6378
- }
6379
- }
6380
- else if (isFunction(ref)) {
6381
- callWithErrorHandling(ref, owner, 12 /* FUNCTION_REF */, [value, refs]);
6382
- }
6383
- else {
6384
- warn$1('Invalid template ref type:', value, `(${typeof value})`);
6385
- }
6386
- }
6387
- function invokeVNodeHook(hook, instance, vnode, prevVNode = null) {
6388
- callWithAsyncErrorHandling(hook, instance, 7 /* VNODE_HOOK */, [
6389
- vnode,
6390
- prevVNode
6391
- ]);
6417
+ function toggleRecurse({ effect, update }, allowed) {
6418
+ effect.allowRecurse = update.allowRecurse = allowed;
6392
6419
  }
6393
6420
  /**
6394
6421
  * #1156
@@ -6847,10 +6874,10 @@ const createVNodeWithArgsTransform = (...args) => {
6847
6874
  };
6848
6875
  const InternalObjectKey = `__vInternal`;
6849
6876
  const normalizeKey = ({ key }) => key != null ? key : null;
6850
- const normalizeRef = ({ ref }) => {
6877
+ const normalizeRef = ({ ref, ref_key, ref_for }) => {
6851
6878
  return (ref != null
6852
6879
  ? isString(ref) || isRef(ref) || isFunction(ref)
6853
- ? { i: currentRenderingInstance, r: ref }
6880
+ ? { i: currentRenderingInstance, r: ref, k: ref_key, f: !!ref_for }
6854
6881
  : ref
6855
6882
  : null);
6856
6883
  };
@@ -7192,6 +7219,12 @@ function mergeProps(...args) {
7192
7219
  }
7193
7220
  }
7194
7221
  return ret;
7222
+ }
7223
+ function invokeVNodeHook(hook, instance, vnode, prevVNode = null) {
7224
+ callWithAsyncErrorHandling(hook, instance, 7 /* VNODE_HOOK */, [
7225
+ vnode,
7226
+ prevVNode
7227
+ ]);
7195
7228
  }
7196
7229
 
7197
7230
  /**
@@ -7383,23 +7416,23 @@ const PublicInstanceProxyHandlers = {
7383
7416
  const n = accessCache[key];
7384
7417
  if (n !== undefined) {
7385
7418
  switch (n) {
7386
- case 0 /* SETUP */:
7419
+ case 1 /* SETUP */:
7387
7420
  return setupState[key];
7388
- case 1 /* DATA */:
7421
+ case 2 /* DATA */:
7389
7422
  return data[key];
7390
- case 3 /* CONTEXT */:
7423
+ case 4 /* CONTEXT */:
7391
7424
  return ctx[key];
7392
- case 2 /* PROPS */:
7425
+ case 3 /* PROPS */:
7393
7426
  return props[key];
7394
7427
  // default: just fallthrough
7395
7428
  }
7396
7429
  }
7397
7430
  else if (setupState !== EMPTY_OBJ && hasOwn(setupState, key)) {
7398
- accessCache[key] = 0 /* SETUP */;
7431
+ accessCache[key] = 1 /* SETUP */;
7399
7432
  return setupState[key];
7400
7433
  }
7401
7434
  else if (data !== EMPTY_OBJ && hasOwn(data, key)) {
7402
- accessCache[key] = 1 /* DATA */;
7435
+ accessCache[key] = 2 /* DATA */;
7403
7436
  return data[key];
7404
7437
  }
7405
7438
  else if (
@@ -7407,15 +7440,15 @@ const PublicInstanceProxyHandlers = {
7407
7440
  // props
7408
7441
  (normalizedProps = instance.propsOptions[0]) &&
7409
7442
  hasOwn(normalizedProps, key)) {
7410
- accessCache[key] = 2 /* PROPS */;
7443
+ accessCache[key] = 3 /* PROPS */;
7411
7444
  return props[key];
7412
7445
  }
7413
7446
  else if (ctx !== EMPTY_OBJ && hasOwn(ctx, key)) {
7414
- accessCache[key] = 3 /* CONTEXT */;
7447
+ accessCache[key] = 4 /* CONTEXT */;
7415
7448
  return ctx[key];
7416
7449
  }
7417
7450
  else if (shouldCacheAccess) {
7418
- accessCache[key] = 4 /* OTHER */;
7451
+ accessCache[key] = 0 /* OTHER */;
7419
7452
  }
7420
7453
  }
7421
7454
  const publicGetter = publicPropertiesMap[key];
@@ -7436,7 +7469,7 @@ const PublicInstanceProxyHandlers = {
7436
7469
  }
7437
7470
  else if (ctx !== EMPTY_OBJ && hasOwn(ctx, key)) {
7438
7471
  // user may set custom properties to `this` that start with `$`
7439
- accessCache[key] = 3 /* CONTEXT */;
7472
+ accessCache[key] = 4 /* CONTEXT */;
7440
7473
  return ctx[key];
7441
7474
  }
7442
7475
  else if (
@@ -7497,7 +7530,7 @@ const PublicInstanceProxyHandlers = {
7497
7530
  },
7498
7531
  has({ _: { data, setupState, accessCache, ctx, appContext, propsOptions } }, key) {
7499
7532
  let normalizedProps;
7500
- return (accessCache[key] !== undefined ||
7533
+ return (!!accessCache[key] ||
7501
7534
  (data !== EMPTY_OBJ && hasOwn(data, key)) ||
7502
7535
  (setupState !== EMPTY_OBJ && hasOwn(setupState, key)) ||
7503
7536
  ((normalizedProps = propsOptions[0]) && hasOwn(normalizedProps, key)) ||
@@ -7603,6 +7636,7 @@ function createComponentInstance(vnode, parent, suspense) {
7603
7636
  root: null,
7604
7637
  next: null,
7605
7638
  subTree: null,
7639
+ effect: null,
7606
7640
  update: null,
7607
7641
  scope: new EffectScope(true /* detached */),
7608
7642
  render: null,
@@ -9044,7 +9078,7 @@ function isMemoSame(cached, memo) {
9044
9078
  }
9045
9079
 
9046
9080
  // Core API ------------------------------------------------------------------
9047
- const version = "3.2.22";
9081
+ const version = "3.2.26";
9048
9082
  /**
9049
9083
  * SSR utils for \@vue/server-renderer. Only exposed in cjs builds.
9050
9084
  * @internal
@@ -9277,12 +9311,19 @@ prevChildren, parentComponent, parentSuspense, unmountChildren) {
9277
9311
  el[key] = value == null ? '' : value;
9278
9312
  return;
9279
9313
  }
9280
- if (key === 'value' && el.tagName !== 'PROGRESS') {
9314
+ if (key === 'value' &&
9315
+ el.tagName !== 'PROGRESS' &&
9316
+ // custom elements may use _value internally
9317
+ !el.tagName.includes('-')) {
9281
9318
  // store value as _value as well since
9282
9319
  // non-string values will be stringified.
9283
9320
  el._value = value;
9284
9321
  const newValue = value == null ? '' : value;
9285
- if (el.value !== newValue) {
9322
+ if (el.value !== newValue ||
9323
+ // #4956: always set for OPTION elements because its value falls back to
9324
+ // textContent if no value attribute is present. And setting .value for
9325
+ // OPTION has no side effect
9326
+ el.tagName === 'OPTION') {
9286
9327
  el.value = newValue;
9287
9328
  }
9288
9329
  if (value == null) {
@@ -9668,7 +9709,7 @@ class VueElement extends BaseClass {
9668
9709
  // HMR
9669
9710
  {
9670
9711
  instance.ceReload = newStyles => {
9671
- // alawys reset styles
9712
+ // always reset styles
9672
9713
  if (this._styles) {
9673
9714
  this._styles.forEach(s => this.shadowRoot.removeChild(s));
9674
9715
  this._styles.length = 0;
@@ -11292,12 +11333,12 @@ function findProp(node, name, dynamicOnly = false, allowEmpty = false) {
11292
11333
  }
11293
11334
  else if (p.name === 'bind' &&
11294
11335
  (p.exp || allowEmpty) &&
11295
- isBindKey(p.arg, name)) {
11336
+ isStaticArgOf(p.arg, name)) {
11296
11337
  return p;
11297
11338
  }
11298
11339
  }
11299
11340
  }
11300
- function isBindKey(arg, name) {
11341
+ function isStaticArgOf(arg, name) {
11301
11342
  return !!(arg && isStaticExp(arg) && arg.content === name);
11302
11343
  }
11303
11344
  function hasDynamicKeyVBind(node) {
@@ -11340,7 +11381,6 @@ function getUnnormalizedProps(props, callPath = []) {
11340
11381
  }
11341
11382
  function injectProp(node, prop, context) {
11342
11383
  let propsWithInjection;
11343
- const originalProps = node.type === 13 /* VNODE_CALL */ ? node.props : node.arguments[2];
11344
11384
  /**
11345
11385
  * 1. mergeProps(...)
11346
11386
  * 2. toHandlers(...)
@@ -11349,7 +11389,7 @@ function injectProp(node, prop, context) {
11349
11389
  *
11350
11390
  * we need to get the real props before normalization
11351
11391
  */
11352
- let props = originalProps;
11392
+ let props = node.type === 13 /* VNODE_CALL */ ? node.props : node.arguments[2];
11353
11393
  let callPath = [];
11354
11394
  let parentCall;
11355
11395
  if (props &&
@@ -11488,11 +11528,6 @@ const deprecationData = {
11488
11528
  `data source.`,
11489
11529
  link: `https://v3.vuejs.org/guide/migration/v-if-v-for.html`
11490
11530
  },
11491
- ["COMPILER_V_FOR_REF" /* COMPILER_V_FOR_REF */]: {
11492
- message: `Ref usage on v-for no longer creates array ref values in Vue 3. ` +
11493
- `Consider using function refs or refactor to avoid ref usage altogether.`,
11494
- link: `https://v3.vuejs.org/guide/migration/array-refs.html`
11495
- },
11496
11531
  ["COMPILER_NATIVE_TEMPLATE" /* COMPILER_NATIVE_TEMPLATE */]: {
11497
11532
  message: `<template> with no special directives will render as a native template ` +
11498
11533
  `element instead of its inner content in Vue 3.`
@@ -11965,7 +12000,7 @@ function isComponent(tag, props, context) {
11965
12000
  else if (
11966
12001
  // :is on plain element - only treat as component in compat mode
11967
12002
  p.name === 'bind' &&
11968
- isBindKey(p.arg, 'is') &&
12003
+ isStaticArgOf(p.arg, 'is') &&
11969
12004
  false &&
11970
12005
  checkCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context, p.loc)) {
11971
12006
  return true;
@@ -12314,15 +12349,6 @@ function isSingleElementRoot(root, child) {
12314
12349
  !isSlotOutlet(child));
12315
12350
  }
12316
12351
  function walk(node, context, doNotHoistNode = false) {
12317
- // Some transforms, e.g. transformAssetUrls from @vue/compiler-sfc, replaces
12318
- // static bindings with expressions. These expressions are guaranteed to be
12319
- // constant so they are still eligible for hoisting, but they are only
12320
- // available at runtime and therefore cannot be evaluated ahead of time.
12321
- // This is only a concern for pre-stringification (via transformHoist by
12322
- // @vue/compiler-dom), but doing it here allows us to perform only one full
12323
- // walk of the AST and allow `stringifyStatic` to stop walking as soon as its
12324
- // stringification threshold is met.
12325
- let canStringify = true;
12326
12352
  const { children } = node;
12327
12353
  const originalCount = children.length;
12328
12354
  let hoistedCount = 0;
@@ -12335,9 +12361,6 @@ function walk(node, context, doNotHoistNode = false) {
12335
12361
  ? 0 /* NOT_CONSTANT */
12336
12362
  : getConstantType(child, context);
12337
12363
  if (constantType > 0 /* NOT_CONSTANT */) {
12338
- if (constantType < 3 /* CAN_STRINGIFY */) {
12339
- canStringify = false;
12340
- }
12341
12364
  if (constantType >= 2 /* CAN_HOIST */) {
12342
12365
  child.codegenNode.patchFlag =
12343
12366
  -1 /* HOISTED */ + (` /* HOISTED */` );
@@ -12368,17 +12391,10 @@ function walk(node, context, doNotHoistNode = false) {
12368
12391
  }
12369
12392
  }
12370
12393
  }
12371
- else if (child.type === 12 /* TEXT_CALL */) {
12372
- const contentType = getConstantType(child.content, context);
12373
- if (contentType > 0) {
12374
- if (contentType < 3 /* CAN_STRINGIFY */) {
12375
- canStringify = false;
12376
- }
12377
- if (contentType >= 2 /* CAN_HOIST */) {
12378
- child.codegenNode = context.hoist(child.codegenNode);
12379
- hoistedCount++;
12380
- }
12381
- }
12394
+ else if (child.type === 12 /* TEXT_CALL */ &&
12395
+ getConstantType(child.content, context) >= 2 /* CAN_HOIST */) {
12396
+ child.codegenNode = context.hoist(child.codegenNode);
12397
+ hoistedCount++;
12382
12398
  }
12383
12399
  // walk further
12384
12400
  if (child.type === 1 /* ELEMENT */) {
@@ -12402,7 +12418,7 @@ function walk(node, context, doNotHoistNode = false) {
12402
12418
  }
12403
12419
  }
12404
12420
  }
12405
- if (canStringify && hoistedCount && context.transformHoist) {
12421
+ if (hoistedCount && context.transformHoist) {
12406
12422
  context.transformHoist(children, context, node);
12407
12423
  }
12408
12424
  // all children were hoisted - the entire children array is hoistable.
@@ -12431,6 +12447,11 @@ function getConstantType(node, context) {
12431
12447
  if (codegenNode.type !== 13 /* VNODE_CALL */) {
12432
12448
  return 0 /* NOT_CONSTANT */;
12433
12449
  }
12450
+ if (codegenNode.isBlock &&
12451
+ node.tag !== 'svg' &&
12452
+ node.tag !== 'foreignObject') {
12453
+ return 0 /* NOT_CONSTANT */;
12454
+ }
12434
12455
  const flag = getPatchFlag(codegenNode);
12435
12456
  if (!flag) {
12436
12457
  let returnType = 3 /* CAN_STRINGIFY */;
@@ -12567,7 +12588,7 @@ function getGeneratedPropsConstantType(node, context) {
12567
12588
  else if (value.type === 14 /* JS_CALL_EXPRESSION */) {
12568
12589
  // some helper calls can be hoisted,
12569
12590
  // such as the `normalizeProps` generated by the compiler for pre-normalize class,
12570
- // in this case we need to respect the ConstantType of the helper's argments
12591
+ // in this case we need to respect the ConstantType of the helper's arguments
12571
12592
  valueType = getConstantTypeOfHelperCall(value, context);
12572
12593
  }
12573
12594
  else {
@@ -14215,10 +14236,7 @@ const transformElement = (node, context) => {
14215
14236
  // updates inside get proper isSVG flag at runtime. (#639, #643)
14216
14237
  // This is technically web-specific, but splitting the logic out of core
14217
14238
  // leads to too much unnecessary complexity.
14218
- (tag === 'svg' ||
14219
- tag === 'foreignObject' ||
14220
- // #938: elements with dynamic keys should be forced into blocks
14221
- findProp(node, 'key', true)));
14239
+ (tag === 'svg' || tag === 'foreignObject'));
14222
14240
  // props
14223
14241
  if (props.length > 0) {
14224
14242
  const propsBuildResult = buildProps(node, context);
@@ -14230,6 +14248,9 @@ const transformElement = (node, context) => {
14230
14248
  directives && directives.length
14231
14249
  ? createArrayExpression(directives.map(dir => buildDirectiveArgs(dir, context)))
14232
14250
  : undefined;
14251
+ if (propsBuildResult.shouldUseBlock) {
14252
+ shouldUseBlock = true;
14253
+ }
14233
14254
  }
14234
14255
  // children
14235
14256
  if (node.children.length > 0) {
@@ -14358,11 +14379,13 @@ function resolveComponentType(node, context, ssr = false) {
14358
14379
  return toValidAssetId(tag, `component`);
14359
14380
  }
14360
14381
  function buildProps(node, context, props = node.props, ssr = false) {
14361
- const { tag, loc: elementLoc } = node;
14382
+ const { tag, loc: elementLoc, children } = node;
14362
14383
  const isComponent = node.tagType === 1 /* COMPONENT */;
14363
14384
  let properties = [];
14364
14385
  const mergeArgs = [];
14365
14386
  const runtimeDirectives = [];
14387
+ const hasChildren = children.length > 0;
14388
+ let shouldUseBlock = false;
14366
14389
  // patchFlag analysis
14367
14390
  let patchFlag = 0;
14368
14391
  let hasRef = false;
@@ -14425,9 +14448,12 @@ function buildProps(node, context, props = node.props, ssr = false) {
14425
14448
  const prop = props[i];
14426
14449
  if (prop.type === 6 /* ATTRIBUTE */) {
14427
14450
  const { loc, name, value } = prop;
14428
- let valueNode = createSimpleExpression(value ? value.content : '', true, value ? value.loc : loc);
14451
+ let isStatic = true;
14429
14452
  if (name === 'ref') {
14430
14453
  hasRef = true;
14454
+ if (context.scopes.vFor > 0) {
14455
+ properties.push(createObjectProperty(createSimpleExpression('ref_for', true), createSimpleExpression('true')));
14456
+ }
14431
14457
  }
14432
14458
  // skip is on <component>, or is="vue:xxx"
14433
14459
  if (name === 'is' &&
@@ -14436,7 +14462,7 @@ function buildProps(node, context, props = node.props, ssr = false) {
14436
14462
  (false ))) {
14437
14463
  continue;
14438
14464
  }
14439
- properties.push(createObjectProperty(createSimpleExpression(name, true, getInnerRange(loc, 0, name.length)), valueNode));
14465
+ properties.push(createObjectProperty(createSimpleExpression(name, true, getInnerRange(loc, 0, name.length)), createSimpleExpression(value ? value.content : '', isStatic, value ? value.loc : loc)));
14440
14466
  }
14441
14467
  else {
14442
14468
  // directives
@@ -14457,7 +14483,7 @@ function buildProps(node, context, props = node.props, ssr = false) {
14457
14483
  // skip v-is and :is on <component>
14458
14484
  if (name === 'is' ||
14459
14485
  (isVBind &&
14460
- isBindKey(arg, 'is') &&
14486
+ isStaticArgOf(arg, 'is') &&
14461
14487
  (isComponentTag(tag) ||
14462
14488
  (false )))) {
14463
14489
  continue;
@@ -14466,6 +14492,17 @@ function buildProps(node, context, props = node.props, ssr = false) {
14466
14492
  if (isVOn && ssr) {
14467
14493
  continue;
14468
14494
  }
14495
+ if (
14496
+ // #938: elements with dynamic keys should be forced into blocks
14497
+ (isVBind && isStaticArgOf(arg, 'key')) ||
14498
+ // inline before-update hooks need to force block so that it is invoked
14499
+ // before children
14500
+ (isVOn && hasChildren && isStaticArgOf(arg, 'vue:before-update'))) {
14501
+ shouldUseBlock = true;
14502
+ }
14503
+ if (isVBind && isStaticArgOf(arg, 'ref') && context.scopes.vFor > 0) {
14504
+ properties.push(createObjectProperty(createSimpleExpression('ref_for', true), createSimpleExpression('true')));
14505
+ }
14469
14506
  // special case for v-bind and v-on with no argument
14470
14507
  if (!arg && (isVBind || isVOn)) {
14471
14508
  hasDynamicKeys = true;
@@ -14510,6 +14547,11 @@ function buildProps(node, context, props = node.props, ssr = false) {
14510
14547
  else {
14511
14548
  // no built-in transform, this is a user custom directive.
14512
14549
  runtimeDirectives.push(prop);
14550
+ // custom dirs may use beforeUpdate so they need to force blocks
14551
+ // to ensure before-update gets called before children update
14552
+ if (hasChildren) {
14553
+ shouldUseBlock = true;
14554
+ }
14513
14555
  }
14514
14556
  }
14515
14557
  }
@@ -14548,7 +14590,8 @@ function buildProps(node, context, props = node.props, ssr = false) {
14548
14590
  patchFlag |= 32 /* HYDRATE_EVENTS */;
14549
14591
  }
14550
14592
  }
14551
- if ((patchFlag === 0 || patchFlag === 32 /* HYDRATE_EVENTS */) &&
14593
+ if (!shouldUseBlock &&
14594
+ (patchFlag === 0 || patchFlag === 32 /* HYDRATE_EVENTS */) &&
14552
14595
  (hasRef || hasVnodeHook || runtimeDirectives.length > 0)) {
14553
14596
  patchFlag |= 512 /* NEED_PATCH */;
14554
14597
  }
@@ -14615,7 +14658,8 @@ function buildProps(node, context, props = node.props, ssr = false) {
14615
14658
  props: propsExpression,
14616
14659
  directives: runtimeDirectives,
14617
14660
  patchFlag,
14618
- dynamicPropNames
14661
+ dynamicPropNames,
14662
+ shouldUseBlock
14619
14663
  };
14620
14664
  }
14621
14665
  // Dedupe props in an object literal.
@@ -14751,7 +14795,7 @@ function processSlotOutlet(node, context) {
14751
14795
  }
14752
14796
  }
14753
14797
  else {
14754
- if (p.name === 'bind' && isBindKey(p.arg, 'name')) {
14798
+ if (p.name === 'bind' && isStaticArgOf(p.arg, 'name')) {
14755
14799
  if (p.exp)
14756
14800
  slotName = p.exp;
14757
14801
  }
@@ -14785,7 +14829,11 @@ const transformOn = (dir, node, context, augmentor) => {
14785
14829
  let eventName;
14786
14830
  if (arg.type === 4 /* SIMPLE_EXPRESSION */) {
14787
14831
  if (arg.isStatic) {
14788
- const rawName = arg.content;
14832
+ let rawName = arg.content;
14833
+ // TODO deprecate @vnodeXXX usage
14834
+ if (rawName.startsWith('vue:')) {
14835
+ rawName = `vnode-${rawName.slice(4)}`;
14836
+ }
14789
14837
  // for all event listeners, auto convert it to camelCase. See issue #2249
14790
14838
  eventName = createSimpleExpression(toHandlerKey(camelize(rawName)), true, arg.loc);
14791
14839
  }