@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 === '';
@@ -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');
@@ -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 {
@@ -1896,11 +1900,6 @@ const deprecationData = {
1896
1900
  `Use "${newHook}" instead.`,
1897
1901
  link: `https://v3.vuejs.org/guide/migration/custom-directives.html`
1898
1902
  },
1899
- ["V_FOR_REF" /* V_FOR_REF */]: {
1900
- message: `Ref usage on v-for no longer creates array ref values in Vue 3. ` +
1901
- `Consider using function refs or refactor to avoid ref usage altogether.`,
1902
- link: `https://v3.vuejs.org/guide/migration/array-refs.html`
1903
- },
1904
1903
  ["V_ON_KEYCODE_MODIFIER" /* V_ON_KEYCODE_MODIFIER */]: {
1905
1904
  message: `Using keyCode as v-on modifier is no longer supported. ` +
1906
1905
  `Use kebab-case key name modifiers instead.`,
@@ -5313,7 +5312,7 @@ function createCompatVue(createApp, createSingletonApp) {
5313
5312
  return vm;
5314
5313
  }
5315
5314
  }
5316
- Vue.version = "3.2.24";
5315
+ Vue.version = "3.2.25";
5317
5316
  Vue.config = singletonApp.config;
5318
5317
  Vue.use = (p, ...options) => {
5319
5318
  if (p && isFunction(p.install)) {
@@ -5664,7 +5663,7 @@ const methodsToPatch = [
5664
5663
  ];
5665
5664
  const patched = new WeakSet();
5666
5665
  function defineReactive(obj, key, val) {
5667
- // it's possible for the orignial object to be mutated after being defined
5666
+ // it's possible for the original object to be mutated after being defined
5668
5667
  // and expecting reactivity... we are covering it here because this seems to
5669
5668
  // be a bit more common.
5670
5669
  if (isObject(val) && !isReactive(val) && !patched.has(val)) {
@@ -5884,6 +5883,102 @@ function createAppAPI(render, hydrate) {
5884
5883
  };
5885
5884
  }
5886
5885
 
5886
+ /**
5887
+ * Function for handling a template ref
5888
+ */
5889
+ function setRef(rawRef, oldRawRef, parentSuspense, vnode, isUnmount = false) {
5890
+ if (isArray(rawRef)) {
5891
+ rawRef.forEach((r, i) => setRef(r, oldRawRef && (isArray(oldRawRef) ? oldRawRef[i] : oldRawRef), parentSuspense, vnode, isUnmount));
5892
+ return;
5893
+ }
5894
+ if (isAsyncWrapper(vnode) && !isUnmount) {
5895
+ // when mounting async components, nothing needs to be done,
5896
+ // because the template ref is forwarded to inner component
5897
+ return;
5898
+ }
5899
+ const refValue = vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */
5900
+ ? getExposeProxy(vnode.component) || vnode.component.proxy
5901
+ : vnode.el;
5902
+ const value = isUnmount ? null : refValue;
5903
+ const { i: owner, r: ref } = rawRef;
5904
+ if (!owner) {
5905
+ warn$1(`Missing ref owner context. ref cannot be used on hoisted vnodes. ` +
5906
+ `A vnode with ref must be created inside the render function.`);
5907
+ return;
5908
+ }
5909
+ const oldRef = oldRawRef && oldRawRef.r;
5910
+ const refs = owner.refs === EMPTY_OBJ ? (owner.refs = {}) : owner.refs;
5911
+ const setupState = owner.setupState;
5912
+ // dynamic ref changed. unset old ref
5913
+ if (oldRef != null && oldRef !== ref) {
5914
+ if (isString(oldRef)) {
5915
+ refs[oldRef] = null;
5916
+ if (hasOwn(setupState, oldRef)) {
5917
+ setupState[oldRef] = null;
5918
+ }
5919
+ }
5920
+ else if (isRef(oldRef)) {
5921
+ oldRef.value = null;
5922
+ }
5923
+ }
5924
+ if (isFunction(ref)) {
5925
+ callWithErrorHandling(ref, owner, 12 /* FUNCTION_REF */, [value, refs]);
5926
+ }
5927
+ else {
5928
+ const _isString = isString(ref);
5929
+ const _isRef = isRef(ref);
5930
+ if (_isString || _isRef) {
5931
+ const doSet = () => {
5932
+ if (rawRef.f) {
5933
+ const existing = _isString ? refs[ref] : ref.value;
5934
+ if (isUnmount) {
5935
+ isArray(existing) && remove(existing, refValue);
5936
+ }
5937
+ else {
5938
+ if (!isArray(existing)) {
5939
+ if (_isString) {
5940
+ refs[ref] = [refValue];
5941
+ }
5942
+ else {
5943
+ ref.value = [refValue];
5944
+ if (rawRef.k)
5945
+ refs[rawRef.k] = ref.value;
5946
+ }
5947
+ }
5948
+ else if (!existing.includes(refValue)) {
5949
+ existing.push(refValue);
5950
+ }
5951
+ }
5952
+ }
5953
+ else if (_isString) {
5954
+ refs[ref] = value;
5955
+ if (hasOwn(setupState, ref)) {
5956
+ setupState[ref] = value;
5957
+ }
5958
+ }
5959
+ else if (isRef(ref)) {
5960
+ ref.value = value;
5961
+ if (rawRef.k)
5962
+ refs[rawRef.k] = value;
5963
+ }
5964
+ else {
5965
+ warn$1('Invalid template ref type:', ref, `(${typeof ref})`);
5966
+ }
5967
+ };
5968
+ if (value) {
5969
+ doSet.id = -1;
5970
+ queuePostRenderEffect(doSet, parentSuspense);
5971
+ }
5972
+ else {
5973
+ doSet();
5974
+ }
5975
+ }
5976
+ else {
5977
+ warn$1('Invalid template ref type:', ref, `(${typeof ref})`);
5978
+ }
5979
+ }
5980
+ }
5981
+
5887
5982
  let hasMismatch = false;
5888
5983
  const isSVGContainer = (container) => /svg/.test(container.namespaceURI) && container.tagName !== 'foreignObject';
5889
5984
  const isComment = (node) => node.nodeType === 8 /* COMMENT */;
@@ -6245,44 +6340,6 @@ function isSupported() {
6245
6340
  return supported;
6246
6341
  }
6247
6342
 
6248
- function convertLegacyRefInFor(vnode) {
6249
- // refInFor
6250
- if (vnode.props && vnode.props.refInFor) {
6251
- delete vnode.props.refInFor;
6252
- if (vnode.ref) {
6253
- if (isArray(vnode.ref)) {
6254
- vnode.ref.forEach(r => (r.f = true));
6255
- }
6256
- else {
6257
- vnode.ref.f = true;
6258
- }
6259
- }
6260
- }
6261
- }
6262
- function registerLegacyRef(refs, key, value, owner, isInFor, isUnmount) {
6263
- const existing = refs[key];
6264
- if (isUnmount) {
6265
- if (isArray(existing)) {
6266
- remove(existing, value);
6267
- }
6268
- else {
6269
- refs[key] = null;
6270
- }
6271
- }
6272
- else if (isInFor) {
6273
- warnDeprecation("V_FOR_REF" /* V_FOR_REF */, owner);
6274
- if (!isArray(existing)) {
6275
- refs[key] = [value];
6276
- }
6277
- else if (!existing.includes(value)) {
6278
- existing.push(value);
6279
- }
6280
- }
6281
- else {
6282
- refs[key] = value;
6283
- }
6284
- }
6285
-
6286
6343
  const queuePostRenderEffect = queueEffectWithSuspense
6287
6344
  ;
6288
6345
  /**
@@ -6554,12 +6611,15 @@ function baseCreateRenderer(options, createHydrationFns) {
6554
6611
  const oldProps = n1.props || EMPTY_OBJ;
6555
6612
  const newProps = n2.props || EMPTY_OBJ;
6556
6613
  let vnodeHook;
6614
+ // disable recurse in beforeUpdate hooks
6615
+ parentComponent && toggleRecurse(parentComponent, false);
6557
6616
  if ((vnodeHook = newProps.onVnodeBeforeUpdate)) {
6558
6617
  invokeVNodeHook(vnodeHook, parentComponent, n2, n1);
6559
6618
  }
6560
6619
  if (dirs) {
6561
6620
  invokeDirectiveHook(n2, n1, parentComponent, 'beforeUpdate');
6562
6621
  }
6622
+ parentComponent && toggleRecurse(parentComponent, true);
6563
6623
  if (isHmrUpdating) {
6564
6624
  // HMR updated, force full diff
6565
6625
  patchFlag = 0;
@@ -6843,7 +6903,7 @@ function baseCreateRenderer(options, createHydrationFns) {
6843
6903
  const { el, props } = initialVNode;
6844
6904
  const { bm, m, parent } = instance;
6845
6905
  const isAsyncWrapperVNode = isAsyncWrapper(initialVNode);
6846
- effect.allowRecurse = false;
6906
+ toggleRecurse(instance, false);
6847
6907
  // beforeMount hook
6848
6908
  if (bm) {
6849
6909
  invokeArrayFns(bm);
@@ -6856,7 +6916,7 @@ function baseCreateRenderer(options, createHydrationFns) {
6856
6916
  if (isCompatEnabled("INSTANCE_EVENT_HOOKS" /* INSTANCE_EVENT_HOOKS */, instance)) {
6857
6917
  instance.emit('hook:beforeMount');
6858
6918
  }
6859
- effect.allowRecurse = true;
6919
+ toggleRecurse(instance, true);
6860
6920
  if (el && hydrateNode) {
6861
6921
  // vnode has adopted host node - perform hydration instead of mount.
6862
6922
  const hydrateSubTree = () => {
@@ -6944,7 +7004,7 @@ function baseCreateRenderer(options, createHydrationFns) {
6944
7004
  pushWarningContext(next || instance.vnode);
6945
7005
  }
6946
7006
  // Disallow component effect recursion during pre-lifecycle hooks.
6947
- effect.allowRecurse = false;
7007
+ toggleRecurse(instance, false);
6948
7008
  if (next) {
6949
7009
  next.el = vnode.el;
6950
7010
  updateComponentPreRender(instance, next, optimized);
@@ -6963,7 +7023,7 @@ function baseCreateRenderer(options, createHydrationFns) {
6963
7023
  if (isCompatEnabled("INSTANCE_EVENT_HOOKS" /* INSTANCE_EVENT_HOOKS */, instance)) {
6964
7024
  instance.emit('hook:beforeUpdate');
6965
7025
  }
6966
- effect.allowRecurse = true;
7026
+ toggleRecurse(instance, true);
6967
7027
  // render
6968
7028
  {
6969
7029
  startMeasure(instance, `render`);
@@ -7012,13 +7072,13 @@ function baseCreateRenderer(options, createHydrationFns) {
7012
7072
  }
7013
7073
  };
7014
7074
  // create reactive effect for rendering
7015
- const effect = new ReactiveEffect(componentUpdateFn, () => queueJob(instance.update), instance.scope // track it in component's effect scope
7016
- );
7075
+ const effect = (instance.effect = new ReactiveEffect(componentUpdateFn, () => queueJob(instance.update), instance.scope // track it in component's effect scope
7076
+ ));
7017
7077
  const update = (instance.update = effect.run.bind(effect));
7018
7078
  update.id = instance.uid;
7019
7079
  // allowRecurse
7020
7080
  // #1801, #2043 component render effects should allow recursive updates
7021
- effect.allowRecurse = update.allowRecurse = true;
7081
+ toggleRecurse(instance, true);
7022
7082
  {
7023
7083
  effect.onTrack = instance.rtc
7024
7084
  ? e => invokeArrayFns(instance.rtc, e)
@@ -7548,88 +7608,8 @@ function baseCreateRenderer(options, createHydrationFns) {
7548
7608
  createApp: createAppAPI(render, hydrate)
7549
7609
  };
7550
7610
  }
7551
- function setRef(rawRef, oldRawRef, parentSuspense, vnode, isUnmount = false) {
7552
- if (isArray(rawRef)) {
7553
- rawRef.forEach((r, i) => setRef(r, oldRawRef && (isArray(oldRawRef) ? oldRawRef[i] : oldRawRef), parentSuspense, vnode, isUnmount));
7554
- return;
7555
- }
7556
- if (isAsyncWrapper(vnode) && !isUnmount) {
7557
- // when mounting async components, nothing needs to be done,
7558
- // because the template ref is forwarded to inner component
7559
- return;
7560
- }
7561
- const refValue = vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */
7562
- ? getExposeProxy(vnode.component) || vnode.component.proxy
7563
- : vnode.el;
7564
- const value = isUnmount ? null : refValue;
7565
- const { i: owner, r: ref } = rawRef;
7566
- if (!owner) {
7567
- warn$1(`Missing ref owner context. ref cannot be used on hoisted vnodes. ` +
7568
- `A vnode with ref must be created inside the render function.`);
7569
- return;
7570
- }
7571
- const oldRef = oldRawRef && oldRawRef.r;
7572
- const refs = owner.refs === EMPTY_OBJ ? (owner.refs = {}) : owner.refs;
7573
- const setupState = owner.setupState;
7574
- // dynamic ref changed. unset old ref
7575
- if (oldRef != null && oldRef !== ref) {
7576
- if (isString(oldRef)) {
7577
- refs[oldRef] = null;
7578
- if (hasOwn(setupState, oldRef)) {
7579
- setupState[oldRef] = null;
7580
- }
7581
- }
7582
- else if (isRef(oldRef)) {
7583
- oldRef.value = null;
7584
- }
7585
- }
7586
- if (isString(ref)) {
7587
- const doSet = () => {
7588
- if (isCompatEnabled("V_FOR_REF" /* V_FOR_REF */, owner)) {
7589
- registerLegacyRef(refs, ref, refValue, owner, rawRef.f, isUnmount);
7590
- }
7591
- else {
7592
- refs[ref] = value;
7593
- }
7594
- if (hasOwn(setupState, ref)) {
7595
- setupState[ref] = value;
7596
- }
7597
- };
7598
- // #1789: for non-null values, set them after render
7599
- // null values means this is unmount and it should not overwrite another
7600
- // ref with the same key
7601
- if (value) {
7602
- doSet.id = -1;
7603
- queuePostRenderEffect(doSet, parentSuspense);
7604
- }
7605
- else {
7606
- doSet();
7607
- }
7608
- }
7609
- else if (isRef(ref)) {
7610
- const doSet = () => {
7611
- ref.value = value;
7612
- };
7613
- if (value) {
7614
- doSet.id = -1;
7615
- queuePostRenderEffect(doSet, parentSuspense);
7616
- }
7617
- else {
7618
- doSet();
7619
- }
7620
- }
7621
- else if (isFunction(ref)) {
7622
- callWithErrorHandling(ref, owner, 12 /* FUNCTION_REF */, [value, refs]);
7623
- }
7624
- else {
7625
- warn$1('Invalid template ref type:', value, `(${typeof value})`);
7626
- }
7627
- }
7628
- function invokeVNodeHook(hook, instance, vnode, prevVNode = null) {
7629
- callWithAsyncErrorHandling(hook, instance, 7 /* VNODE_HOOK */, [
7630
- vnode,
7631
- prevVNode
7632
- ]);
7611
+ function toggleRecurse({ effect, update }, allowed) {
7612
+ effect.allowRecurse = update.allowRecurse = allowed;
7633
7613
  }
7634
7614
  /**
7635
7615
  * #1156
@@ -8424,10 +8404,10 @@ const createVNodeWithArgsTransform = (...args) => {
8424
8404
  };
8425
8405
  const InternalObjectKey = `__vInternal`;
8426
8406
  const normalizeKey = ({ key }) => key != null ? key : null;
8427
- const normalizeRef = ({ ref }) => {
8407
+ const normalizeRef = ({ ref, ref_key, ref_for }) => {
8428
8408
  return (ref != null
8429
8409
  ? isString(ref) || isRef(ref) || isFunction(ref)
8430
- ? { i: currentRenderingInstance, r: ref }
8410
+ ? { i: currentRenderingInstance, r: ref, k: ref_key, f: !!ref_for }
8431
8411
  : ref
8432
8412
  : null);
8433
8413
  };
@@ -8495,7 +8475,6 @@ function createBaseVNode(type, props = null, children = null, patchFlag = 0, dyn
8495
8475
  }
8496
8476
  {
8497
8477
  convertLegacyVModelProps(vnode);
8498
- convertLegacyRefInFor(vnode);
8499
8478
  defineLegacyVNodeProperties(vnode);
8500
8479
  }
8501
8480
  return vnode;
@@ -8781,6 +8760,12 @@ function mergeProps(...args) {
8781
8760
  }
8782
8761
  }
8783
8762
  return ret;
8763
+ }
8764
+ function invokeVNodeHook(hook, instance, vnode, prevVNode = null) {
8765
+ callWithAsyncErrorHandling(hook, instance, 7 /* VNODE_HOOK */, [
8766
+ vnode,
8767
+ prevVNode
8768
+ ]);
8784
8769
  }
8785
8770
 
8786
8771
  function getCompatChildren(instance) {
@@ -9440,6 +9425,7 @@ function createComponentInstance(vnode, parent, suspense) {
9440
9425
  root: null,
9441
9426
  next: null,
9442
9427
  subTree: null,
9428
+ effect: null,
9443
9429
  update: null,
9444
9430
  scope: new EffectScope(true /* detached */),
9445
9431
  render: null,
@@ -10909,7 +10895,7 @@ function isMemoSame(cached, memo) {
10909
10895
  }
10910
10896
 
10911
10897
  // Core API ------------------------------------------------------------------
10912
- const version = "3.2.24";
10898
+ const version = "3.2.25";
10913
10899
  /**
10914
10900
  * SSR utils for \@vue/server-renderer. Only exposed in cjs builds.
10915
10901
  * @internal
@@ -13320,12 +13306,12 @@ function findProp(node, name, dynamicOnly = false, allowEmpty = false) {
13320
13306
  }
13321
13307
  else if (p.name === 'bind' &&
13322
13308
  (p.exp || allowEmpty) &&
13323
- isBindKey(p.arg, name)) {
13309
+ isStaticArgOf(p.arg, name)) {
13324
13310
  return p;
13325
13311
  }
13326
13312
  }
13327
13313
  }
13328
- function isBindKey(arg, name) {
13314
+ function isStaticArgOf(arg, name) {
13329
13315
  return !!(arg && isStaticExp(arg) && arg.content === name);
13330
13316
  }
13331
13317
  function hasDynamicKeyVBind(node) {
@@ -13515,11 +13501,6 @@ const deprecationData$1 = {
13515
13501
  `data source.`,
13516
13502
  link: `https://v3.vuejs.org/guide/migration/v-if-v-for.html`
13517
13503
  },
13518
- ["COMPILER_V_FOR_REF" /* COMPILER_V_FOR_REF */]: {
13519
- message: `Ref usage on v-for no longer creates array ref values in Vue 3. ` +
13520
- `Consider using function refs or refactor to avoid ref usage altogether.`,
13521
- link: `https://v3.vuejs.org/guide/migration/array-refs.html`
13522
- },
13523
13504
  ["COMPILER_NATIVE_TEMPLATE" /* COMPILER_NATIVE_TEMPLATE */]: {
13524
13505
  message: `<template> with no special directives will render as a native template ` +
13525
13506
  `element instead of its inner content in Vue 3.`
@@ -14037,7 +14018,7 @@ function isComponent(tag, props, context) {
14037
14018
  else if (
14038
14019
  // :is on plain element - only treat as component in compat mode
14039
14020
  p.name === 'bind' &&
14040
- isBindKey(p.arg, 'is') &&
14021
+ isStaticArgOf(p.arg, 'is') &&
14041
14022
  true &&
14042
14023
  checkCompatEnabled$1("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context, p.loc)) {
14043
14024
  return true;
@@ -14495,6 +14476,11 @@ function getConstantType(node, context) {
14495
14476
  if (codegenNode.type !== 13 /* VNODE_CALL */) {
14496
14477
  return 0 /* NOT_CONSTANT */;
14497
14478
  }
14479
+ if (codegenNode.isBlock &&
14480
+ node.tag !== 'svg' &&
14481
+ node.tag !== 'foreignObject') {
14482
+ return 0 /* NOT_CONSTANT */;
14483
+ }
14498
14484
  const flag = getPatchFlag(codegenNode);
14499
14485
  if (!flag) {
14500
14486
  let returnType = 3 /* CAN_STRINGIFY */;
@@ -14631,7 +14617,7 @@ function getGeneratedPropsConstantType(node, context) {
14631
14617
  else if (value.type === 14 /* JS_CALL_EXPRESSION */) {
14632
14618
  // some helper calls can be hoisted,
14633
14619
  // such as the `normalizeProps` generated by the compiler for pre-normalize class,
14634
- // in this case we need to respect the ConstantType of the helper's argments
14620
+ // in this case we need to respect the ConstantType of the helper's arguments
14635
14621
  valueType = getConstantTypeOfHelperCall(value, context);
14636
14622
  }
14637
14623
  else {
@@ -16298,10 +16284,7 @@ const transformElement = (node, context) => {
16298
16284
  // updates inside get proper isSVG flag at runtime. (#639, #643)
16299
16285
  // This is technically web-specific, but splitting the logic out of core
16300
16286
  // leads to too much unnecessary complexity.
16301
- (tag === 'svg' ||
16302
- tag === 'foreignObject' ||
16303
- // #938: elements with dynamic keys should be forced into blocks
16304
- findProp(node, 'key', true)));
16287
+ (tag === 'svg' || tag === 'foreignObject'));
16305
16288
  // props
16306
16289
  if (props.length > 0) {
16307
16290
  const propsBuildResult = buildProps(node, context);
@@ -16313,6 +16296,9 @@ const transformElement = (node, context) => {
16313
16296
  directives && directives.length
16314
16297
  ? createArrayExpression(directives.map(dir => buildDirectiveArgs(dir, context)))
16315
16298
  : undefined;
16299
+ if (propsBuildResult.shouldUseBlock) {
16300
+ shouldUseBlock = true;
16301
+ }
16316
16302
  }
16317
16303
  // children
16318
16304
  if (node.children.length > 0) {
@@ -16441,11 +16427,13 @@ function resolveComponentType(node, context, ssr = false) {
16441
16427
  return toValidAssetId(tag, `component`);
16442
16428
  }
16443
16429
  function buildProps(node, context, props = node.props, ssr = false) {
16444
- const { tag, loc: elementLoc } = node;
16430
+ const { tag, loc: elementLoc, children } = node;
16445
16431
  const isComponent = node.tagType === 1 /* COMPONENT */;
16446
16432
  let properties = [];
16447
16433
  const mergeArgs = [];
16448
16434
  const runtimeDirectives = [];
16435
+ const hasChildren = children.length > 0;
16436
+ let shouldUseBlock = false;
16449
16437
  // patchFlag analysis
16450
16438
  let patchFlag = 0;
16451
16439
  let hasRef = false;
@@ -16508,9 +16496,12 @@ function buildProps(node, context, props = node.props, ssr = false) {
16508
16496
  const prop = props[i];
16509
16497
  if (prop.type === 6 /* ATTRIBUTE */) {
16510
16498
  const { loc, name, value } = prop;
16511
- let valueNode = createSimpleExpression(value ? value.content : '', true, value ? value.loc : loc);
16499
+ let isStatic = true;
16512
16500
  if (name === 'ref') {
16513
16501
  hasRef = true;
16502
+ if (context.scopes.vFor > 0) {
16503
+ properties.push(createObjectProperty(createSimpleExpression('ref_for', true), createSimpleExpression('true')));
16504
+ }
16514
16505
  }
16515
16506
  // skip is on <component>, or is="vue:xxx"
16516
16507
  if (name === 'is' &&
@@ -16519,7 +16510,7 @@ function buildProps(node, context, props = node.props, ssr = false) {
16519
16510
  (isCompatEnabled$1("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context)))) {
16520
16511
  continue;
16521
16512
  }
16522
- properties.push(createObjectProperty(createSimpleExpression(name, true, getInnerRange(loc, 0, name.length)), valueNode));
16513
+ properties.push(createObjectProperty(createSimpleExpression(name, true, getInnerRange(loc, 0, name.length)), createSimpleExpression(value ? value.content : '', isStatic, value ? value.loc : loc)));
16523
16514
  }
16524
16515
  else {
16525
16516
  // directives
@@ -16540,7 +16531,7 @@ function buildProps(node, context, props = node.props, ssr = false) {
16540
16531
  // skip v-is and :is on <component>
16541
16532
  if (name === 'is' ||
16542
16533
  (isVBind &&
16543
- isBindKey(arg, 'is') &&
16534
+ isStaticArgOf(arg, 'is') &&
16544
16535
  (isComponentTag(tag) ||
16545
16536
  (isCompatEnabled$1("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context))))) {
16546
16537
  continue;
@@ -16549,6 +16540,17 @@ function buildProps(node, context, props = node.props, ssr = false) {
16549
16540
  if (isVOn && ssr) {
16550
16541
  continue;
16551
16542
  }
16543
+ if (
16544
+ // #938: elements with dynamic keys should be forced into blocks
16545
+ (isVBind && isStaticArgOf(arg, 'key')) ||
16546
+ // inline before-update hooks need to force block so that it is invoked
16547
+ // before children
16548
+ (isVOn && hasChildren && isStaticArgOf(arg, 'vue:before-update'))) {
16549
+ shouldUseBlock = true;
16550
+ }
16551
+ if (isVBind && isStaticArgOf(arg, 'ref') && context.scopes.vFor > 0) {
16552
+ properties.push(createObjectProperty(createSimpleExpression('ref_for', true), createSimpleExpression('true')));
16553
+ }
16552
16554
  // special case for v-bind and v-on with no argument
16553
16555
  if (!arg && (isVBind || isVOn)) {
16554
16556
  hasDynamicKeys = true;
@@ -16622,14 +16624,13 @@ function buildProps(node, context, props = node.props, ssr = false) {
16622
16624
  else {
16623
16625
  // no built-in transform, this is a user custom directive.
16624
16626
  runtimeDirectives.push(prop);
16627
+ // custom dirs may use beforeUpdate so they need to force blocks
16628
+ // to ensure before-update gets called before children update
16629
+ if (hasChildren) {
16630
+ shouldUseBlock = true;
16631
+ }
16625
16632
  }
16626
16633
  }
16627
- if (prop.type === 6 /* ATTRIBUTE */ &&
16628
- prop.name === 'ref' &&
16629
- context.scopes.vFor > 0 &&
16630
- checkCompatEnabled$1("COMPILER_V_FOR_REF" /* COMPILER_V_FOR_REF */, context, prop.loc)) {
16631
- properties.push(createObjectProperty(createSimpleExpression('refInFor', true), createSimpleExpression('true', false)));
16632
- }
16633
16634
  }
16634
16635
  let propsExpression = undefined;
16635
16636
  // has v-bind="object" or v-on="object", wrap with mergeProps
@@ -16666,7 +16667,8 @@ function buildProps(node, context, props = node.props, ssr = false) {
16666
16667
  patchFlag |= 32 /* HYDRATE_EVENTS */;
16667
16668
  }
16668
16669
  }
16669
- if ((patchFlag === 0 || patchFlag === 32 /* HYDRATE_EVENTS */) &&
16670
+ if (!shouldUseBlock &&
16671
+ (patchFlag === 0 || patchFlag === 32 /* HYDRATE_EVENTS */) &&
16670
16672
  (hasRef || hasVnodeHook || runtimeDirectives.length > 0)) {
16671
16673
  patchFlag |= 512 /* NEED_PATCH */;
16672
16674
  }
@@ -16733,7 +16735,8 @@ function buildProps(node, context, props = node.props, ssr = false) {
16733
16735
  props: propsExpression,
16734
16736
  directives: runtimeDirectives,
16735
16737
  patchFlag,
16736
- dynamicPropNames
16738
+ dynamicPropNames,
16739
+ shouldUseBlock
16737
16740
  };
16738
16741
  }
16739
16742
  // Dedupe props in an object literal.
@@ -16869,7 +16872,7 @@ function processSlotOutlet(node, context) {
16869
16872
  }
16870
16873
  }
16871
16874
  else {
16872
- if (p.name === 'bind' && isBindKey(p.arg, 'name')) {
16875
+ if (p.name === 'bind' && isStaticArgOf(p.arg, 'name')) {
16873
16876
  if (p.exp)
16874
16877
  slotName = p.exp;
16875
16878
  }
@@ -16903,7 +16906,11 @@ const transformOn = (dir, node, context, augmentor) => {
16903
16906
  let eventName;
16904
16907
  if (arg.type === 4 /* SIMPLE_EXPRESSION */) {
16905
16908
  if (arg.isStatic) {
16906
- const rawName = arg.content;
16909
+ let rawName = arg.content;
16910
+ // TODO deprecate @vnodeXXX usage
16911
+ if (rawName.startsWith('vue:')) {
16912
+ rawName = `vnode-${rawName.slice(4)}`;
16913
+ }
16907
16914
  // for all event listeners, auto convert it to camelCase. See issue #2249
16908
16915
  eventName = createSimpleExpression(toHandlerKey(camelize(rawName)), true, arg.loc);
16909
16916
  }