@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.
package/dist/vue.cjs.js CHANGED
@@ -113,7 +113,7 @@ const specialBooleanAttrs = `itemscope,allowfullscreen,formnovalidate,ismap,nomo
113
113
  const isSpecialBooleanAttr = /*#__PURE__*/ makeMap(specialBooleanAttrs);
114
114
  /**
115
115
  * Boolean attributes should be included if the value is truthy or ''.
116
- * e.g. <select multiple> compiles to { multiple: '' }
116
+ * e.g. `<select multiple>` compiles to `{ multiple: '' }`
117
117
  */
118
118
  function includeBooleanAttr(value) {
119
119
  return !!value || value === '';
@@ -478,7 +478,7 @@ const isIntegerKey = (key) => isString(key) &&
478
478
  '' + parseInt(key, 10) === key;
479
479
  const isReservedProp = /*#__PURE__*/ makeMap(
480
480
  // the leading comma is intentional so empty string "" is also included
481
- ',key,ref,' +
481
+ ',key,ref,ref_for,ref_key,' +
482
482
  'onVnodeBeforeMount,onVnodeMounted,' +
483
483
  'onVnodeBeforeUpdate,onVnodeUpdated,' +
484
484
  'onVnodeBeforeUnmount,onVnodeUnmounted');
@@ -1573,21 +1573,25 @@ function toRefs(object) {
1573
1573
  return ret;
1574
1574
  }
1575
1575
  class ObjectRefImpl {
1576
- constructor(_object, _key) {
1576
+ constructor(_object, _key, _defaultValue) {
1577
1577
  this._object = _object;
1578
1578
  this._key = _key;
1579
+ this._defaultValue = _defaultValue;
1579
1580
  this.__v_isRef = true;
1580
1581
  }
1581
1582
  get value() {
1582
- return this._object[this._key];
1583
+ const val = this._object[this._key];
1584
+ return val === undefined ? this._defaultValue : val;
1583
1585
  }
1584
1586
  set value(newVal) {
1585
1587
  this._object[this._key] = newVal;
1586
1588
  }
1587
1589
  }
1588
- function toRef(object, key) {
1590
+ function toRef(object, key, defaultValue) {
1589
1591
  const val = object[key];
1590
- return isRef(val) ? val : new ObjectRefImpl(object, key);
1592
+ return isRef(val)
1593
+ ? val
1594
+ : new ObjectRefImpl(object, key, defaultValue);
1591
1595
  }
1592
1596
 
1593
1597
  class ComputedRefImpl {
@@ -2033,11 +2037,6 @@ const deprecationData = {
2033
2037
  `Use "${newHook}" instead.`,
2034
2038
  link: `https://v3.vuejs.org/guide/migration/custom-directives.html`
2035
2039
  },
2036
- ["V_FOR_REF" /* V_FOR_REF */]: {
2037
- message: `Ref usage on v-for no longer creates array ref values in Vue 3. ` +
2038
- `Consider using function refs or refactor to avoid ref usage altogether.`,
2039
- link: `https://v3.vuejs.org/guide/migration/array-refs.html`
2040
- },
2041
2040
  ["V_ON_KEYCODE_MODIFIER" /* V_ON_KEYCODE_MODIFIER */]: {
2042
2041
  message: `Using keyCode as v-on modifier is no longer supported. ` +
2043
2042
  `Use kebab-case key name modifiers instead.`,
@@ -5450,7 +5449,7 @@ function createCompatVue(createApp, createSingletonApp) {
5450
5449
  return vm;
5451
5450
  }
5452
5451
  }
5453
- Vue.version = "3.2.24";
5452
+ Vue.version = "3.2.25";
5454
5453
  Vue.config = singletonApp.config;
