@vue/compat 3.2.24 → 3.2.25

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 === '';
@@ -342,7 +342,7 @@ const isIntegerKey = (key) => isString(key) &&
342
342
  '' + parseInt(key, 10) === key;
343
343
  const isReservedProp = /*#__PURE__*/ makeMap(
344
344
  // the leading comma is intentional so empty string "" is also included
345
- ',key,ref,' +
345
+ ',key,ref,ref_for,ref_key,' +
346
346
  'onVnodeBeforeMount,onVnodeMounted,' +
347
347
  'onVnodeBeforeUpdate,onVnodeUpdated,' +
348
348
  'onVnodeBeforeUnmount,onVnodeUnmounted');
@@ -1452,21 +1452,25 @@ function toRefs(object) {
1452
1452
  return ret;
1453
1453
  }
1454
1454
  class ObjectRefImpl {
1455
- constructor(_object, _key) {
1455
+ constructor(_object, _key, _defaultValue) {
1456
1456
  this._object = _object;
1457
1457
  this._key = _key;
1458
+ this._defaultValue = _defaultValue;
1458
1459
  this.__v_isRef = true;
1459
1460
  }
1460
1461
  get value() {
1461
- return this._object[this._key];
1462
+ const val = this._object[this._key];
1463
+ return val === undefined ? this._defaultValue : val;
1462
1464
  }
1463
1465
  set value(newVal) {
1464
1466
  this._object[this._key] = newVal;
1465
1467
  }
1466
1468
  }
1467
- function toRef(object, key) {
1469
+ function toRef(object, key, defaultValue) {
1468
1470
  const val = object[key];
1469
- return isRef(val) ? val : new ObjectRefImpl(object, key);
1471
+ return isRef(val)
1472
+ ? val
1473
+ : new ObjectRefImpl(object, key, defaultValue);
1470
1474
  }
1471
1475
 
1472
1476
  class ComputedRefImpl {
@@ -1913,11 +1917,6 @@ const deprecationData = {
1913
1917
  `Use "${newHook}" instead.`,
1914
1918
  link: `https://v3.vuejs.org/guide/migration/custom-directives.html`
1915
1919
  },
1916
- ["V_FOR_REF" /* V_FOR_REF */]: {
1917
- message: `Ref usage on v-for no longer creates array ref values in Vue 3. ` +
1918
- `Consider using function refs or refactor to avoid ref usage altogether.`,
1919
- link: `https://v3.vuejs.org/guide/migration/array-refs.html`
1920
- },
1921
1920
  ["V_ON_KEYCODE_MODIFIER" /* V_ON_KEYCODE_MODIFIER */]: {
1922
1921
  message: `Using keyCode as v-on modifier is no longer supported. ` +
1923
1922
  `Use kebab-case key name modifiers instead.`,
@@ -5344,7 +5343,7 @@ function createCompatVue(createApp, createSingletonApp) {
5344
5343
  return vm;
5345
5344
  }
5346
5345
  }
5347
- Vue.version = "3.2.24";
5346
+ Vue.version = "3.2.25";
5348
5347
  Vue.config = singletonApp.config;
5349
5348
  Vue.use = (p, ...options) => {
5350
5349
  if (p && isFunction(p.install)) {
@@ -5697,7 +5696,7 @@ const methodsToPatch = [
5697
5696
  ];
5698
5697
  const patched = new WeakSet();
5699
5698
  function defineReactive(obj, key, val) {
5700
- // it's possible for the orignial object to be mutated after being defined
5699
+ // it's possible for the original object to be mutated after being defined
5701
5700
  // and expecting reactivity... we are covering it here because this seems to
5702
5701
  // be a bit more common.
5703
5702
  if (isObject(val) && !isReactive(val) && !patched.has(val)) {
@@ -5920,6 +5919,102 @@ function createAppAPI(render, hydrate) {
5920
5919
  };
5921
5920
  }
5922
5921
 
5922
+ /**
5923
+ * Function for handling a template ref
5924
+ */
5925
+ function setRef(rawRef, oldRawRef, parentSuspense, vnode, isUnmount = false) {
5926
+ if (isArray(rawRef)) {
5927
+ rawRef.forEach((r, i) => setRef(r, oldRawRef && (isArray(oldRawRef) ? oldRawRef[i] : oldRawRef), parentSuspense, vnode, isUnmount));
5928
+ return;
5929
+ }
5930
+ if (isAsyncWrapper(vnode) && !isUnmount) {
5931
+ // when mounting async components, nothing needs to be done,
5932
+ // because the template ref is forwarded to inner component
5933
+ return;
5934
+ }
5935
+ const refValue = vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */
5936
+ ? getExposeProxy(vnode.component) || vnode.component.proxy
5937
+ : vnode.el;
5938
+ const value = isUnmount ? null : refValue;
5939
+ const { i: owner, r: ref } = rawRef;
5940
+ if ((process.env.NODE_ENV !== 'production') && !owner) {
5941
+ warn$1(`Missing ref owner context. ref cannot be used on hoisted vnodes. ` +
5942
+ `A vnode with ref must be created inside the render function.`);
5943
+ return;
5944
+ }
5945
+ const oldRef = oldRawRef && oldRawRef.r;
5946
+ const refs = owner.refs === EMPTY_OBJ ? (owner.refs = {}) : owner.refs;
5947
+ const setupState = owner.setupState;
5948
+ // dynamic ref changed. unset old ref
5949
+ if (oldRef != null && oldRef !== ref) {
5950
+ if (isString(oldRef)) {
5951
+ refs[oldRef] = null;
5952
+ if (hasOwn(setupState, oldRef)) {
5953
+ setupState[oldRef] = null;
5954
+ }
5955
+ }
5956
+ else if (isRef(oldRef)) {
5957
+ oldRef.value = null;
5958
+ }
5959
+ }
5960
+ if (isFunction(ref)) {
5961
+ callWithErrorHandling(ref, owner, 12 /* FUNCTION_REF */, [value, refs]);
5962
+ }
5963
+ else {
5964
+ const _isString = isString(ref);
5965
+ const _isRef = isRef(ref);
5966
+ if (_isString || _isRef) {
5967
+ const doSet = () => {
5968
+ if (rawRef.f) {
5969
+ const existing = _isString ? refs[ref] : ref.value;
5970
+ if (isUnmount) {
5971
+ isArray(existing) && remove(existing, refValue);
5972
+ }
5973
+ else {
5974
+ if (!isArray(existing)) {
5975
+ if (_isString) {
5976
+ refs[ref] = [refValue];
5977
+ }
5978
+ else {
5979
+ ref.value = [refValue];
5980
+ if (rawRef.k)
5981
+ refs[rawRef.k] = ref.value;
5982
+ }
5983
+ }
5984
+ else if (!existing.includes(refValue)) {
5985
+ existing.push(refValue);
5986
+ }
5987
+ }
5988
+ }
5989
+ else if (_isString) {
5990
+ refs[ref] = value;
5991
+ if (hasOwn(setupState, ref)) {
5992
+ setupState[ref] = value;
5993
+ }
5994
+ }
5995
+ else if (isRef(ref)) {
5996
+ ref.value = value;
5997
+ if (rawRef.k)
5998
+ refs[rawRef.k] = value;
5999
+ }
6000
+ else if ((process.env.NODE_ENV !== 'production')) {
6001
+ warn$1('Invalid template ref type:', ref, `(${typeof ref})`);
6002
+ }
6003
+ };
6004
+ if (value) {
6005
+ doSet.id = -1;
6006
+ queuePostRenderEffect(doSet, parentSuspense);
6007
+ }
6008
+ else {
6009
+ doSet();
6010
+ }
6011
+ }
6012
+ else if ((process.env.NODE_ENV !== 'production')) {
6013
+ warn$1('Invalid template ref type:', ref, `(${typeof ref})`);
6014
+ }
6015
+ }
6016
+ }
6017
+
5923
6018
  let hasMismatch = false;
5924
6019
  const isSVGContainer = (container) => /svg/.test(container.namespaceURI) && container.tagName !== 'foreignObject';
5925
6020
  const isComment = (node) => node.nodeType === 8 /* COMMENT */;
@@ -6308,45 +6403,7 @@ function initFeatureFlags() {
6308
6403
  `which expects these compile-time feature flags to be globally injected ` +
6309
6404
  `via the bundler config in order to get better tree-shaking in the ` +
6310
6405
  `production bundle.\n\n` +
6311
- `For more details, see http://link.vuejs.org/feature-flags.`);
6312
- }
6313
- }
6314
-
6315
- function convertLegacyRefInFor(vnode) {
6316
- // refInFor
6317
- if (vnode.props && vnode.props.refInFor) {
6318
- delete vnode.props.refInFor;
6319
- if (vnode.ref) {
6320
- if (isArray(vnode.ref)) {
6321
- vnode.ref.forEach(r => (r.f = true));
6322
- }
6323
- else {
6324
- vnode.ref.f = true;
6325
- }
6326
- }
6327
- }
6328
- }
6329
- function registerLegacyRef(refs, key, value, owner, isInFor, isUnmount) {
6330
- const existing = refs[key];
6331
- if (isUnmount) {
6332
- if (isArray(existing)) {
6333
- remove(existing, value);
6334
- }
6335
- else {
6336
- refs[key] = null;
6337
- }
6338
- }
6339
- else if (isInFor) {
6340
- (process.env.NODE_ENV !== 'production') && warnDeprecation("V_FOR_REF" /* V_FOR_REF */, owner);
6341
- if (!isArray(existing)) {
6342
- refs[key] = [value];
6343
- }
6344
- else if (!existing.includes(value)) {
6345
- existing.push(value);
6346
- }
6347
- }
6348
- else {
6349
- refs[key] = value;
6406
+ `For more details, see https://link.vuejs.org/feature-flags.`);
6350
6407
  }
6351
6408
  }
6352
6409
 
@@ -6636,12 +6693,15 @@ function baseCreateRenderer(options, createHydrationFns) {
6636
6693
  const oldProps = n1.props || EMPTY_OBJ;
6637
6694
  const newProps = n2.props || EMPTY_OBJ;
6638
6695
  let vnodeHook;
6696
+ // disable recurse in beforeUpdate hooks
6697
+ parentComponent && toggleRecurse(parentComponent, false);
6639
6698
  if ((vnodeHook = newProps.onVnodeBeforeUpdate)) {
6640
6699
  invokeVNodeHook(vnodeHook, parentComponent, n2, n1);
6641
6700
  }
6642
6701
  if (dirs) {
6643
6702
  invokeDirectiveHook(n2, n1, parentComponent, 'beforeUpdate');
6644
6703
  }
6704
+ parentComponent && toggleRecurse(parentComponent, true);
6645
6705
  if ((process.env.NODE_ENV !== 'production') && isHmrUpdating) {
6646
6706
  // HMR updated, force full diff
6647
6707
  patchFlag = 0;
@@ -6925,7 +6985,7 @@ function baseCreateRenderer(options, createHydrationFns) {
6925
6985
  const { el, props } = initialVNode;
6926
6986
  const { bm, m, parent } = instance;
6927
6987
  const isAsyncWrapperVNode = isAsyncWrapper(initialVNode);
6928
- effect.allowRecurse = false;
6988
+ toggleRecurse(instance, false);
6929
6989
  // beforeMount hook
6930
6990
  if (bm) {
6931
6991
  invokeArrayFns(bm);
@@ -6938,7 +6998,7 @@ function baseCreateRenderer(options, createHydrationFns) {
6938
6998
  if (isCompatEnabled("INSTANCE_EVENT_HOOKS" /* INSTANCE_EVENT_HOOKS */, instance)) {
6939
6999
  instance.emit('hook:beforeMount');
6940
7000
  }
6941
- effect.allowRecurse = true;
7001
+ toggleRecurse(instance, true);
6942
7002
  if (el && hydrateNode) {
6943
7003
  // vnode has adopted host node - perform hydration instead of mount.
6944
7004
  const hydrateSubTree = () => {
@@ -7026,7 +7086,7 @@ function baseCreateRenderer(options, createHydrationFns) {
7026
7086
  pushWarningContext(next || instance.vnode);
7027
7087
  }
7028
7088
  // Disallow component effect recursion during pre-lifecycle hooks.
7029
- effect.allowRecurse = false;
7089
+ toggleRecurse(instance, false);
7030
7090
  if (next) {
7031
7091
  next.el = vnode.el;
7032
7092
  updateComponentPreRender(instance, next, optimized);
@@ -7045,7 +7105,7 @@ function baseCreateRenderer(options, createHydrationFns) {
7045
7105
  if (isCompatEnabled("INSTANCE_EVENT_HOOKS" /* INSTANCE_EVENT_HOOKS */, instance)) {
7046
7106
  instance.emit('hook:beforeUpdate');
7047
7107
  }
7048
- effect.allowRecurse = true;
7108
+ toggleRecurse(instance, true);
7049
7109
  // render
7050
7110
  if ((process.env.NODE_ENV !== 'production')) {
7051
7111
  startMeasure(instance, `render`);
@@ -7094,13 +7154,13 @@ function baseCreateRenderer(options, createHydrationFns) {
7094
7154
  }
7095
7155
  };
7096
7156
  // create reactive effect for rendering
7097
- const effect = new ReactiveEffect(componentUpdateFn, () => queueJob(instance.update), instance.scope // track it in component's effect scope
7098
- );
7157
+ const effect = (instance.effect = new ReactiveEffect(componentUpdateFn, () => queueJob(instance.update), instance.scope // track it in component's effect scope
7158
+ ));
7099
7159
  const update = (instance.update = effect.run.bind(effect));
7100
7160
  update.id = instance.uid;
7101
7161
  // allowRecurse
7102
7162
  // #1801, #2043 component render effects should allow recursive updates
7103
- effect.allowRecurse = update.allowRecurse = true;
7163
+ toggleRecurse(instance, true);
7104
7164
  if ((process.env.NODE_ENV !== 'production')) {
7105
7165
  effect.onTrack = instance.rtc
7106
7166
  ? e => invokeArrayFns(instance.rtc, e)
@@ -7630,88 +7690,8 @@ function baseCreateRenderer(options, createHydrationFns) {
7630
7690
  createApp: createAppAPI(render, hydrate)
7631
7691
  };
7632
7692
  }
7633
- function setRef(rawRef, oldRawRef, parentSuspense, vnode, isUnmount = false) {
7634
- if (isArray(rawRef)) {
7635
- rawRef.forEach((r, i) => setRef(r, oldRawRef && (isArray(oldRawRef) ? oldRawRef[i] : oldRawRef), parentSuspense, vnode, isUnmount));
7636
- return;
7637
- }
7638
- if (isAsyncWrapper(vnode) && !isUnmount) {
7639
- // when mounting async components, nothing needs to be done,
7640
- // because the template ref is forwarded to inner component
7641
- return;
7642
- }
7643
- const refValue = vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */
7644
- ? getExposeProxy(vnode.component) || vnode.component.proxy
7645
- : vnode.el;
7646
- const value = isUnmount ? null : refValue;
7647
- const { i: owner, r: ref } = rawRef;
7648
- if ((process.env.NODE_ENV !== 'production') && !owner) {
7649
- warn$1(`Missing ref owner context. ref cannot be used on hoisted vnodes. ` +
7650
- `A vnode with ref must be created inside the render function.`);
7651
- return;
7652
- }
7653
- const oldRef = oldRawRef && oldRawRef.r;
7654
- const refs = owner.refs === EMPTY_OBJ ? (owner.refs = {}) : owner.refs;
7655
- const setupState = owner.setupState;
7656
- // dynamic ref changed. unset old ref
7657
- if (oldRef != null && oldRef !== ref) {
7658
- if (isString(oldRef)) {
7659
- refs[oldRef] = null;
7660
- if (hasOwn(setupState, oldRef)) {
7661
- setupState[oldRef] = null;
7662
- }
7663
- }
7664
- else if (isRef(oldRef)) {
7665
- oldRef.value = null;
7666
- }
7667
- }
7668
- if (isString(ref)) {
7669
- const doSet = () => {
7670
- if (isCompatEnabled("V_FOR_REF" /* V_FOR_REF */, owner)) {
7671
- registerLegacyRef(refs, ref, refValue, owner, rawRef.f, isUnmount);
7672
- }
7673
- else {
7674
- refs[ref] = value;
7675
- }
7676
- if (hasOwn(setupState, ref)) {
7677
- setupState[ref] = value;
7678
- }
7679
- };
7680
- // #1789: for non-null values, set them after render
7681
- // null values means this is unmount and it should not overwrite another
7682
- // ref with the same key
7683
- if (value) {
7684
- doSet.id = -1;
7685
- queuePostRenderEffect(doSet, parentSuspense);
7686
- }
7687
- else {
7688
- doSet();
7689
- }
7690
- }
7691
- else if (isRef(ref)) {
7692
- const doSet = () => {
7693
- ref.value = value;
7694
- };
7695
- if (value) {
7696
- doSet.id = -1;
7697
- queuePostRenderEffect(doSet, parentSuspense);
7698
- }
7699
- else {
7700
- doSet();
7701
- }
7702
- }
7703
- else if (isFunction(ref)) {
7704
- callWithErrorHandling(ref, owner, 12 /* FUNCTION_REF */, [value, refs]);
7705
- }
7706
- else if ((process.env.NODE_ENV !== 'production')) {
7707
- warn$1('Invalid template ref type:', value, `(${typeof value})`);
7708
- }
7709
- }
7710
- function invokeVNodeHook(hook, instance, vnode, prevVNode = null) {
7711
- callWithAsyncErrorHandling(hook, instance, 7 /* VNODE_HOOK */, [
7712
- vnode,
7713
- prevVNode
7714
- ]);
7693
+ function toggleRecurse({ effect, update }, allowed) {
7694
+ effect.allowRecurse = update.allowRecurse = allowed;
7715
7695
  }
7716
7696
  /**
7717
7697
  * #1156
@@ -8511,10 +8491,10 @@ const createVNodeWithArgsTransform = (...args) => {
8511
8491
  };
8512
8492
  const InternalObjectKey = `__vInternal`;
8513
8493
  const normalizeKey = ({ key }) => key != null ? key : null;
8514
- const normalizeRef = ({ ref }) => {
8494
+ const normalizeRef = ({ ref, ref_key, ref_for }) => {
8515
8495
  return (ref != null
8516
8496
  ? isString(ref) || isRef(ref) || isFunction(ref)
8517
- ? { i: currentRenderingInstance, r: ref }
8497
+ ? { i: currentRenderingInstance, r: ref, k: ref_key, f: !!ref_for }
8518
8498
  : ref
8519
8499
  : null);
8520
8500
  };
@@ -8582,7 +8562,6 @@ function createBaseVNode(type, props = null, children = null, patchFlag = 0, dyn
8582
8562
  }
8583
8563
  {
8584
8564
  convertLegacyVModelProps(vnode);
8585
- convertLegacyRefInFor(vnode);
8586
8565
  defineLegacyVNodeProperties(vnode);
8587
8566
  }
8588
8567
  return vnode;
@@ -8868,6 +8847,12 @@ function mergeProps(...args) {
8868
8847
  }
8869
8848
  }
8870
8849
  return ret;
8850
+ }
8851
+ function invokeVNodeHook(hook, instance, vnode, prevVNode = null) {
8852
+ callWithAsyncErrorHandling(hook, instance, 7 /* VNODE_HOOK */, [
8853
+ vnode,
8854
+ prevVNode
8855
+ ]);
8871
8856
  }
8872
8857
 
8873
8858
  function getCompatChildren(instance) {
@@ -9531,6 +9516,7 @@ function createComponentInstance(vnode, parent, suspense) {
9531
9516
  root: null,
9532
9517
  next: null,
9533
9518
  subTree: null,
9519
+ effect: null,
9534
9520
  update: null,
9535
9521
  scope: new EffectScope(true /* detached */),
9536
9522
  render: null,
@@ -11050,7 +11036,7 @@ function isMemoSame(cached, memo) {
11050
11036
  }
11051
11037
 
11052
11038
  // Core API ------------------------------------------------------------------
11053
- const version = "3.2.24";
11039
+ const version = "3.2.25";
11054
11040
  const _ssrUtils = {
11055
11041
  createComponentInstance,
11056
11042
  setupComponent,
@@ -13514,12 +13500,12 @@ function findProp(node, name, dynamicOnly = false, allowEmpty = false) {
13514
13500
  }
13515
13501
  else if (p.name === 'bind' &&
13516
13502
  (p.exp || allowEmpty) &&
13517
- isBindKey(p.arg, name)) {
13503
+ isStaticArgOf(p.arg, name)) {
13518
13504
  return p;
13519
13505
  }
13520
13506
  }
13521
13507
  }
13522
- function isBindKey(arg, name) {
13508
+ function isStaticArgOf(arg, name) {
13523
13509
  return !!(arg && isStaticExp(arg) && arg.content === name);
13524
13510
  }
13525
13511
  function hasDynamicKeyVBind(node) {
@@ -13709,11 +13695,6 @@ const deprecationData$1 = {
13709
13695
  `data source.`,
13710
13696
  link: `https://v3.vuejs.org/guide/migration/v-if-v-for.html`
13711
13697
  },
13712
- ["COMPILER_V_FOR_REF" /* COMPILER_V_FOR_REF */]: {
13713
- message: `Ref usage on v-for no longer creates array ref values in Vue 3. ` +
13714
- `Consider using function refs or refactor to avoid ref usage altogether.`,
13715
- link: `https://v3.vuejs.org/guide/migration/array-refs.html`
13716
- },
13717
13698
  ["COMPILER_NATIVE_TEMPLATE" /* COMPILER_NATIVE_TEMPLATE */]: {
13718
13699
  message: `<template> with no special directives will render as a native template ` +
13719
13700
  `element instead of its inner content in Vue 3.`
@@ -14233,7 +14214,7 @@ function isComponent(tag, props, context) {
14233
14214
  else if (
14234
14215
  // :is on plain element - only treat as component in compat mode
14235
14216
  p.name === 'bind' &&
14236
- isBindKey(p.arg, 'is') &&
14217
+ isStaticArgOf(p.arg, 'is') &&
14237
14218
  true &&
14238
14219
  checkCompatEnabled$1("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context, p.loc)) {
14239
14220
  return true;
@@ -14691,6 +14672,11 @@ function getConstantType(node, context) {
14691
14672
  if (codegenNode.type !== 13 /* VNODE_CALL */) {
14692
14673
  return 0 /* NOT_CONSTANT */;
14693
14674
  }
14675
+ if (codegenNode.isBlock &&
14676
+ node.tag !== 'svg' &&
14677
+ node.tag !== 'foreignObject') {
14678
+ return 0 /* NOT_CONSTANT */;
14679
+ }
14694
14680
  const flag = getPatchFlag(codegenNode);
14695
14681
  if (!flag) {
14696
14682
  let returnType = 3 /* CAN_STRINGIFY */;
@@ -14828,7 +14814,7 @@ function getGeneratedPropsConstantType(node, context) {
14828
14814
  else if (value.type === 14 /* JS_CALL_EXPRESSION */) {
14829
14815
  // some helper calls can be hoisted,
14830
14816
  // such as the `normalizeProps` generated by the compiler for pre-normalize class,
14831
- // in this case we need to respect the ConstantType of the helper's argments
14817
+ // in this case we need to respect the ConstantType of the helper's arguments
14832
14818
  valueType = getConstantTypeOfHelperCall(value, context);
14833
14819
  }
14834
14820
  else {
@@ -16501,10 +16487,7 @@ const transformElement = (node, context) => {
16501
16487
  // updates inside get proper isSVG flag at runtime. (#639, #643)
16502
16488
  // This is technically web-specific, but splitting the logic out of core
16503
16489
  // leads to too much unnecessary complexity.
16504
- (tag === 'svg' ||
16505
- tag === 'foreignObject' ||
16506
- // #938: elements with dynamic keys should be forced into blocks
16507
- findProp(node, 'key', true)));
16490
+ (tag === 'svg' || tag === 'foreignObject'));
16508
16491
  // props
16509
16492
  if (props.length > 0) {
16510
16493
  const propsBuildResult = buildProps(node, context);
@@ -16516,6 +16499,9 @@ const transformElement = (node, context) => {
16516
16499
  directives && directives.length
16517
16500
  ? createArrayExpression(directives.map(dir => buildDirectiveArgs(dir, context)))
16518
16501
  : undefined;
16502
+ if (propsBuildResult.shouldUseBlock) {
16503
+ shouldUseBlock = true;
16504
+ }
16519
16505
  }
16520
16506
  // children
16521
16507
  if (node.children.length > 0) {
@@ -16647,11 +16633,13 @@ function resolveComponentType(node, context, ssr = false) {
16647
16633
  return toValidAssetId(tag, `component`);
16648
16634
  }
16649
16635
  function buildProps(node, context, props = node.props, ssr = false) {
16650
- const { tag, loc: elementLoc } = node;
16636
+ const { tag, loc: elementLoc, children } = node;
16651
16637
  const isComponent = node.tagType === 1 /* COMPONENT */;
16652
16638
  let properties = [];
16653
16639
  const mergeArgs = [];
16654
16640
  const runtimeDirectives = [];
16641
+ const hasChildren = children.length > 0;
16642
+ let shouldUseBlock = false;
16655
16643
  // patchFlag analysis
16656
16644
  let patchFlag = 0;
16657
16645
  let hasRef = false;
@@ -16714,9 +16702,12 @@ function buildProps(node, context, props = node.props, ssr = false) {
16714
16702
  const prop = props[i];
16715
16703
  if (prop.type === 6 /* ATTRIBUTE */) {
16716
16704
  const { loc, name, value } = prop;
16717
- let valueNode = createSimpleExpression(value ? value.content : '', true, value ? value.loc : loc);
16705
+ let isStatic = true;
16718
16706
  if (name === 'ref') {
16719
16707
  hasRef = true;
16708
+ if (context.scopes.vFor > 0) {
16709
+ properties.push(createObjectProperty(createSimpleExpression('ref_for', true), createSimpleExpression('true')));
16710
+ }
16720
16711
  }
16721
16712
  // skip is on <component>, or is="vue:xxx"
16722
16713
  if (name === 'is' &&
@@ -16725,7 +16716,7 @@ function buildProps(node, context, props = node.props, ssr = false) {
16725
16716
  (isCompatEnabled$1("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context)))) {
16726
16717
  continue;
16727
16718
  }
16728
- properties.push(createObjectProperty(createSimpleExpression(name, true, getInnerRange(loc, 0, name.length)), valueNode));
16719
+ properties.push(createObjectProperty(createSimpleExpression(name, true, getInnerRange(loc, 0, name.length)), createSimpleExpression(value ? value.content : '', isStatic, value ? value.loc : loc)));
16729
16720
  }
16730
16721
  else {
16731
16722
  // directives
@@ -16746,7 +16737,7 @@ function buildProps(node, context, props = node.props, ssr = false) {
16746
16737
  // skip v-is and :is on <component>
16747
16738
  if (name === 'is' ||
16748
16739
  (isVBind &&
16749
- isBindKey(arg, 'is') &&
16740
+ isStaticArgOf(arg, 'is') &&
16750
16741
  (isComponentTag(tag) ||
16751
16742
  (isCompatEnabled$1("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context))))) {
16752
16743
  continue;
@@ -16755,6 +16746,17 @@ function buildProps(node, context, props = node.props, ssr = false) {
16755
16746
  if (isVOn && ssr) {
16756
16747
  continue;
16757
16748
  }
16749
+ if (
16750
+ // #938: elements with dynamic keys should be forced into blocks
16751
+ (isVBind && isStaticArgOf(arg, 'key')) ||
16752
+ // inline before-update hooks need to force block so that it is invoked
16753
+ // before children
16754
+ (isVOn && hasChildren && isStaticArgOf(arg, 'vue:before-update'))) {
16755
+ shouldUseBlock = true;
16756
+ }
16757
+ if (isVBind && isStaticArgOf(arg, 'ref') && context.scopes.vFor > 0) {
16758
+ properties.push(createObjectProperty(createSimpleExpression('ref_for', true), createSimpleExpression('true')));
16759
+ }
16758
16760
  // special case for v-bind and v-on with no argument
16759
16761
  if (!arg && (isVBind || isVOn)) {
16760
16762
  hasDynamicKeys = true;
@@ -16828,14 +16830,13 @@ function buildProps(node, context, props = node.props, ssr = false) {
16828
16830
  else {
16829
16831
  // no built-in transform, this is a user custom directive.
16830
16832
  runtimeDirectives.push(prop);
16833
+ // custom dirs may use beforeUpdate so they need to force blocks
16834
+ // to ensure before-update gets called before children update
16835
+ if (hasChildren) {
16836
+ shouldUseBlock = true;
16837
+ }
16831
16838
  }
16832
16839
  }
16833
- if (prop.type === 6 /* ATTRIBUTE */ &&
16834
- prop.name === 'ref' &&
16835
- context.scopes.vFor > 0 &&
16836
- checkCompatEnabled$1("COMPILER_V_FOR_REF" /* COMPILER_V_FOR_REF */, context, prop.loc)) {
16837
- properties.push(createObjectProperty(createSimpleExpression('refInFor', true), createSimpleExpression('true', false)));
16838
- }
16839
16840
  }
16840
16841
  let propsExpression = undefined;
16841
16842
  // has v-bind="object" or v-on="object", wrap with mergeProps
@@ -16872,7 +16873,8 @@ function buildProps(node, context, props = node.props, ssr = false) {
16872
16873
  patchFlag |= 32 /* HYDRATE_EVENTS */;
16873
16874
  }
16874
16875
  }
16875
- if ((patchFlag === 0 || patchFlag === 32 /* HYDRATE_EVENTS */) &&
16876
+ if (!shouldUseBlock &&
16877
+ (patchFlag === 0 || patchFlag === 32 /* HYDRATE_EVENTS */) &&
16876
16878
  (hasRef || hasVnodeHook || runtimeDirectives.length > 0)) {
16877
16879
  patchFlag |= 512 /* NEED_PATCH */;
16878
16880
  }
@@ -16939,7 +16941,8 @@ function buildProps(node, context, props = node.props, ssr = false) {
16939
16941
  props: propsExpression,
16940
16942
  directives: runtimeDirectives,
16941
16943
  patchFlag,
16942
- dynamicPropNames
16944
+ dynamicPropNames,
16945
+ shouldUseBlock
16943
16946
  };
16944
16947
  }
16945
16948
  // Dedupe props in an object literal.
@@ -17075,7 +17078,7 @@ function processSlotOutlet(node, context) {
17075
17078
  }
17076
17079
  }
17077
17080
  else {
17078
- if (p.name === 'bind' && isBindKey(p.arg, 'name')) {
17081
+ if (p.name === 'bind' && isStaticArgOf(p.arg, 'name')) {
17079
17082
  if (p.exp)
17080
17083
  slotName = p.exp;
17081
17084
  }
@@ -17109,7 +17112,11 @@ const transformOn = (dir, node, context, augmentor) => {
17109
17112
  let eventName;
17110
17113
  if (arg.type === 4 /* SIMPLE_EXPRESSION */) {
17111
17114
  if (arg.isStatic) {
17112
- const rawName = arg.content;
17115
+ let rawName = arg.content;
17116
+ // TODO deprecate @vnodeXXX usage
17117
+ if (rawName.startsWith('vue:')) {
17118
+ rawName = `vnode-${rawName.slice(4)}`;
17119
+ }
17113
17120
  // for all event listeners, auto convert it to camelCase. See issue #2249
17114
17121
  eventName = createSimpleExpression(toHandlerKey(camelize(rawName)), true, arg.loc);
17115
17122
  }