@vue/compiler-core 3.2.24 → 3.2.28

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.
@@ -530,12 +530,12 @@ function findProp(node, name, dynamicOnly = false, allowEmpty = false) {
530
530
  }
531
531
  else if (p.name === 'bind' &&
532
532
  (p.exp || allowEmpty) &&
533
- isBindKey(p.arg, name)) {
533
+ isStaticArgOf(p.arg, name)) {
534
534
  return p;
535
535
  }
536
536
  }
537
537
  }
538
- function isBindKey(arg, name) {
538
+ function isStaticArgOf(arg, name) {
539
539
  return !!(arg && isStaticExp(arg) && arg.content === name);
540
540
  }
541
541
  function hasDynamicKeyVBind(node) {
@@ -768,11 +768,6 @@ const deprecationData = {
768
768
  `data source.`,
769
769
  link: `https://v3.vuejs.org/guide/migration/v-if-v-for.html`
770
770
  },
771
- ["COMPILER_V_FOR_REF" /* COMPILER_V_FOR_REF */]: {
772
- message: `Ref usage on v-for no longer creates array ref values in Vue 3. ` +
773
- `Consider using function refs or refactor to avoid ref usage altogether.`,
774
- link: `https://v3.vuejs.org/guide/migration/array-refs.html`
775
- },
776
771
  ["COMPILER_NATIVE_TEMPLATE" /* COMPILER_NATIVE_TEMPLATE */]: {
777
772
  message: `<template> with no special directives will render as a native template ` +
778
773
  `element instead of its inner content in Vue 3.`
@@ -1290,7 +1285,7 @@ function isComponent(tag, props, context) {
1290
1285
  else if (
1291
1286
  // :is on plain element - only treat as component in compat mode
1292
1287
  p.name === 'bind' &&
1293
- isBindKey(p.arg, 'is') &&
1288
+ isStaticArgOf(p.arg, 'is') &&
1294
1289
  true &&
1295
1290
  checkCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context, p.loc)) {
1296
1291
  return true;
@@ -1315,7 +1310,7 @@ function parseAttributes(context, type) {
1315
1310
  }
1316
1311
  const attr = parseAttribute(context, attributeNames);
1317
1312
  // Trim whitespace between class
1318
- // https://github.com/vuejs/vue-next/issues/4251
1313
+ // https://github.com/vuejs/core/issues/4251
1319
1314
  if (attr.type === 6 /* ATTRIBUTE */ &&
1320
1315
  attr.value &&
1321
1316
  attr.name === 'class') {
@@ -1551,7 +1546,7 @@ function parseTextData(context, length, mode) {
1551
1546
  advanceBy(context, length);
1552
1547
  if (mode === 2 /* RAWTEXT */ ||
1553
1548
  mode === 3 /* CDATA */ ||
1554
- rawText.indexOf('&') === -1) {
1549
+ !rawText.includes('&')) {
1555
1550
  return rawText;
1556
1551
  }
1557
1552
  else {
@@ -1748,6 +1743,11 @@ function getConstantType(node, context) {
1748
1743
  if (codegenNode.type !== 13 /* VNODE_CALL */) {
1749
1744
  return 0 /* NOT_CONSTANT */;
1750
1745
  }
1746
+ if (codegenNode.isBlock &&
1747
+ node.tag !== 'svg' &&
1748
+ node.tag !== 'foreignObject') {
1749
+ return 0 /* NOT_CONSTANT */;
1750
+ }
1751
1751
  const flag = getPatchFlag(codegenNode);
1752
1752
  if (!flag) {
1753
1753
  let returnType = 3 /* CAN_STRINGIFY */;
@@ -1884,7 +1884,7 @@ function getGeneratedPropsConstantType(node, context) {
1884
1884
  else if (value.type === 14 /* JS_CALL_EXPRESSION */) {
1885
1885
  // some helper calls can be hoisted,
1886
1886
  // such as the `normalizeProps` generated by the compiler for pre-normalize class,
1887
- // in this case we need to respect the ConstantType of the helper's argments
1887
+ // in this case we need to respect the ConstantType of the helper's arguments
1888
1888
  valueType = getConstantTypeOfHelperCall(value, context);
1889
1889
  }
1890
1890
  else {
@@ -3288,7 +3288,7 @@ function isReferenced(node, parent, grandparent) {
3288
3288
  // no: NODE.target
3289
3289
  case 'MetaProperty':
3290
3290
  return false;
3291
- // yes: type X = { somePropert: NODE }
3291
+ // yes: type X = { someProperty: NODE }
3292
3292
  // no: type X = { NODE: OtherType }
3293
3293
  case 'ObjectTypeProperty':
3294
3294
  return parent.key !== node;
@@ -3799,6 +3799,7 @@ const transformFor = createStructuralDirectiveTransform('for', (node, dir, conte
3799
3799
  const renderExp = createCallExpression(helper(RENDER_LIST), [
3800
3800
  forNode.source
3801
3801
  ]);
3802
+ const isTemplate = isTemplateNode(node);
3802
3803
  const memo = findDir(node, 'memo');
3803
3804
  const keyProp = findProp(node, `key`);
3804
3805
  const keyExp = keyProp &&
@@ -3806,15 +3807,17 @@ const transformFor = createStructuralDirectiveTransform('for', (node, dir, conte
3806
3807
  ? createSimpleExpression(keyProp.value.content, true)
3807
3808
  : keyProp.exp);
3808
3809
  const keyProperty = keyProp ? createObjectProperty(`key`, keyExp) : null;
3809
- if (context.prefixIdentifiers &&
3810
- keyProperty &&
3811
- keyProp.type !== 6 /* ATTRIBUTE */) {
3812
- // #2085 process :key expression needs to be processed in order for it
3813
- // to behave consistently for <template v-for> and <div v-for>.
3814
- // In the case of `<template v-for>`, the node is discarded and never
3815
- // traversed so its key expression won't be processed by the normal
3816
- // transforms.
3817
- keyProperty.value = processExpression(keyProperty.value, context);
3810
+ if (isTemplate) {
3811
+ // #2085 / #5288 process :key and v-memo expressions need to be
3812
+ // processed on `<template v-for>`. In this case the node is discarded
3813
+ // and never traversed so its binding expressions won't be processed
3814
+ // by the normal transforms.
3815
+ if (memo) {
3816
+ memo.exp = processExpression(memo.exp, context);
3817
+ }
3818
+ if (keyProperty && keyProp.type !== 6 /* ATTRIBUTE */) {
3819
+ keyProperty.value = processExpression(keyProperty.value, context);
3820
+ }
3818
3821
  }
3819
3822
  const isStableFragment = forNode.source.type === 4 /* SIMPLE_EXPRESSION */ &&
3820
3823
  forNode.source.constType > 0 /* NOT_CONSTANT */;
@@ -3828,7 +3831,6 @@ const transformFor = createStructuralDirectiveTransform('for', (node, dir, conte
3828
3831
  return () => {
3829
3832
  // finish the codegen now that all children have been traversed
3830
3833
  let childBlock;
3831
- const isTemplate = isTemplateNode(node);
3832
3834
  const { children } = forNode;
3833
3835
  // check <template v-for> key placement
3834
3836
  if (isTemplate) {
@@ -4338,10 +4340,7 @@ const transformElement = (node, context) => {
4338
4340
  // updates inside get proper isSVG flag at runtime. (#639, #643)
4339
4341
  // This is technically web-specific, but splitting the logic out of core
4340
4342
  // leads to too much unnecessary complexity.
4341
- (tag === 'svg' ||
4342
- tag === 'foreignObject' ||
4343
- // #938: elements with dynamic keys should be forced into blocks
4344
- findProp(node, 'key', true)));
4343
+ (tag === 'svg' || tag === 'foreignObject'));
4345
4344
  // props
4346
4345
  if (props.length > 0) {
4347
4346
  const propsBuildResult = buildProps(node, context);
@@ -4353,6 +4352,9 @@ const transformElement = (node, context) => {
4353
4352
  directives && directives.length
4354
4353
  ? createArrayExpression(directives.map(dir => buildDirectiveArgs(dir, context)))
4355
4354
  : undefined;
4355
+ if (propsBuildResult.shouldUseBlock) {
4356
+ shouldUseBlock = true;
4357
+ }
4356
4358
  }
4357
4359
  // children
4358
4360
  if (node.children.length > 0) {
@@ -4542,11 +4544,13 @@ function resolveSetupReference(name, context) {
4542
4544
  }
4543
4545
  }
4544
4546
  function buildProps(node, context, props = node.props, ssr = false) {
4545
- const { tag, loc: elementLoc } = node;
4547
+ const { tag, loc: elementLoc, children } = node;
4546
4548
  const isComponent = node.tagType === 1 /* COMPONENT */;
4547
4549
  let properties = [];
4548
4550
  const mergeArgs = [];
4549
4551
  const runtimeDirectives = [];
4552
+ const hasChildren = children.length > 0;
4553
+ let shouldUseBlock = false;
4550
4554
  // patchFlag analysis
4551
4555
  let patchFlag = 0;
4552
4556
  let hasRef = false;
@@ -4609,15 +4613,20 @@ function buildProps(node, context, props = node.props, ssr = false) {
4609
4613
  const prop = props[i];
4610
4614
  if (prop.type === 6 /* ATTRIBUTE */) {
4611
4615
  const { loc, name, value } = prop;
4612
- let valueNode = createSimpleExpression(value ? value.content : '', true, value ? value.loc : loc);
4616
+ let isStatic = true;
4613
4617
  if (name === 'ref') {
4614
4618
  hasRef = true;
4619
+ if (context.scopes.vFor > 0) {
4620
+ properties.push(createObjectProperty(createSimpleExpression('ref_for', true), createSimpleExpression('true')));
4621
+ }
4615
4622
  // in inline mode there is no setupState object, so we can't use string
4616
4623
  // keys to set the ref. Instead, we need to transform it to pass the
4617
4624
  // actual ref instead.
4618
- if (context.inline && (value === null || value === void 0 ? void 0 : value.content)) {
4619
- valueNode = createFunctionExpression(['_value', '_refs']);
4620
- valueNode.body = createBlockStatement(processInlineRef(context, value.content));
4625
+ if (value &&
4626
+ context.inline &&
4627
+ context.bindingMetadata[value.content]) {
4628
+ isStatic = false;
4629
+ properties.push(createObjectProperty(createSimpleExpression('ref_key', true), createSimpleExpression(value.content, true, value.loc)));
4621
4630
  }
4622
4631
  }
4623
4632
  // skip is on <component>, or is="vue:xxx"
@@ -4627,7 +4636,7 @@ function buildProps(node, context, props = node.props, ssr = false) {
4627
4636
  (isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context)))) {
4628
4637
  continue;
4629
4638
  }
4630
- properties.push(createObjectProperty(createSimpleExpression(name, true, getInnerRange(loc, 0, name.length)), valueNode));
4639
+ properties.push(createObjectProperty(createSimpleExpression(name, true, getInnerRange(loc, 0, name.length)), createSimpleExpression(value ? value.content : '', isStatic, value ? value.loc : loc)));
4631
4640
  }
4632
4641
  else {
4633
4642
  // directives
@@ -4648,7 +4657,7 @@ function buildProps(node, context, props = node.props, ssr = false) {
4648
4657
  // skip v-is and :is on <component>
4649
4658
  if (name === 'is' ||
4650
4659
  (isVBind &&
4651
- isBindKey(arg, 'is') &&
4660
+ isStaticArgOf(arg, 'is') &&
4652
4661
  (isComponentTag(tag) ||
4653
4662
  (isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context))))) {
4654
4663
  continue;
@@ -4657,6 +4666,17 @@ function buildProps(node, context, props = node.props, ssr = false) {
4657
4666
  if (isVOn && ssr) {
4658
4667
  continue;
4659
4668
  }
4669
+ if (
4670
+ // #938: elements with dynamic keys should be forced into blocks
4671
+ (isVBind && isStaticArgOf(arg, 'key')) ||
4672
+ // inline before-update hooks need to force block so that it is invoked
4673
+ // before children
4674
+ (isVOn && hasChildren && isStaticArgOf(arg, 'vue:before-update'))) {
4675
+ shouldUseBlock = true;
4676
+ }
4677
+ if (isVBind && isStaticArgOf(arg, 'ref') && context.scopes.vFor > 0) {
4678
+ properties.push(createObjectProperty(createSimpleExpression('ref_for', true), createSimpleExpression('true')));
4679
+ }
4660
4680
  // special case for v-bind and v-on with no argument
4661
4681
  if (!arg && (isVBind || isVOn)) {
4662
4682
  hasDynamicKeys = true;
@@ -4730,14 +4750,13 @@ function buildProps(node, context, props = node.props, ssr = false) {
4730
4750
  else {
4731
4751
  // no built-in transform, this is a user custom directive.
4732
4752
  runtimeDirectives.push(prop);
4753
+ // custom dirs may use beforeUpdate so they need to force blocks
4754
+ // to ensure before-update gets called before children update
4755
+ if (hasChildren) {
4756
+ shouldUseBlock = true;
4757
+ }
4733
4758
  }
4734
4759
  }
4735
- if (prop.type === 6 /* ATTRIBUTE */ &&
4736
- prop.name === 'ref' &&
4737
- context.scopes.vFor > 0 &&
4738
- checkCompatEnabled("COMPILER_V_FOR_REF" /* COMPILER_V_FOR_REF */, context, prop.loc)) {
4739
- properties.push(createObjectProperty(createSimpleExpression('refInFor', true), createSimpleExpression('true', false)));
4740
- }
4741
4760
  }
4742
4761
  let propsExpression = undefined;
4743
4762
  // has v-bind="object" or v-on="object", wrap with mergeProps
@@ -4774,7 +4793,8 @@ function buildProps(node, context, props = node.props, ssr = false) {
4774
4793
  patchFlag |= 32 /* HYDRATE_EVENTS */;
4775
4794
  }
4776
4795
  }
4777
- if ((patchFlag === 0 || patchFlag === 32 /* HYDRATE_EVENTS */) &&
4796
+ if (!shouldUseBlock &&
4797
+ (patchFlag === 0 || patchFlag === 32 /* HYDRATE_EVENTS */) &&
4778
4798
  (hasRef || hasVnodeHook || runtimeDirectives.length > 0)) {
4779
4799
  patchFlag |= 512 /* NEED_PATCH */;
4780
4800
  }
@@ -4841,7 +4861,8 @@ function buildProps(node, context, props = node.props, ssr = false) {
4841
4861
  props: propsExpression,
4842
4862
  directives: runtimeDirectives,
4843
4863
  patchFlag,
4844
- dynamicPropNames
4864
+ dynamicPropNames,
4865
+ shouldUseBlock
4845
4866
  };
4846
4867
  }
4847
4868
  // Dedupe props in an object literal.
@@ -4936,21 +4957,6 @@ function stringifyDynamicPropNames(props) {
4936
4957
  }
4937
4958
  function isComponentTag(tag) {
4938
4959
  return tag === 'component' || tag === 'Component';
4939
- }
4940
- function processInlineRef(context, raw) {
4941
- const body = [createSimpleExpression(`_refs['${raw}'] = _value`)];
4942
- const { bindingMetadata, helperString } = context;
4943
- const type = bindingMetadata[raw];
4944
- if (type === "setup-ref" /* SETUP_REF */) {
4945
- body.push(createSimpleExpression(`${raw}.value = _value`));
4946
- }
4947
- else if (type === "setup-maybe-ref" /* SETUP_MAYBE_REF */) {
4948
- body.push(createSimpleExpression(`${helperString(IS_REF)}(${raw}) && (${raw}.value = _value)`));
4949
- }
4950
- else if (type === "setup-let" /* SETUP_LET */) {
4951
- body.push(createSimpleExpression(`${helperString(IS_REF)}(${raw}) ? ${raw}.value = _value : ${raw} = _value`));
4952
- }
4953
- return body;
4954
4960
  }
4955
4961
 
4956
4962
  Object.freeze({})
@@ -5016,7 +5022,7 @@ function processSlotOutlet(node, context) {
5016
5022
  }
5017
5023
  }
5018
5024
  else {
5019
- if (p.name === 'bind' && isBindKey(p.arg, 'name')) {
5025
+ if (p.name === 'bind' && isStaticArgOf(p.arg, 'name')) {
5020
5026
  if (p.exp)
5021
5027
  slotName = p.exp;
5022
5028
  }
@@ -5050,7 +5056,11 @@ const transformOn = (dir, node, context, augmentor) => {
5050
5056
  let eventName;
5051
5057
  if (arg.type === 4 /* SIMPLE_EXPRESSION */) {
5052
5058
  if (arg.isStatic) {
5053
- const rawName = arg.content;
5059
+ let rawName = arg.content;
5060
+ // TODO deprecate @vnodeXXX usage
5061
+ if (rawName.startsWith('vue:')) {
5062
+ rawName = `vnode-${rawName.slice(4)}`;
5063
+ }
5054
5064
  // for all event listeners, auto convert it to camelCase. See issue #2249
5055
5065
  eventName = createSimpleExpression(shared.toHandlerKey(shared.camelize(rawName)), true, arg.loc);
5056
5066
  }
@@ -5748,7 +5758,6 @@ exports.hasDynamicKeyVBind = hasDynamicKeyVBind;
5748
5758
  exports.hasScopeRef = hasScopeRef;
5749
5759
  exports.helperNameMap = helperNameMap;
5750
5760
  exports.injectProp = injectProp;
5751
- exports.isBindKey = isBindKey;
5752
5761
  exports.isBuiltInType = isBuiltInType;
5753
5762
  exports.isCoreComponent = isCoreComponent;
5754
5763
  exports.isFunctionType = isFunctionType;
@@ -5759,6 +5768,7 @@ exports.isMemberExpressionNode = isMemberExpressionNode;
5759
5768
  exports.isReferencedIdentifier = isReferencedIdentifier;
5760
5769
  exports.isSimpleIdentifier = isSimpleIdentifier;
5761
5770
  exports.isSlotOutlet = isSlotOutlet;
5771
+ exports.isStaticArgOf = isStaticArgOf;
5762
5772
  exports.isStaticExp = isStaticExp;
5763
5773
  exports.isStaticProperty = isStaticProperty;
5764
5774
  exports.isStaticPropertyKey = isStaticPropertyKey;
@@ -529,12 +529,12 @@ function findProp(node, name, dynamicOnly = false, allowEmpty = false) {
529
529
  }
530
530
  else if (p.name === 'bind' &&
531
531
  (p.exp || allowEmpty) &&
532
- isBindKey(p.arg, name)) {
532
+ isStaticArgOf(p.arg, name)) {
533
533
  return p;
534
534
  }
535
535
  }
536
536
  }
537
- function isBindKey(arg, name) {
537
+ function isStaticArgOf(arg, name) {
538
538
  return !!(arg && isStaticExp(arg) && arg.content === name);
539
539
  }
540
540
  function hasDynamicKeyVBind(node) {
@@ -767,11 +767,6 @@ const deprecationData = {
767
767
  `data source.`,
768
768
  link: `https://v3.vuejs.org/guide/migration/v-if-v-for.html`
769
769
  },
770
- ["COMPILER_V_FOR_REF" /* COMPILER_V_FOR_REF */]: {
771
- message: `Ref usage on v-for no longer creates array ref values in Vue 3. ` +
772
- `Consider using function refs or refactor to avoid ref usage altogether.`,
773
- link: `https://v3.vuejs.org/guide/migration/array-refs.html`
774
- },
775
770
  ["COMPILER_NATIVE_TEMPLATE" /* COMPILER_NATIVE_TEMPLATE */]: {
776
771
  message: `<template> with no special directives will render as a native template ` +
777
772
  `element instead of its inner content in Vue 3.`
@@ -1265,7 +1260,7 @@ function isComponent(tag, props, context) {
1265
1260
  else if (
1266
1261
  // :is on plain element - only treat as component in compat mode
1267
1262
  p.name === 'bind' &&
1268
- isBindKey(p.arg, 'is') &&
1263
+ isStaticArgOf(p.arg, 'is') &&
1269
1264
  true &&
1270
1265
  checkCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context, p.loc)) {
1271
1266
  return true;
@@ -1290,7 +1285,7 @@ function parseAttributes(context, type) {
1290
1285
  }
1291
1286
  const attr = parseAttribute(context, attributeNames);
1292
1287
  // Trim whitespace between class
1293
- // https://github.com/vuejs/vue-next/issues/4251
1288
+ // https://github.com/vuejs/core/issues/4251
1294
1289
  if (attr.type === 6 /* ATTRIBUTE */ &&
1295
1290
  attr.value &&
1296
1291
  attr.name === 'class') {
@@ -1523,7 +1518,7 @@ function parseTextData(context, length, mode) {
1523
1518
  advanceBy(context, length);
1524
1519
  if (mode === 2 /* RAWTEXT */ ||
1525
1520
  mode === 3 /* CDATA */ ||
1526
- rawText.indexOf('&') === -1) {
1521
+ !rawText.includes('&')) {
1527
1522
  return rawText;
1528
1523
  }
1529
1524
  else {
@@ -1720,6 +1715,11 @@ function getConstantType(node, context) {
1720
1715
  if (codegenNode.type !== 13 /* VNODE_CALL */) {
1721
1716
  return 0 /* NOT_CONSTANT */;
1722
1717
  }
1718
+ if (codegenNode.isBlock &&
1719
+ node.tag !== 'svg' &&
1720
+ node.tag !== 'foreignObject') {
1721
+ return 0 /* NOT_CONSTANT */;
1722
+ }
1723
1723
  const flag = getPatchFlag(codegenNode);
1724
1724
  if (!flag) {
1725
1725
  let returnType = 3 /* CAN_STRINGIFY */;
@@ -1856,7 +1856,7 @@ function getGeneratedPropsConstantType(node, context) {
1856
1856
  else if (value.type === 14 /* JS_CALL_EXPRESSION */) {
1857
1857
  // some helper calls can be hoisted,
1858
1858
  // such as the `normalizeProps` generated by the compiler for pre-normalize class,
1859
- // in this case we need to respect the ConstantType of the helper's argments
1859
+ // in this case we need to respect the ConstantType of the helper's arguments
1860
1860
  valueType = getConstantTypeOfHelperCall(value, context);
1861
1861
  }
1862
1862
  else {
@@ -3225,7 +3225,7 @@ function isReferenced(node, parent, grandparent) {
3225
3225
  // no: NODE.target
3226
3226
  case 'MetaProperty':
3227
3227
  return false;
3228
- // yes: type X = { somePropert: NODE }
3228
+ // yes: type X = { someProperty: NODE }
3229
3229
  // no: type X = { NODE: OtherType }
3230
3230
  case 'ObjectTypeProperty':
3231
3231
  return parent.key !== node;
@@ -3717,6 +3717,7 @@ const transformFor = createStructuralDirectiveTransform('for', (node, dir, conte
3717
3717
  const renderExp = createCallExpression(helper(RENDER_LIST), [
3718
3718
  forNode.source
3719
3719
  ]);
3720
+ const isTemplate = isTemplateNode(node);
3720
3721
  const memo = findDir(node, 'memo');
3721
3722
  const keyProp = findProp(node, `key`);
3722
3723
  const keyExp = keyProp &&
@@ -3724,15 +3725,17 @@ const transformFor = createStructuralDirectiveTransform('for', (node, dir, conte
3724
3725
  ? createSimpleExpression(keyProp.value.content, true)
3725
3726
  : keyProp.exp);
3726
3727
  const keyProperty = keyProp ? createObjectProperty(`key`, keyExp) : null;
3727
- if (context.prefixIdentifiers &&
3728
- keyProperty &&
3729
- keyProp.type !== 6 /* ATTRIBUTE */) {
3730
- // #2085 process :key expression needs to be processed in order for it
3731
- // to behave consistently for <template v-for> and <div v-for>.
3732
- // In the case of `<template v-for>`, the node is discarded and never
3733
- // traversed so its key expression won't be processed by the normal
3734
- // transforms.
3735
- keyProperty.value = processExpression(keyProperty.value, context);
3728
+ if (isTemplate) {
3729
+ // #2085 / #5288 process :key and v-memo expressions need to be
3730
+ // processed on `<template v-for>`. In this case the node is discarded
3731
+ // and never traversed so its binding expressions won't be processed
3732
+ // by the normal transforms.
3733
+ if (memo) {
3734
+ memo.exp = processExpression(memo.exp, context);
3735
+ }
3736
+ if (keyProperty && keyProp.type !== 6 /* ATTRIBUTE */) {
3737
+ keyProperty.value = processExpression(keyProperty.value, context);
3738
+ }
3736
3739
  }
3737
3740
  const isStableFragment = forNode.source.type === 4 /* SIMPLE_EXPRESSION */ &&
3738
3741
  forNode.source.constType > 0 /* NOT_CONSTANT */;
@@ -3746,7 +3749,6 @@ const transformFor = createStructuralDirectiveTransform('for', (node, dir, conte
3746
3749
  return () => {
3747
3750
  // finish the codegen now that all children have been traversed
3748
3751
  let childBlock;
3749
- const isTemplate = isTemplateNode(node);
3750
3752
  const { children } = forNode;
3751
3753
  // check <template v-for> key placement
3752
3754
  if (isTemplate) {
@@ -4255,10 +4257,7 @@ const transformElement = (node, context) => {
4255
4257
  // updates inside get proper isSVG flag at runtime. (#639, #643)
4256
4258
  // This is technically web-specific, but splitting the logic out of core
4257
4259
  // leads to too much unnecessary complexity.
4258
- (tag === 'svg' ||
4259
- tag === 'foreignObject' ||
4260
- // #938: elements with dynamic keys should be forced into blocks
4261
- findProp(node, 'key', true)));
4260
+ (tag === 'svg' || tag === 'foreignObject'));
4262
4261
  // props
4263
4262
  if (props.length > 0) {
4264
4263
  const propsBuildResult = buildProps(node, context);
@@ -4270,6 +4269,9 @@ const transformElement = (node, context) => {
4270
4269
  directives && directives.length
4271
4270
  ? createArrayExpression(directives.map(dir => buildDirectiveArgs(dir, context)))
4272
4271
  : undefined;
4272
+ if (propsBuildResult.shouldUseBlock) {
4273
+ shouldUseBlock = true;
4274
+ }
4273
4275
  }
4274
4276
  // children
4275
4277
  if (node.children.length > 0) {
@@ -4440,11 +4442,13 @@ function resolveSetupReference(name, context) {
4440
4442
  }
4441
4443
  }
4442
4444
  function buildProps(node, context, props = node.props, ssr = false) {
4443
- const { tag, loc: elementLoc } = node;
4445
+ const { tag, loc: elementLoc, children } = node;
4444
4446
  const isComponent = node.tagType === 1 /* COMPONENT */;
4445
4447
  let properties = [];
4446
4448
  const mergeArgs = [];
4447
4449
  const runtimeDirectives = [];
4450
+ const hasChildren = children.length > 0;
4451
+ let shouldUseBlock = false;
4448
4452
  // patchFlag analysis
4449
4453
  let patchFlag = 0;
4450
4454
  let hasRef = false;
@@ -4507,15 +4511,20 @@ function buildProps(node, context, props = node.props, ssr = false) {
4507
4511
  const prop = props[i];
4508
4512
  if (prop.type === 6 /* ATTRIBUTE */) {
4509
4513
  const { loc, name, value } = prop;
4510
- let valueNode = createSimpleExpression(value ? value.content : '', true, value ? value.loc : loc);
4514
+ let isStatic = true;
4511
4515
  if (name === 'ref') {
4512
4516
  hasRef = true;
4517
+ if (context.scopes.vFor > 0) {
4518
+ properties.push(createObjectProperty(createSimpleExpression('ref_for', true), createSimpleExpression('true')));
4519
+ }
4513
4520
  // in inline mode there is no setupState object, so we can't use string
4514
4521
  // keys to set the ref. Instead, we need to transform it to pass the
4515
4522
  // actual ref instead.
4516
- if (context.inline && (value === null || value === void 0 ? void 0 : value.content)) {
4517
- valueNode = createFunctionExpression(['_value', '_refs']);
4518
- valueNode.body = createBlockStatement(processInlineRef(context, value.content));
4523
+ if (value &&
4524
+ context.inline &&
4525
+ context.bindingMetadata[value.content]) {
4526
+ isStatic = false;
4527
+ properties.push(createObjectProperty(createSimpleExpression('ref_key', true), createSimpleExpression(value.content, true, value.loc)));
4519
4528
  }
4520
4529
  }
4521
4530
  // skip is on <component>, or is="vue:xxx"
@@ -4525,7 +4534,7 @@ function buildProps(node, context, props = node.props, ssr = false) {
4525
4534
  (isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context)))) {
4526
4535
  continue;
4527
4536
  }
4528
- properties.push(createObjectProperty(createSimpleExpression(name, true, getInnerRange(loc, 0, name.length)), valueNode));
4537
+ properties.push(createObjectProperty(createSimpleExpression(name, true, getInnerRange(loc, 0, name.length)), createSimpleExpression(value ? value.content : '', isStatic, value ? value.loc : loc)));
4529
4538
  }
4530
4539
  else {
4531
4540
  // directives
@@ -4546,7 +4555,7 @@ function buildProps(node, context, props = node.props, ssr = false) {
4546
4555
  // skip v-is and :is on <component>
4547
4556
  if (name === 'is' ||
4548
4557
  (isVBind &&
4549
- isBindKey(arg, 'is') &&
4558
+ isStaticArgOf(arg, 'is') &&
4550
4559
  (isComponentTag(tag) ||
4551
4560
  (isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context))))) {
4552
4561
  continue;
@@ -4555,6 +4564,17 @@ function buildProps(node, context, props = node.props, ssr = false) {
4555
4564
  if (isVOn && ssr) {
4556
4565
  continue;
4557
4566
  }
4567
+ if (
4568
+ // #938: elements with dynamic keys should be forced into blocks
4569
+ (isVBind && isStaticArgOf(arg, 'key')) ||
4570
+ // inline before-update hooks need to force block so that it is invoked
4571
+ // before children
4572
+ (isVOn && hasChildren && isStaticArgOf(arg, 'vue:before-update'))) {
4573
+ shouldUseBlock = true;
4574
+ }
4575
+ if (isVBind && isStaticArgOf(arg, 'ref') && context.scopes.vFor > 0) {
4576
+ properties.push(createObjectProperty(createSimpleExpression('ref_for', true), createSimpleExpression('true')));
4577
+ }
4558
4578
  // special case for v-bind and v-on with no argument
4559
4579
  if (!arg && (isVBind || isVOn)) {
4560
4580
  hasDynamicKeys = true;
@@ -4605,14 +4625,13 @@ function buildProps(node, context, props = node.props, ssr = false) {
4605
4625
  else {
4606
4626
  // no built-in transform, this is a user custom directive.
4607
4627
  runtimeDirectives.push(prop);
4628
+ // custom dirs may use beforeUpdate so they need to force blocks
4629
+ // to ensure before-update gets called before children update
4630
+ if (hasChildren) {
4631
+ shouldUseBlock = true;
4632
+ }
4608
4633
  }
4609
4634
  }
4610
- if (prop.type === 6 /* ATTRIBUTE */ &&
4611
- prop.name === 'ref' &&
4612
- context.scopes.vFor > 0 &&
4613
- checkCompatEnabled("COMPILER_V_FOR_REF" /* COMPILER_V_FOR_REF */, context, prop.loc)) {
4614
- properties.push(createObjectProperty(createSimpleExpression('refInFor', true), createSimpleExpression('true', false)));
4615
- }
4616
4635
  }
4617
4636
  let propsExpression = undefined;
4618
4637
  // has v-bind="object" or v-on="object", wrap with mergeProps
@@ -4649,7 +4668,8 @@ function buildProps(node, context, props = node.props, ssr = false) {
4649
4668
  patchFlag |= 32 /* HYDRATE_EVENTS */;
4650
4669
  }
4651
4670
  }
4652
- if ((patchFlag === 0 || patchFlag === 32 /* HYDRATE_EVENTS */) &&
4671
+ if (!shouldUseBlock &&
4672
+ (patchFlag === 0 || patchFlag === 32 /* HYDRATE_EVENTS */) &&
4653
4673
  (hasRef || hasVnodeHook || runtimeDirectives.length > 0)) {
4654
4674
  patchFlag |= 512 /* NEED_PATCH */;
4655
4675
  }
@@ -4716,7 +4736,8 @@ function buildProps(node, context, props = node.props, ssr = false) {
4716
4736
  props: propsExpression,
4717
4737
  directives: runtimeDirectives,
4718
4738
  patchFlag,
4719
- dynamicPropNames
4739
+ dynamicPropNames,
4740
+ shouldUseBlock
4720
4741
  };
4721
4742
  }
4722
4743
  // Dedupe props in an object literal.
@@ -4811,21 +4832,6 @@ function stringifyDynamicPropNames(props) {
4811
4832
  }
4812
4833
  function isComponentTag(tag) {
4813
4834
  return tag === 'component' || tag === 'Component';
4814
- }
4815
- function processInlineRef(context, raw) {
4816
- const body = [createSimpleExpression(`_refs['${raw}'] = _value`)];
4817
- const { bindingMetadata, helperString } = context;
4818
- const type = bindingMetadata[raw];
4819
- if (type === "setup-ref" /* SETUP_REF */) {
4820
- body.push(createSimpleExpression(`${raw}.value = _value`));
4821
- }
4822
- else if (type === "setup-maybe-ref" /* SETUP_MAYBE_REF */) {
4823
- body.push(createSimpleExpression(`${helperString(IS_REF)}(${raw}) && (${raw}.value = _value)`));
4824
- }
4825
- else if (type === "setup-let" /* SETUP_LET */) {
4826
- body.push(createSimpleExpression(`${helperString(IS_REF)}(${raw}) ? ${raw}.value = _value : ${raw} = _value`));
4827
- }
4828
- return body;
4829
4835
  }
4830
4836
 
4831
4837
  const cacheStringFunction = (fn) => {
@@ -4888,7 +4894,7 @@ function processSlotOutlet(node, context) {
4888
4894
  }
4889
4895
  }
4890
4896
  else {
4891
- if (p.name === 'bind' && isBindKey(p.arg, 'name')) {
4897
+ if (p.name === 'bind' && isStaticArgOf(p.arg, 'name')) {
4892
4898
  if (p.exp)
4893
4899
  slotName = p.exp;
4894
4900
  }
@@ -4922,7 +4928,11 @@ const transformOn = (dir, node, context, augmentor) => {
4922
4928
  let eventName;
4923
4929
  if (arg.type === 4 /* SIMPLE_EXPRESSION */) {
4924
4930
  if (arg.isStatic) {
4925
- const rawName = arg.content;
4931
+ let rawName = arg.content;
4932
+ // TODO deprecate @vnodeXXX usage
4933
+ if (rawName.startsWith('vue:')) {
4934
+ rawName = `vnode-${rawName.slice(4)}`;
4935
+ }
4926
4936
  // for all event listeners, auto convert it to camelCase. See issue #2249
4927
4937
  eventName = createSimpleExpression(shared.toHandlerKey(shared.camelize(rawName)), true, arg.loc);
4928
4938
  }
@@ -5619,7 +5629,6 @@ exports.hasDynamicKeyVBind = hasDynamicKeyVBind;
5619
5629
  exports.hasScopeRef = hasScopeRef;
5620
5630
  exports.helperNameMap = helperNameMap;
5621
5631
  exports.injectProp = injectProp;
5622
- exports.isBindKey = isBindKey;
5623
5632
  exports.isBuiltInType = isBuiltInType;
5624
5633
  exports.isCoreComponent = isCoreComponent;
5625
5634
  exports.isFunctionType = isFunctionType;
@@ -5630,6 +5639,7 @@ exports.isMemberExpressionNode = isMemberExpressionNode;
5630
5639
  exports.isReferencedIdentifier = isReferencedIdentifier;
5631
5640
  exports.isSimpleIdentifier = isSimpleIdentifier;
5632
5641
  exports.isSlotOutlet = isSlotOutlet;
5642
+ exports.isStaticArgOf = isStaticArgOf;
5633
5643
  exports.isStaticExp = isStaticExp;
5634
5644
  exports.isStaticProperty = isStaticProperty;
5635
5645
  exports.isStaticPropertyKey = isStaticPropertyKey;
@@ -105,6 +105,7 @@ export declare function buildProps(node: ElementNode, context: TransformContext,
105
105
  directives: DirectiveNode[];
106
106
  patchFlag: number;
107
107
  dynamicPropNames: string[];
108
+ shouldUseBlock: boolean;
108
109
  };
109
110
 
110
111
  export declare function buildSlots(node: ElementNode, context: TransformContext, buildSlotFn?: SlotFnBuilder): {
@@ -220,7 +221,6 @@ export declare const enum CompilerDeprecationTypes {
220
221
  COMPILER_V_BIND_OBJECT_ORDER = "COMPILER_V_BIND_OBJECT_ORDER",
221
222
  COMPILER_V_ON_NATIVE = "COMPILER_V_ON_NATIVE",
222
223
  COMPILER_V_IF_V_FOR_PRECEDENCE = "COMPILER_V_IF_V_FOR_PRECEDENCE",
223
- COMPILER_V_FOR_REF = "COMPILER_V_FOR_REF",
224
224
  COMPILER_NATIVE_TEMPLATE = "COMPILER_NATIVE_TEMPLATE",
225
225
  COMPILER_INLINE_TEMPLATE = "COMPILER_INLINE_TEMPLATE",
226
226
  COMPILER_FILTERS = "COMPILER_FILTER"
@@ -589,8 +589,6 @@ export declare const IS_MEMO_SAME: unique symbol;
589
589
 
590
590
  export declare const IS_REF: unique symbol;
591
591
 
592
- export declare function isBindKey(arg: DirectiveNode['arg'], name: string): boolean;
593
-
594
592
  export declare const isBuiltInType: (tag: string, expected: string) => boolean;
595
593
 
596
594
  export declare function isCoreComponent(tag: string): symbol | void;
@@ -617,6 +615,8 @@ export declare const isSimpleIdentifier: (name: string) => boolean;
617
615
 
618
616
  export declare function isSlotOutlet(node: RootNode | TemplateChildNode): node is SlotOutletNode;
619
617
 
618
+ export declare function isStaticArgOf(arg: DirectiveNode['arg'], name: string): boolean;
619
+
620
620
  export declare const isStaticExp: (p: JSChildNode) => p is SimpleExpressionNode;
621
621
 
622
622
  export declare const isStaticProperty: (node: Node_3) => node is ObjectProperty;
@@ -512,12 +512,12 @@ function findProp(node, name, dynamicOnly = false, allowEmpty = false) {
512
512
  }
513
513
  else if (p.name === 'bind' &&
514
514
  (p.exp || allowEmpty) &&
515
- isBindKey(p.arg, name)) {
515
+ isStaticArgOf(p.arg, name)) {
516
516
  return p;
517
517
  }
518
518
  }
519
519
  }
520
- function isBindKey(arg, name) {
520
+ function isStaticArgOf(arg, name) {
521
521
  return !!(arg && isStaticExp(arg) && arg.content === name);
522
522
  }
523
523
  function hasDynamicKeyVBind(node) {
@@ -751,11 +751,6 @@ const deprecationData = {
751
751
  `data source.`,
752
752
  link: `https://v3.vuejs.org/guide/migration/v-if-v-for.html`
753
753
  },
754
- ["COMPILER_V_FOR_REF" /* COMPILER_V_FOR_REF */]: {
755
- message: `Ref usage on v-for no longer creates array ref values in Vue 3. ` +
756
- `Consider using function refs or refactor to avoid ref usage altogether.`,
757
- link: `https://v3.vuejs.org/guide/migration/array-refs.html`
758
- },
759
754
  ["COMPILER_NATIVE_TEMPLATE" /* COMPILER_NATIVE_TEMPLATE */]: {
760
755
  message: `<template> with no special directives will render as a native template ` +
761
756
  `element instead of its inner content in Vue 3.`
@@ -1275,7 +1270,7 @@ function isComponent(tag, props, context) {
1275
1270
  else if (
1276
1271
  // :is on plain element - only treat as component in compat mode
1277
1272
  p.name === 'bind' &&
1278
- isBindKey(p.arg, 'is') &&
1273
+ isStaticArgOf(p.arg, 'is') &&
1279
1274
  true &&
1280
1275
  checkCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context, p.loc)) {
1281
1276
  return true;
@@ -1300,7 +1295,7 @@ function parseAttributes(context, type) {
1300
1295
  }
1301
1296
  const attr = parseAttribute(context, attributeNames);
1302
1297
  // Trim whitespace between class
1303
- // https://github.com/vuejs/vue-next/issues/4251
1298
+ // https://github.com/vuejs/core/issues/4251
1304
1299
  if (attr.type === 6 /* ATTRIBUTE */ &&
1305
1300
  attr.value &&
1306
1301
  attr.name === 'class') {
@@ -1536,7 +1531,7 @@ function parseTextData(context, length, mode) {
1536
1531
  advanceBy(context, length);
1537
1532
  if (mode === 2 /* RAWTEXT */ ||
1538
1533
  mode === 3 /* CDATA */ ||
1539
- rawText.indexOf('&') === -1) {
1534
+ !rawText.includes('&')) {
1540
1535
  return rawText;
1541
1536
  }
1542
1537
  else {
@@ -1733,6 +1728,11 @@ function getConstantType(node, context) {
1733
1728
  if (codegenNode.type !== 13 /* VNODE_CALL */) {
1734
1729
  return 0 /* NOT_CONSTANT */;
1735
1730
  }
1731
+ if (codegenNode.isBlock &&
1732
+ node.tag !== 'svg' &&
1733
+ node.tag !== 'foreignObject') {
1734
+ return 0 /* NOT_CONSTANT */;
1735
+ }
1736
1736
  const flag = getPatchFlag(codegenNode);
1737
1737
  if (!flag) {
1738
1738
  let returnType = 3 /* CAN_STRINGIFY */;
@@ -1870,7 +1870,7 @@ function getGeneratedPropsConstantType(node, context) {
1870
1870
  else if (value.type === 14 /* JS_CALL_EXPRESSION */) {
1871
1871
  // some helper calls can be hoisted,
1872
1872
  // such as the `normalizeProps` generated by the compiler for pre-normalize class,
1873
- // in this case we need to respect the ConstantType of the helper's argments
1873
+ // in this case we need to respect the ConstantType of the helper's arguments
1874
1874
  valueType = getConstantTypeOfHelperCall(value, context);
1875
1875
  }
1876
1876
  else {
@@ -3155,6 +3155,7 @@ const transformFor = createStructuralDirectiveTransform('for', (node, dir, conte
3155
3155
  const renderExp = createCallExpression(helper(RENDER_LIST), [
3156
3156
  forNode.source
3157
3157
  ]);
3158
+ const isTemplate = isTemplateNode(node);
3158
3159
  const memo = findDir(node, 'memo');
3159
3160
  const keyProp = findProp(node, `key`);
3160
3161
  const keyExp = keyProp &&
@@ -3174,7 +3175,6 @@ const transformFor = createStructuralDirectiveTransform('for', (node, dir, conte
3174
3175
  return () => {
3175
3176
  // finish the codegen now that all children have been traversed
3176
3177
  let childBlock;
3177
- const isTemplate = isTemplateNode(node);
3178
3178
  const { children } = forNode;
3179
3179
  // check <template v-for> key placement
3180
3180
  if (((process.env.NODE_ENV !== 'production') || !true) && isTemplate) {
@@ -3662,10 +3662,7 @@ const transformElement = (node, context) => {
3662
3662
  // updates inside get proper isSVG flag at runtime. (#639, #643)
3663
3663
  // This is technically web-specific, but splitting the logic out of core
3664
3664
  // leads to too much unnecessary complexity.
3665
- (tag === 'svg' ||
3666
- tag === 'foreignObject' ||
3667
- // #938: elements with dynamic keys should be forced into blocks
3668
- findProp(node, 'key', true)));
3665
+ (tag === 'svg' || tag === 'foreignObject'));
3669
3666
  // props
3670
3667
  if (props.length > 0) {
3671
3668
  const propsBuildResult = buildProps(node, context);
@@ -3677,6 +3674,9 @@ const transformElement = (node, context) => {
3677
3674
  directives && directives.length
3678
3675
  ? createArrayExpression(directives.map(dir => buildDirectiveArgs(dir, context)))
3679
3676
  : undefined;
3677
+ if (propsBuildResult.shouldUseBlock) {
3678
+ shouldUseBlock = true;
3679
+ }
3680
3680
  }
3681
3681
  // children
3682
3682
  if (node.children.length > 0) {
@@ -3808,11 +3808,13 @@ function resolveComponentType(node, context, ssr = false) {
3808
3808
  return toValidAssetId(tag, `component`);
3809
3809
  }
3810
3810
  function buildProps(node, context, props = node.props, ssr = false) {
3811
- const { tag, loc: elementLoc } = node;
3811
+ const { tag, loc: elementLoc, children } = node;
3812
3812
  const isComponent = node.tagType === 1 /* COMPONENT */;
3813
3813
  let properties = [];
3814
3814
  const mergeArgs = [];
3815
3815
  const runtimeDirectives = [];
3816
+ const hasChildren = children.length > 0;
3817
+ let shouldUseBlock = false;
3816
3818
  // patchFlag analysis
3817
3819
  let patchFlag = 0;
3818
3820
  let hasRef = false;
@@ -3875,9 +3877,12 @@ function buildProps(node, context, props = node.props, ssr = false) {
3875
3877
  const prop = props[i];
3876
3878
  if (prop.type === 6 /* ATTRIBUTE */) {
3877
3879
  const { loc, name, value } = prop;
3878
- let valueNode = createSimpleExpression(value ? value.content : '', true, value ? value.loc : loc);
3880
+ let isStatic = true;
3879
3881
  if (name === 'ref') {
3880
3882
  hasRef = true;
3883
+ if (context.scopes.vFor > 0) {
3884
+ properties.push(createObjectProperty(createSimpleExpression('ref_for', true), createSimpleExpression('true')));
3885
+ }
3881
3886
  }
3882
3887
  // skip is on <component>, or is="vue:xxx"
3883
3888
  if (name === 'is' &&
@@ -3886,7 +3891,7 @@ function buildProps(node, context, props = node.props, ssr = false) {
3886
3891
  (isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context)))) {
3887
3892
  continue;
3888
3893
  }
3889
- properties.push(createObjectProperty(createSimpleExpression(name, true, getInnerRange(loc, 0, name.length)), valueNode));
3894
+ properties.push(createObjectProperty(createSimpleExpression(name, true, getInnerRange(loc, 0, name.length)), createSimpleExpression(value ? value.content : '', isStatic, value ? value.loc : loc)));
3890
3895
  }
3891
3896
  else {
3892
3897
  // directives
@@ -3907,7 +3912,7 @@ function buildProps(node, context, props = node.props, ssr = false) {
3907
3912
  // skip v-is and :is on <component>
3908
3913
  if (name === 'is' ||
3909
3914
  (isVBind &&
3910
- isBindKey(arg, 'is') &&
3915
+ isStaticArgOf(arg, 'is') &&
3911
3916
  (isComponentTag(tag) ||
3912
3917
  (isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context))))) {
3913
3918
  continue;
@@ -3916,6 +3921,17 @@ function buildProps(node, context, props = node.props, ssr = false) {
3916
3921
  if (isVOn && ssr) {
3917
3922
  continue;
3918
3923
  }
3924
+ if (
3925
+ // #938: elements with dynamic keys should be forced into blocks
3926
+ (isVBind && isStaticArgOf(arg, 'key')) ||
3927
+ // inline before-update hooks need to force block so that it is invoked
3928
+ // before children
3929
+ (isVOn && hasChildren && isStaticArgOf(arg, 'vue:before-update'))) {
3930
+ shouldUseBlock = true;
3931
+ }
3932
+ if (isVBind && isStaticArgOf(arg, 'ref') && context.scopes.vFor > 0) {
3933
+ properties.push(createObjectProperty(createSimpleExpression('ref_for', true), createSimpleExpression('true')));
3934
+ }
3919
3935
  // special case for v-bind and v-on with no argument
3920
3936
  if (!arg && (isVBind || isVOn)) {
3921
3937
  hasDynamicKeys = true;
@@ -3989,14 +4005,13 @@ function buildProps(node, context, props = node.props, ssr = false) {
3989
4005
  else {
3990
4006
  // no built-in transform, this is a user custom directive.
3991
4007
  runtimeDirectives.push(prop);
4008
+ // custom dirs may use beforeUpdate so they need to force blocks
4009
+ // to ensure before-update gets called before children update
4010
+ if (hasChildren) {
4011
+ shouldUseBlock = true;
4012
+ }
3992
4013
  }
3993
4014
  }
3994
- if (prop.type === 6 /* ATTRIBUTE */ &&
3995
- prop.name === 'ref' &&
3996
- context.scopes.vFor > 0 &&
3997
- checkCompatEnabled("COMPILER_V_FOR_REF" /* COMPILER_V_FOR_REF */, context, prop.loc)) {
3998
- properties.push(createObjectProperty(createSimpleExpression('refInFor', true), createSimpleExpression('true', false)));
3999
- }
4000
4015
  }
4001
4016
  let propsExpression = undefined;
4002
4017
  // has v-bind="object" or v-on="object", wrap with mergeProps
@@ -4033,7 +4048,8 @@ function buildProps(node, context, props = node.props, ssr = false) {
4033
4048
  patchFlag |= 32 /* HYDRATE_EVENTS */;
4034
4049
  }
4035
4050
  }
4036
- if ((patchFlag === 0 || patchFlag === 32 /* HYDRATE_EVENTS */) &&
4051
+ if (!shouldUseBlock &&
4052
+ (patchFlag === 0 || patchFlag === 32 /* HYDRATE_EVENTS */) &&
4037
4053
  (hasRef || hasVnodeHook || runtimeDirectives.length > 0)) {
4038
4054
  patchFlag |= 512 /* NEED_PATCH */;
4039
4055
  }
@@ -4100,7 +4116,8 @@ function buildProps(node, context, props = node.props, ssr = false) {
4100
4116
  props: propsExpression,
4101
4117
  directives: runtimeDirectives,
4102
4118
  patchFlag,
4103
- dynamicPropNames
4119
+ dynamicPropNames,
4120
+ shouldUseBlock
4104
4121
  };
4105
4122
  }
4106
4123
  // Dedupe props in an object literal.
@@ -4255,7 +4272,7 @@ function processSlotOutlet(node, context) {
4255
4272
  }
4256
4273
  }
4257
4274
  else {
4258
- if (p.name === 'bind' && isBindKey(p.arg, 'name')) {
4275
+ if (p.name === 'bind' && isStaticArgOf(p.arg, 'name')) {
4259
4276
  if (p.exp)
4260
4277
  slotName = p.exp;
4261
4278
  }
@@ -4289,7 +4306,11 @@ const transformOn = (dir, node, context, augmentor) => {
4289
4306
  let eventName;
4290
4307
  if (arg.type === 4 /* SIMPLE_EXPRESSION */) {
4291
4308
  if (arg.isStatic) {
4292
- const rawName = arg.content;
4309
+ let rawName = arg.content;
4310
+ // TODO deprecate @vnodeXXX usage
4311
+ if (rawName.startsWith('vue:')) {
4312
+ rawName = `vnode-${rawName.slice(4)}`;
4313
+ }
4293
4314
  // for all event listeners, auto convert it to camelCase. See issue #2249
4294
4315
  eventName = createSimpleExpression(toHandlerKey(camelize$1(rawName)), true, arg.loc);
4295
4316
  }
@@ -4834,4 +4855,4 @@ function baseCompile(template, options = {}) {
4834
4855
 
4835
4856
  const noopDirectiveTransform = () => ({ props: [] });
4836
4857
 
4837
- export { BASE_TRANSITION, CAMELIZE, CAPITALIZE, CREATE_BLOCK, CREATE_COMMENT, CREATE_ELEMENT_BLOCK, CREATE_ELEMENT_VNODE, CREATE_SLOTS, CREATE_STATIC, CREATE_TEXT, CREATE_VNODE, FRAGMENT, GUARD_REACTIVE_PROPS, IS_MEMO_SAME, IS_REF, KEEP_ALIVE, MERGE_PROPS, NORMALIZE_CLASS, NORMALIZE_PROPS, NORMALIZE_STYLE, OPEN_BLOCK, POP_SCOPE_ID, PUSH_SCOPE_ID, RENDER_LIST, RENDER_SLOT, RESOLVE_COMPONENT, RESOLVE_DIRECTIVE, RESOLVE_DYNAMIC_COMPONENT, RESOLVE_FILTER, SET_BLOCK_TRACKING, SUSPENSE, TELEPORT, TO_DISPLAY_STRING, TO_HANDLERS, TO_HANDLER_KEY, UNREF, WITH_CTX, WITH_DIRECTIVES, WITH_MEMO, advancePositionWithClone, advancePositionWithMutation, assert, baseCompile, baseParse, buildProps, buildSlots, checkCompatEnabled, createArrayExpression, createAssignmentExpression, createBlockStatement, createCacheExpression, createCallExpression, createCompilerError, createCompoundExpression, createConditionalExpression, createForLoopParams, createFunctionExpression, createIfStatement, createInterpolation, createObjectExpression, createObjectProperty, createReturnStatement, createRoot, createSequenceExpression, createSimpleExpression, createStructuralDirectiveTransform, createTemplateLiteral, createTransformContext, createVNodeCall, extractIdentifiers, findDir, findProp, generate, getBaseTransformPreset, getInnerRange, getMemoedVNodeCall, getVNodeBlockHelper, getVNodeHelper, hasDynamicKeyVBind, hasScopeRef, helperNameMap, injectProp, isBindKey, isBuiltInType, isCoreComponent, isFunctionType, isInDestructureAssignment, isMemberExpression, isMemberExpressionBrowser, isMemberExpressionNode, isReferencedIdentifier, isSimpleIdentifier, isSlotOutlet, isStaticExp, isStaticProperty, isStaticPropertyKey, isTemplateNode, isText, isVSlot, locStub, makeBlock, noopDirectiveTransform, processExpression, processFor, processIf, processSlotOutlet, registerRuntimeHelpers, resolveComponentType, toValidAssetId, trackSlotScopes, trackVForSlotScopes, transform, transformBind, transformElement, transformExpression, transformModel, transformOn, traverseNode, walkBlockDeclarations, walkFunctionParams, walkIdentifiers, warnDeprecation };
4858
+ export { BASE_TRANSITION, CAMELIZE, CAPITALIZE, CREATE_BLOCK, CREATE_COMMENT, CREATE_ELEMENT_BLOCK, CREATE_ELEMENT_VNODE, CREATE_SLOTS, CREATE_STATIC, CREATE_TEXT, CREATE_VNODE, FRAGMENT, GUARD_REACTIVE_PROPS, IS_MEMO_SAME, IS_REF, KEEP_ALIVE, MERGE_PROPS, NORMALIZE_CLASS, NORMALIZE_PROPS, NORMALIZE_STYLE, OPEN_BLOCK, POP_SCOPE_ID, PUSH_SCOPE_ID, RENDER_LIST, RENDER_SLOT, RESOLVE_COMPONENT, RESOLVE_DIRECTIVE, RESOLVE_DYNAMIC_COMPONENT, RESOLVE_FILTER, SET_BLOCK_TRACKING, SUSPENSE, TELEPORT, TO_DISPLAY_STRING, TO_HANDLERS, TO_HANDLER_KEY, UNREF, WITH_CTX, WITH_DIRECTIVES, WITH_MEMO, advancePositionWithClone, advancePositionWithMutation, assert, baseCompile, baseParse, buildProps, buildSlots, checkCompatEnabled, createArrayExpression, createAssignmentExpression, createBlockStatement, createCacheExpression, createCallExpression, createCompilerError, createCompoundExpression, createConditionalExpression, createForLoopParams, createFunctionExpression, createIfStatement, createInterpolation, createObjectExpression, createObjectProperty, createReturnStatement, createRoot, createSequenceExpression, createSimpleExpression, createStructuralDirectiveTransform, createTemplateLiteral, createTransformContext, createVNodeCall, extractIdentifiers, findDir, findProp, generate, getBaseTransformPreset, getInnerRange, getMemoedVNodeCall, getVNodeBlockHelper, getVNodeHelper, hasDynamicKeyVBind, hasScopeRef, helperNameMap, injectProp, isBuiltInType, isCoreComponent, isFunctionType, isInDestructureAssignment, isMemberExpression, isMemberExpressionBrowser, isMemberExpressionNode, isReferencedIdentifier, isSimpleIdentifier, isSlotOutlet, isStaticArgOf, isStaticExp, isStaticProperty, isStaticPropertyKey, isTemplateNode, isText, isVSlot, locStub, makeBlock, noopDirectiveTransform, processExpression, processFor, processIf, processSlotOutlet, registerRuntimeHelpers, resolveComponentType, toValidAssetId, trackSlotScopes, trackVForSlotScopes, transform, transformBind, transformElement, transformExpression, transformModel, transformOn, traverseNode, walkBlockDeclarations, walkFunctionParams, walkIdentifiers, warnDeprecation };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vue/compiler-core",
3
- "version": "3.2.24",
3
+ "version": "3.2.28",
4
4
  "description": "@vue/compiler-core",
5
5
  "main": "index.js",
6
6
  "module": "dist/compiler-core.esm-bundler.js",
@@ -19,7 +19,7 @@
19
19
  },
20
20
  "repository": {
21
21
  "type": "git",
22
- "url": "git+https://github.com/vuejs/vue-next.git",
22
+ "url": "git+https://github.com/vuejs/core.git",
23
23
  "directory": "packages/compiler-core"
24
24
  },
25
25
  "keywords": [
@@ -28,16 +28,16 @@
28
28
  "author": "Evan You",
29
29
  "license": "MIT",
30
30
  "bugs": {
31
- "url": "https://github.com/vuejs/vue-next/issues"
31
+ "url": "https://github.com/vuejs/core/issues"
32
32
  },
33
- "homepage": "https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme",
33
+ "homepage": "https://github.com/vuejs/core/tree/main/packages/compiler-core#readme",
34
34
  "dependencies": {
35
- "@vue/shared": "3.2.24",
36
- "@babel/parser": "^7.15.0",
35
+ "@vue/shared": "3.2.28",
36
+ "@babel/parser": "^7.16.4",
37
37
  "estree-walker": "^2.0.2",
38
38
  "source-map": "^0.6.1"
39
39
  },
40
40
  "devDependencies": {
41
- "@babel/types": "^7.15.0"
41
+ "@babel/types": "^7.16.0"
42
42
  }
43
43
  }