5455
5454
  Vue.use = (p, ...options) => {
5456
5455
  if (p && isFunction(p.install)) {
@@ -5801,7 +5800,7 @@ const methodsToPatch = [
5801
5800
  ];
5802
5801
  const patched = new WeakSet();
5803
5802
  function defineReactive(obj, key, val) {
5804
- // it's possible for the orignial object to be mutated after being defined
5803
+ // it's possible for the original object to be mutated after being defined
5805
5804
  // and expecting reactivity... we are covering it here because this seems to
5806
5805
  // be a bit more common.
5807
5806
  if (isObject(val) && !isReactive(val) && !patched.has(val)) {
@@ -6021,6 +6020,102 @@ function createAppAPI(render, hydrate) {
6021
6020
  };
6022
6021
  }
6023
6022
 
6023
+ /**
6024
+ * Function for handling a template ref
6025
+ */
6026
+ function setRef(rawRef, oldRawRef, parentSuspense, vnode, isUnmount = false) {
6027
+ if (isArray(rawRef)) {
6028
+ rawRef.forEach((r, i) => setRef(r, oldRawRef && (isArray(oldRawRef) ? oldRawRef[i] : oldRawRef), parentSuspense, vnode, isUnmount));
6029
+ return;
6030
+ }
6031
+ if (isAsyncWrapper(vnode) && !isUnmount) {
6032
+ // when mounting async components, nothing needs to be done,
6033
+ // because the template ref is forwarded to inner component
6034
+ return;
6035
+ }
6036
+ const refValue = vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */
6037
+ ? getExposeProxy(vnode.component) || vnode.component.proxy
6038
+ : vnode.el;
6039
+ const value = isUnmount ? null : refValue;
6040
+ const { i: owner, r: ref } = rawRef;
6041
+ if (!owner) {
6042
+ warn$1(`Missing ref owner context. ref cannot be used on hoisted vnodes. ` +
6043
+ `A vnode with ref must be created inside the render function.`);
6044
+ return;
6045
+ }
6046
+ const oldRef = oldRawRef && oldRawRef.r;
6047
+ const refs = owner.refs === EMPTY_OBJ ? (owner.refs = {}) : owner.refs;
6048
+ const setupState = owner.setupState;
6049
+ // dynamic ref changed. unset old ref
6050
+ if (oldRef != null && oldRef !== ref) {
6051
+ if (isString(oldRef)) {
6052
+ refs[oldRef] = null;
6053
+ if (hasOwn(setupState, oldRef)) {
6054
+ setupState[oldRef] = null;
6055
+ }
6056
+ }
6057
+ else if (isRef(oldRef)) {
6058
+ oldRef.value = null;
6059
+ }
6060
+ }
6061
+ if (isFunction(ref)) {
6062
+ callWithErrorHandling(ref, owner, 12 /* FUNCTION_REF */, [value, refs]);
6063
+ }
6064
+ else {
6065
+ const _isString = isString(ref);
6066
+ const _isRef = isRef(ref);
6067
+ if (_isString || _isRef) {
6068
+ const doSet = () => {
6069
+ if (rawRef.f) {
6070
+ const existing = _isString ? refs[ref] : ref.value;
6071
+ if (isUnmount) {
6072
+ isArray(existing) && remove(existing, refValue);
6073
+ }
6074
+ else {
6075
+ if (!isArray(existing)) {
6076
+ if (_isString) {
6077
+ refs[ref] = [refValue];
6078
+ }
6079
+ else {
6080
+ ref.value = [refValue];
6081
+ if (rawRef.k)
6082
+ refs[rawRef.k] = ref.value;
6083
+ }
6084
+ }
6085
+ else if (!existing.includes(refValue)) {
6086
+ existing.push(refValue);
6087
+ }
6088
+ }
6089
+ }
6090
+ else if (_isString) {
6091
+ refs[ref] = value;
6092
+ if (hasOwn(setupState, ref)) {
6093
+ setupState[ref] = value;
6094
+ }
6095
+ }
6096
+ else if (isRef(ref)) {
6097
+ ref.value = value;
6098
+ if (rawRef.k)
6099
+ refs[rawRef.k] = value;
6100
+ }
6101
+ else {
6102
+ warn$1('Invalid template ref type:', ref, `(${typeof ref})`);
6103
+ }
6104
+ };
6105
+ if (value) {
6106
+ doSet.id = -1;
6107
+ queuePostRenderEffect(doSet, parentSuspense);
6108
+ }
6109
+ else {
6110
+ doSet();
6111
+ }
6112
+ }
6113
+ else {
6114
+ warn$1('Invalid template ref type:', ref, `(${typeof ref})`);
6115
+ }
6116
+ }
6117
+ }
6118
+
6024
6119
  let hasMismatch = false;
6025
6120
  const isSVGContainer = (container) => /svg/.test(container.namespaceURI) && container.tagName !== 'foreignObject';
6026
6121
  const isComment = (node) => node.nodeType === 8 /* COMMENT */;
@@ -6382,44 +6477,6 @@ function isSupported() {
6382
6477
  return supported;
6383
6478
  }
6384
6479
 
6385
- function convertLegacyRefInFor(vnode) {
6386
- // refInFor
6387
- if (vnode.props && vnode.props.refInFor) {
6388
- delete vnode.props.refInFor;
6389
- if (vnode.ref) {
6390
- if (isArray(vnode.ref)) {
6391
- vnode.ref.forEach(r => (r.f = true));
6392
- }
6393
- else {
6394
- vnode.ref.f = true;
6395
- }
6396
- }
6397
- }
6398
- }
6399
- function registerLegacyRef(refs, key, value, owner, isInFor, isUnmount) {
6400
- const existing = refs[key];
6401
- if (isUnmount) {
6402
- if (isArray(existing)) {
6403
- remove(existing, value);
6404
- }
6405
- else {
6406
- refs[key] = null;
6407
- }
6408
- }
6409
- else if (isInFor) {
6410
- warnDeprecation("V_FOR_REF" /* V_FOR_REF */, owner);
6411
- if (!isArray(existing)) {
6412
- refs[key] = [value];
6413
- }
6414
- else if (!existing.includes(value)) {
6415
- existing.push(value);
6416
- }
6417
- }
6418
- else {
6419
- refs[key] = value;
6420
- }
6421
- }
6422
-
6423
6480
  const queuePostRenderEffect = queueEffectWithSuspense
6424
6481
  ;
6425
6482
  /**
@@ -6691,12 +6748,15 @@ function baseCreateRenderer(options, createHydrationFns) {
6691
6748
  const oldProps = n1.props || EMPTY_OBJ;
6692
6749
  const newProps = n2.props || EMPTY_OBJ;
6693
6750
  let vnodeHook;
6751
+ // disable recurse in beforeUpdate hooks
6752
+ parentComponent && toggleRecurse(parentComponent, false);
6694
6753
  if ((vnodeHook = newProps.onVnodeBeforeUpdate)) {
6695
6754
  invokeVNodeHook(vnodeHook, parentComponent, n2, n1);
6696
6755
  }
6697
6756
  if (dirs) {
6698
6757
  invokeDirectiveHook(n2, n1, parentComponent, 'beforeUpdate');
6699
6758
  }
6759
+ parentComponent && toggleRecurse(parentComponent, true);
6700
6760
  if (isHmrUpdating) {
6701
6761
  // HMR updated, force full diff
6702
6762
  patchFlag = 0;
@@ -6980,7 +7040,7 @@ function baseCreateRenderer(options, createHydrationFns) {
6980
7040
  const { el, props } = initialVNode;
6981
7041
  const { bm, m, parent } = instance;
6982
7042
  const isAsyncWrapperVNode = isAsyncWrapper(initialVNode);
6983
- effect.allowRecurse = false;
7043
+ toggleRecurse(instance, false);
6984
7044
  // beforeMount hook
6985
7045
  if (bm) {
6986
7046
  invokeArrayFns(bm);
@@ -6993,7 +7053,7 @@ function baseCreateRenderer(options, createHydrationFns) {
6993
7053
  if (isCompatEnabled("INSTANCE_EVENT_HOOKS" /* INSTANCE_EVENT_HOOKS */, instance)) {
6994
7054
  instance.emit('hook:beforeMount');
6995
7055
  }
6996
- effect.allowRecurse = true;
7056
+ toggleRecurse(instance, true);
6997
7057
  if (el && hydrateNode) {
6998
7058
  // vnode has adopted host node - perform hydration instead of mount.
6999
7059
  const hydrateSubTree = () => {
@@ -7081,7 +7141,7 @@ function baseCreateRenderer(options, createHydrationFns) {
7081
7141
  pushWarningContext(next || instance.vnode);
7082
7142
  }
7083
7143
  // Disallow component effect recursion during pre-lifecycle hooks.
7084
- effect.allowRecurse = false;
7144
+ toggleRecurse(instance, false);
7085
7145
  if (next) {
7086
7146
  next.el = vnode.el;
7087
7147
  updateComponentPreRender(instance, next, optimized);
@@ -7100,7 +7160,7 @@ function baseCreateRenderer(options, createHydrationFns) {
7100
7160
  if (isCompatEnabled("INSTANCE_EVENT_HOOKS" /* INSTANCE_EVENT_HOOKS */, instance)) {
7101
7161
  instance.emit('hook:beforeUpdate');
7102
7162
  }
7103
- effect.allowRecurse = true;
7163
+ toggleRecurse(instance, true);
7104
7164
  // render
7105
7165
  {
7106
7166
  startMeasure(instance, `render`);
@@ -7149,13 +7209,13 @@ function baseCreateRenderer(options, createHydrationFns) {
7149
7209
  }
7150
7210
  };
7151
7211
  // create reactive effect for rendering
7152
- const effect = new ReactiveEffect(componentUpdateFn, () => queueJob(instance.update), instance.scope // track it in component's effect scope
7153
- );
7212
+ const effect = (instance.effect = new ReactiveEffect(componentUpdateFn, () => queueJob(instance.update), instance.scope // track it in component's effect scope
7213
+ ));
7154
7214
  const update = (instance.update = effect.run.bind(effect));
7155
7215
  update.id = instance.uid;
7156
7216
  // allowRecurse
7157
7217
  // #1801, #2043 component render effects should allow recursive updates
7158
- effect.allowRecurse = update.allowRecurse = true;
7218
+ toggleRecurse(instance, true);
7159
7219
  {
7160
7220
  effect.onTrack = instance.rtc
7161
7221
  ? e => invokeArrayFns(instance.rtc, e)
@@ -7685,88 +7745,8 @@ function baseCreateRenderer(options, createHydrationFns) {
7685
7745
  createApp: createAppAPI(render, hydrate)
7686
7746
  };
7687
7747
  }
7688
- function setRef(rawRef, oldRawRef, parentSuspense, vnode, isUnmount = false) {
7689
- if (isArray(rawRef)) {
7690
- rawRef.forEach((r, i) => setRef(r, oldRawRef && (isArray(oldRawRef) ? oldRawRef[i] : oldRawRef), parentSuspense, vnode, isUnmount));
7691
- return;
7692
- }
7693
- if (isAsyncWrapper(vnode) && !isUnmount) {
7694
- // when mounting async components, nothing needs to be done,
7695
- // because the template ref is forwarded to inner component
7696
- return;
7697
- }
7698
- const refValue = vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */
7699
- ? getExposeProxy(vnode.component) || vnode.component.proxy
7700
- : vnode.el;
7701
- const value = isUnmount ? null : refValue;
7702
- const { i: owner, r: ref } = rawRef;
7703
- if (!owner) {
7704
- warn$1(`Missing ref owner context. ref cannot be used on hoisted vnodes. ` +
7705
- `A vnode with ref must be created inside the render function.`);
7706
- return;
7707
- }
7708
- const oldRef = oldRawRef && oldRawRef.r;
7709
- const refs = owner.refs === EMPTY_OBJ ? (owner.refs = {}) : owner.refs;
7710
- const setupState = owner.setupState;
7711
- // dynamic ref changed. unset old ref
7712
- if (oldRef != null && oldRef !== ref) {
7713
- if (isString(oldRef)) {
7714
- refs[oldRef] = null;
7715
- if (hasOwn(setupState, oldRef)) {
7716
- setupState[oldRef] = null;
7717
- }
7718
- }
7719
- else if (isRef(oldRef)) {
7720
- oldRef.value = null;
7721
- }
7722
- }
7723
- if (isString(ref)) {
7724
- const doSet = () => {
7725
- if (isCompatEnabled("V_FOR_REF" /* V_FOR_REF */, owner)) {
7726
- registerLegacyRef(refs, ref, refValue, owner, rawRef.f, isUnmount);
7727
- }
7728
- else {
7729
- refs[ref] = value;
7730
- }
7731
- if (hasOwn(setupState, ref)) {
7732
- setupState[ref] = value;
7733
- }
7734
- };
7735
- // #1789: for non-null values, set them after render
7736
- // null values means this is unmount and it should not overwrite another
7737
- // ref with the same key
7738
- if (value) {
7739
- doSet.id = -1;
7740
- queuePostRenderEffect(doSet, parentSuspense);
7741
- }
7742
- else {
7743
- doSet();
7744
- }
7745
- }
7746
- else if (isRef(ref)) {
7747
- const doSet = () => {
7748
- ref.value = value;
7749
- };
7750
- if (value) {
7751
- doSet.id = -1;
7752
- queuePostRenderEffect(doSet, parentSuspense);
7753
- }
7754
- else {
7755
- doSet();
7756
- }
7757
- }
7758
- else if (isFunction(ref)) {
7759
- callWithErrorHandling(ref, owner, 12 /* FUNCTION_REF */, [value, refs]);
7760
- }
7761
- else {
7762
- warn$1('Invalid template ref type:', value, `(${typeof value})`);
7763
- }
7764
- }
7765
- function invokeVNodeHook(hook, instance, vnode, prevVNode = null) {
7766
- callWithAsyncErrorHandling(hook, instance, 7 /* VNODE_HOOK */, [
7767
- vnode,
7768
- prevVNode
7769
- ]);
7748
+ function toggleRecurse({ effect, update }, allowed) {
7749
+ effect.allowRecurse = update.allowRecurse = allowed;
7770
7750
  }
7771
7751
  /**
7772
7752
  * #1156
@@ -8561,10 +8541,10 @@ const createVNodeWithArgsTransform = (...args) => {
8561
8541
  };
8562
8542
  const InternalObjectKey = `__vInternal`;
8563
8543
  const normalizeKey = ({ key }) => key != null ? key : null;
8564
- const normalizeRef = ({ ref }) => {
8544
+ const normalizeRef = ({ ref, ref_key, ref_for }) => {
8565
8545
  return (ref != null
8566
8546
  ? isString(ref) || isRef(ref) || isFunction(ref)
8567
- ? { i: currentRenderingInstance, r: ref }
8547
+ ? { i: currentRenderingInstance, r: ref, k: ref_key, f: !!ref_for }
8568
8548
  : ref
8569
8549
  : null);
8570
8550
  };
@@ -8632,7 +8612,6 @@ function createBaseVNode(type, props = null, children = null, patchFlag = 0, dyn
8632
8612
  }
8633
8613
  {
8634
8614
  convertLegacyVModelProps(vnode);
8635
- convertLegacyRefInFor(vnode);
8636
8615
  defineLegacyVNodeProperties(vnode);
8637
8616
  }
8638
8617
  return vnode;
@@ -8918,6 +8897,12 @@ function mergeProps(...args) {
8918
8897
  }
8919
8898
  }
8920
8899
  return ret;
8900
+ }
8901
+ function invokeVNodeHook(hook, instance, vnode, prevVNode = null) {
8902
+ callWithAsyncErrorHandling(hook, instance, 7 /* VNODE_HOOK */, [
8903
+ vnode,
8904
+ prevVNode
8905
+ ]);
8921
8906
  }
8922
8907
 
8923
8908
  function getCompatChildren(instance) {
@@ -9577,6 +9562,7 @@ function createComponentInstance(vnode, parent, suspense) {
9577
9562
  root: null,
9578
9563
  next: null,
9579
9564
  subTree: null,
9565
+ effect: null,
9580
9566
  update: null,
9581
9567
  scope: new EffectScope(true /* detached */),
9582
9568
  render: null,
@@ -11067,7 +11053,7 @@ function isMemoSame(cached, memo) {
11067
11053
  }
11068
11054
 
11069
11055
  // Core API ------------------------------------------------------------------
11070
- const version = "3.2.24";
11056
+ const version = "3.2.25";
11071
11057
  const _ssrUtils = {
11072
11058
  createComponentInstance,
11073
11059
  setupComponent,
@@ -13401,12 +13387,12 @@ function findProp(node, name, dynamicOnly = false, allowEmpty = false) {
13401
13387
  }
13402
13388
  else if (p.name === 'bind' &&
13403
13389
  (p.exp || allowEmpty) &&
13404
- isBindKey(p.arg, name)) {
13390
+ isStaticArgOf(p.arg, name)) {
13405
13391
  return p;
13406
13392
  }
13407
13393
  }
13408
13394
  }
13409
- function isBindKey(arg, name) {
13395
+ function isStaticArgOf(arg, name) {
13410
13396
  return !!(arg && isStaticExp(arg) && arg.content === name);
13411
13397
  }
13412
13398
  function hasDynamicKeyVBind(node) {
@@ -13639,11 +13625,6 @@ const deprecationData$1 = {
13639
13625
  `data source.`,
13640
13626
  link: `https://v3.vuejs.org/guide/migration/v-if-v-for.html`
13641
13627
  },
13642
- ["COMPILER_V_FOR_REF" /* COMPILER_V_FOR_REF */]: {
13643
- message: `Ref usage on v-for no longer creates array ref values in Vue 3. ` +
13644
- `Consider using function refs or refactor to avoid ref usage altogether.`,
13645
- link: `https://v3.vuejs.org/guide/migration/array-refs.html`
13646
- },
13647
13628
  ["COMPILER_NATIVE_TEMPLATE" /* COMPILER_NATIVE_TEMPLATE */]: {
13648
13629
  message: `<template> with no special directives will render as a native template ` +
13649
13630
  `element instead of its inner content in Vue 3.`
@@ -14161,7 +14142,7 @@ function isComponent(tag, props, context) {
14161
14142
  else if (
14162
14143
  // :is on plain element - only treat as component in compat mode
14163
14144
  p.name === 'bind' &&
14164
- isBindKey(p.arg, 'is') &&
14145
+ isStaticArgOf(p.arg, 'is') &&
14165
14146
  true &&
14166
14147
  checkCompatEnabled$1("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context, p.loc)) {
14167
14148
  return true;
@@ -14619,6 +14600,11 @@ function getConstantType(node, context) {
14619
14600
  if (codegenNode.type !== 13 /* VNODE_CALL */) {
14620
14601
  return 0 /* NOT_CONSTANT */;
14621
14602
  }
14603
+ if (codegenNode.isBlock &&
14604
+ node.tag !== 'svg' &&
14605
+ node.tag !== 'foreignObject') {
14606
+ return 0 /* NOT_CONSTANT */;
14607
+ }
14622
14608
  const flag = getPatchFlag(codegenNode);
14623
14609
  if (!flag) {
14624
14610
  let returnType = 3 /* CAN_STRINGIFY */;
@@ -14755,7 +14741,7 @@ function getGeneratedPropsConstantType(node, context) {
14755
14741
  else if (value.type === 14 /* JS_CALL_EXPRESSION */) {
14756
14742
  // some helper calls can be hoisted,
14757
14743
  // such as the `normalizeProps` generated by the compiler for pre-normalize class,
14758
- // in this case we need to respect the ConstantType of the helper's argments
14744
+ // in this case we need to respect the ConstantType of the helper's arguments
14759
14745
  valueType = getConstantTypeOfHelperCall(value, context);
14760
14746
  }
14761
14747
  else {
@@ -17209,10 +17195,7 @@ const transformElement = (node, context) => {
17209
17195
  // updates inside get proper isSVG flag at runtime. (#639, #643)
17210
17196
  // This is technically web-specific, but splitting the logic out of core
17211
17197
  // leads to too much unnecessary complexity.
17212
- (tag === 'svg' ||
17213
- tag === 'foreignObject' ||
17214
- // #938: elements with dynamic keys should be forced into blocks
17215
- findProp(node, 'key', true)));
17198
+ (tag === 'svg' || tag === 'foreignObject'));
17216
17199
  // props
17217
17200
  if (props.length > 0) {
17218
17201
  const propsBuildResult = buildProps(node, context);
@@ -17224,6 +17207,9 @@ const transformElement = (node, context) => {
17224
17207
  directives && directives.length
17225
17208
  ? createArrayExpression(directives.map(dir => buildDirectiveArgs(dir, context)))
17226
17209
  : undefined;
17210
+ if (propsBuildResult.shouldUseBlock) {
17211
+ shouldUseBlock = true;
17212
+ }
17227
17213
  }
17228
17214
  // children
17229
17215
  if (node.children.length > 0) {
@@ -17413,11 +17399,13 @@ function resolveSetupReference(name, context) {
17413
17399
  }
17414
17400
  }
17415
17401
  function buildProps(node, context, props = node.props, ssr = false) {
17416
- const { tag, loc: elementLoc } = node;
17402
+ const { tag, loc: elementLoc, children } = node;
17417
17403
  const isComponent = node.tagType === 1 /* COMPONENT */;
17418
17404
  let properties = [];
17419
17405
  const mergeArgs = [];
17420
17406
  const runtimeDirectives = [];
17407
+ const hasChildren = children.length > 0;
17408
+ let shouldUseBlock = false;
17421
17409
  // patchFlag analysis
17422
17410
  let patchFlag = 0;
17423
17411
  let hasRef = false;
@@ -17480,15 +17468,20 @@ function buildProps(node, context, props = node.props, ssr = false) {
17480
17468
  const prop = props[i];
17481
17469
  if (prop.type === 6 /* ATTRIBUTE */) {
17482
17470
  const { loc, name, value } = prop;
17483
- let valueNode = createSimpleExpression(value ? value.content : '', true, value ? value.loc : loc);
17471
+ let isStatic = true;
17484
17472
  if (name === 'ref') {
17485
17473
  hasRef = true;
17474
+ if (context.scopes.vFor > 0) {
17475
+ properties.push(createObjectProperty(createSimpleExpression('ref_for', true), createSimpleExpression('true')));
17476
+ }
17486
17477
  // in inline mode there is no setupState object, so we can't use string
17487
17478
  // keys to set the ref. Instead, we need to transform it to pass the
17488
17479
  // actual ref instead.
17489
- if (context.inline && (value === null || value === void 0 ? void 0 : value.content)) {
17490
- valueNode = createFunctionExpression(['_value', '_refs']);
17491
- valueNode.body = createBlockStatement(processInlineRef(context, value.content));
17480
+ if (value &&
17481
+ context.inline &&
17482
+ context.bindingMetadata[value.content]) {
17483
+ isStatic = false;
17484
+ properties.push(createObjectProperty(createSimpleExpression('ref_key', true), createSimpleExpression(value.content, true, value.loc)));
17492
17485
  }
17493
17486
  }
17494
17487
  // skip is on <component>, or is="vue:xxx"
@@ -17498,7 +17491,7 @@ function buildProps(node, context, props = node.props, ssr = false) {
17498
17491
  (isCompatEnabled$1("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context)))) {
17499
17492
  continue;
17500
17493
  }
17501
- properties.push(createObjectProperty(createSimpleExpression(name, true, getInnerRange(loc, 0, name.length)), valueNode));
17494
+ properties.push(createObjectProperty(createSimpleExpression(name, true, getInnerRange(loc, 0, name.length)), createSimpleExpression(value ? value.content : '', isStatic, value ? value.loc : loc)));
17502
17495
  }
17503
17496
  else {
17504
17497
  // directives
@@ -17519,7 +17512,7 @@ function buildProps(node, context, props = node.props, ssr = false) {
17519
17512
  // skip v-is and :is on <component>
17520
17513
  if (name === 'is' ||
17521
17514
  (isVBind &&
17522
- isBindKey(arg, 'is') &&
17515
+ isStaticArgOf(arg, 'is') &&
17523
17516
  (isComponentTag(tag) ||
17524
17517
  (isCompatEnabled$1("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context))))) {
17525
17518
  continue;
@@ -17528,6 +17521,17 @@ function buildProps(node, context, props = node.props, ssr = false) {
17528
17521
  if (isVOn && ssr) {
17529
17522
  continue;
17530
17523
  }
17524
+ if (
17525
+ // #938: elements with dynamic keys should be forced into blocks
17526
+ (isVBind && isStaticArgOf(arg, 'key')) ||
17527
+ // inline before-update hooks need to force block so that it is invoked
17528
+ // before children
17529
+ (isVOn && hasChildren && isStaticArgOf(arg, 'vue:before-update'))) {
17530
+ shouldUseBlock = true;
17531
+ }
17532
+ if (isVBind && isStaticArgOf(arg, 'ref') && context.scopes.vFor > 0) {
17533
+ properties.push(createObjectProperty(createSimpleExpression('ref_for', true), createSimpleExpression('true')));
17534
+ }
17531
17535
  // special case for v-bind and v-on with no argument
17532
17536
  if (!arg && (isVBind || isVOn)) {
17533
17537
  hasDynamicKeys = true;
@@ -17601,14 +17605,13 @@ function buildProps(node, context, props = node.props, ssr = false) {
17601
17605
  else {
17602
17606
  // no built-in transform, this is a user custom directive.
17603
17607
  runtimeDirectives.push(prop);
17608
+ // custom dirs may use beforeUpdate so they need to force blocks
17609
+ // to ensure before-update gets called before children update
17610
+ if (hasChildren) {
17611
+ shouldUseBlock = true;
17612
+ }
17604
17613
  }
17605
17614
  }
17606
- if (prop.type === 6 /* ATTRIBUTE */ &&
17607
- prop.name === 'ref' &&
17608
- context.scopes.vFor > 0 &&
17609
- checkCompatEnabled$1("COMPILER_V_FOR_REF" /* COMPILER_V_FOR_REF */, context, prop.loc)) {
17610
- properties.push(createObjectProperty(createSimpleExpression('refInFor', true), createSimpleExpression('true', false)));
17611
- }
17612
17615
  }
17613
17616
  let propsExpression = undefined;
17614
17617
  // has v-bind="object" or v-on="object", wrap with mergeProps
@@ -17645,7 +17648,8 @@ function buildProps(node, context, props = node.props, ssr = false) {
17645
17648
  patchFlag |= 32 /* HYDRATE_EVENTS */;
17646
17649
  }
17647
17650
  }
17648
- if ((patchFlag === 0 || patchFlag === 32 /* HYDRATE_EVENTS */) &&
17651
+ if (!shouldUseBlock &&
17652
+ (patchFlag === 0 || patchFlag === 32 /* HYDRATE_EVENTS */) &&
17649
17653
  (hasRef || hasVnodeHook || runtimeDirectives.length > 0)) {
17650
17654
  patchFlag |= 512 /* NEED_PATCH */;
17651
17655
  }
@@ -17712,7 +17716,8 @@ function buildProps(node, context, props = node.props, ssr = false) {
17712
17716
  props: propsExpression,
17713
17717
  directives: runtimeDirectives,
17714
17718
  patchFlag,
17715
- dynamicPropNames
17719
+ dynamicPropNames,
17720
+ shouldUseBlock
17716
17721
  };
17717
17722
  }
17718
17723
  // Dedupe props in an object literal.
@@ -17807,21 +17812,6 @@ function stringifyDynamicPropNames(props) {
17807
17812
  }
17808
17813
  function isComponentTag(tag) {
17809
17814
  return tag === 'component' || tag === 'Component';
17810
- }
17811
- function processInlineRef(context, raw) {
17812
- const body = [createSimpleExpression(`_refs['${raw}'] = _value`)];
17813
- const { bindingMetadata, helperString } = context;
17814
- const type = bindingMetadata[raw];
17815
- if (type === "setup-ref" /* SETUP_REF */) {
17816
- body.push(createSimpleExpression(`${raw}.value = _value`));
17817
- }
17818
- else if (type === "setup-maybe-ref" /* SETUP_MAYBE_REF */) {
17819
- body.push(createSimpleExpression(`${helperString(IS_REF)}(${raw}) && (${raw}.value = _value)`));
17820
- }
17821
- else if (type === "setup-let" /* SETUP_LET */) {
17822
- body.push(createSimpleExpression(`${helperString(IS_REF)}(${raw}) ? ${raw}.value = _value : ${raw} = _value`));
17823
- }
17824
- return body;
17825
17815
  }
17826
17816
 
17827
17817
  const transformSlotOutlet = (node, context) => {
@@ -17869,7 +17859,7 @@ function processSlotOutlet(node, context) {
17869
17859
  }
17870
17860
  }
17871
17861
  else {
17872
- if (p.name === 'bind' && isBindKey(p.arg, 'name')) {
17862
+ if (p.name === 'bind' && isStaticArgOf(p.arg, 'name')) {
17873
17863
  if (p.exp)
17874
17864
  slotName = p.exp;
17875
17865
  }
@@ -17903,7 +17893,11 @@ const transformOn = (dir, node, context, augmentor) => {
17903
17893
  let eventName;
17904
17894
  if (arg.type === 4 /* SIMPLE_EXPRESSION */) {
17905
17895
  if (arg.isStatic) {
17906
- const rawName = arg.content;
17896
+ let rawName = arg.content;
17897
+ // TODO deprecate @vnodeXXX usage
17898
+ if (rawName.startsWith('vue:')) {
17899
+ rawName = `vnode-${rawName.slice(4)}`;
17900
+ }
17907
17901
  // for all event listeners, auto convert it to camelCase. See issue #2249
17908
17902
  eventName = createSimpleExpression(toHandlerKey(camelize(rawName)), true, arg.loc);
17909
17903
  }