@vue/compat 3.2.27 → 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.
package/README.md CHANGED
@@ -18,7 +18,7 @@ While we've tried hard to make the migration build mimic Vue 2 behavior as much
18
18
 
19
19
  - Internet Explorer 11 support: [Vue 3 has officially dropped the plan for IE11 support](https://github.com/vuejs/rfcs/blob/master/active-rfcs/0038-vue3-ie11-support.md). If you still need to support IE11 or below, you will have to stay on Vue 2.
20
20
 
21
- - Server-side rendering: the migration build can be used for SSR, but migrating a custom SSR setup is much more involved. The general idea is replacing `vue-server-renderer` with [`@vue/server-renderer`](https://github.com/vuejs/vue-next/tree/master/packages/server-renderer). Vue 3 no longer provides a bundle renderer and it is recommended to use Vue 3 SSR with [Vite](https://vitejs.dev/guide/ssr.html). If you are using [Nuxt.js](https://nuxtjs.org/), it is probably better to wait for Nuxt 3.
21
+ - Server-side rendering: the migration build can be used for SSR, but migrating a custom SSR setup is much more involved. The general idea is replacing `vue-server-renderer` with [`@vue/server-renderer`](https://github.com/vuejs/core/tree/main/packages/server-renderer). Vue 3 no longer provides a bundle renderer and it is recommended to use Vue 3 SSR with [Vite](https://vitejs.dev/guide/ssr.html). If you are using [Nuxt.js](https://nuxtjs.org/), it is probably better to wait for Nuxt 3.
22
22
 
23
23
  ### Expectations
24
24
 
@@ -259,7 +259,7 @@ Features that start with `COMPILER_` are compiler-specific: if you are using the
259
259
  | ID | Type | Description | Docs |
260
260
  | ------------------------------------- | ---- | ----------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
261
261
  | GLOBAL_MOUNT_CONTAINER | ⨂ | Mounted application does not replace the element it's mounted to | [link](https://v3.vuejs.org/guide/migration/mount-changes.html) |
262
- | CONFIG_DEVTOOLS | ⨂ | production devtools is now a build-time flag | [link](https://github.com/vuejs/vue-next/tree/master/packages/vue#bundler-build-feature-flags) |
262
+ | CONFIG_DEVTOOLS | ⨂ | production devtools is now a build-time flag | [link](https://github.com/vuejs/core/tree/main/packages/vue#bundler-build-feature-flags) |
263
263
  | COMPILER_V_IF_V_FOR_PRECEDENCE | ⨂ | `v-if` and `v-for` precedence when used on the same element has changed | [link](https://v3.vuejs.org/guide/migration/v-if-v-for.html) |
264
264
  | COMPILER_V_IF_SAME_KEY | ⨂ | `v-if` branches can no longer have the same key | [link](https://v3.vuejs.org/guide/migration/key-attribute.html#on-conditional-branches) |
265
265
  | COMPILER_V_FOR_TEMPLATE_KEY_PLACEMENT | ⨂ | `<template v-for>` key should now be placed on `<template>` | [link](https://v3.vuejs.org/guide/migration/key-attribute.html#with-template-v-for) |
package/dist/vue.cjs.js CHANGED
@@ -303,8 +303,20 @@ const SVG_TAGS = 'svg,animate,animateMotion,animateTransform,circle,clipPath,col
303
303
  'polygon,polyline,radialGradient,rect,set,solidcolor,stop,switch,symbol,' +
304
304
  'text,textPath,title,tspan,unknown,use,view';
305
305
  const VOID_TAGS = 'area,base,br,col,embed,hr,img,input,link,meta,param,source,track,wbr';
306
+ /**
307
+ * Compiler only.
308
+ * Do NOT use in runtime code paths unless behind `true` flag.
309
+ */
306
310
  const isHTMLTag = /*#__PURE__*/ makeMap(HTML_TAGS);
311
+ /**
312
+ * Compiler only.
313
+ * Do NOT use in runtime code paths unless behind `true` flag.
314
+ */
307
315
  const isSVGTag = /*#__PURE__*/ makeMap(SVG_TAGS);
316
+ /**
317
+ * Compiler only.
318
+ * Do NOT use in runtime code paths unless behind `true` flag.
319
+ */
308
320
  const isVoidTag = /*#__PURE__*/ makeMap(VOID_TAGS);
309
321
 
310
322
  const escapeRE = /["'&<>]/;
@@ -688,7 +700,7 @@ class ReactiveEffect {
688
700
  if (!this.active) {
689
701
  return this.fn();
690
702
  }
691
- if (!effectStack.includes(this)) {
703
+ if (!effectStack.length || !effectStack.includes(this)) {
692
704
  try {
693
705
  effectStack.push((activeEffect = this));
694
706
  enableTracking();
@@ -944,6 +956,9 @@ function createGetter(isReadonly = false, shallow = false) {
944
956
  else if (key === "__v_isReadonly" /* IS_READONLY */) {
945
957
  return isReadonly;
946
958
  }
959
+ else if (key === "__v_isShallow" /* IS_SHALLOW */) {
960
+ return shallow;
961
+ }
947
962
  else if (key === "__v_raw" /* RAW */ &&
948
963
  receiver ===
949
964
  (isReadonly
@@ -988,9 +1003,14 @@ const shallowSet = /*#__PURE__*/ createSetter(true);
988
1003
  function createSetter(shallow = false) {
989
1004
  return function set(target, key, value, receiver) {
990
1005
  let oldValue = target[key];
1006
+ if (isReadonly(oldValue) && isRef(oldValue)) {
1007
+ return false;
1008
+ }
991
1009
  if (!shallow && !isReadonly(value)) {
992
- value = toRaw(value);
993
- oldValue = toRaw(oldValue);
1010
+ if (!isShallow(value)) {
1011
+ value = toRaw(value);
1012
+ oldValue = toRaw(oldValue);
1013
+ }
994
1014
  if (!isArray(target) && isRef(oldValue) && !isRef(value)) {
995
1015
  oldValue.value = value;
996
1016
  return true;
@@ -1377,7 +1397,7 @@ function getTargetType(value) {
1377
1397
  }
1378
1398
  function reactive(target) {
1379
1399
  // if trying to observe a readonly proxy, return the readonly version.
1380
- if (target && target["__v_isReadonly" /* IS_READONLY */]) {
1400
+ if (isReadonly(target)) {
1381
1401
  return target;
1382
1402
  }
1383
1403
  return createReactiveObject(target, false, mutableHandlers, mutableCollectionHandlers, reactiveMap);
@@ -1442,6 +1462,9 @@ function isReactive(value) {
1442
1462
  function isReadonly(value) {
1443
1463
  return !!(value && value["__v_isReadonly" /* IS_READONLY */]);
1444
1464
  }
1465
+ function isShallow(value) {
1466
+ return !!(value && value["__v_isShallow" /* IS_SHALLOW */]);
1467
+ }
1445
1468
  function isProxy(value) {
1446
1469
  return isReactive(value) || isReadonly(value);
1447
1470
  }
@@ -1500,22 +1523,22 @@ function createRef(rawValue, shallow) {
1500
1523
  return new RefImpl(rawValue, shallow);
1501
1524
  }
1502
1525
  class RefImpl {
1503
- constructor(value, _shallow) {
1504
- this._shallow = _shallow;
1526
+ constructor(value, __v_isShallow) {
1527
+ this.__v_isShallow = __v_isShallow;
1505
1528
  this.dep = undefined;
1506
1529
  this.__v_isRef = true;
1507
- this._rawValue = _shallow ? value : toRaw(value);
1508
- this._value = _shallow ? value : toReactive(value);
1530
+ this._rawValue = __v_isShallow ? value : toRaw(value);
1531
+ this._value = __v_isShallow ? value : toReactive(value);
1509
1532
  }
1510
1533
  get value() {
1511
1534
  trackRefValue(this);
1512
1535
  return this._value;
1513
1536
  }
1514
1537
  set value(newVal) {
1515
- newVal = this._shallow ? newVal : toRaw(newVal);
1538
+ newVal = this.__v_isShallow ? newVal : toRaw(newVal);
1516
1539
  if (hasChanged(newVal, this._rawValue)) {
1517
1540
  this._rawValue = newVal;
1518
- this._value = this._shallow ? newVal : toReactive(newVal);
1541
+ this._value = this.__v_isShallow ? newVal : toReactive(newVal);
1519
1542
  triggerRefValue(this, newVal);
1520
1543
  }
1521
1544
  }
@@ -1598,22 +1621,23 @@ class ComputedRefImpl {
1598
1621
  constructor(getter, _setter, isReadonly, isSSR) {
1599
1622
  this._setter = _setter;
1600
1623
  this.dep = undefined;
1601
- this._dirty = true;
1602
1624
  this.__v_isRef = true;
1625
+ this._dirty = true;
1603
1626
  this.effect = new ReactiveEffect(getter, () => {
1604
1627
  if (!this._dirty) {
1605
1628
  this._dirty = true;
1606
1629
  triggerRefValue(this);
1607
1630
  }
1608
1631
  });
1609
- this.effect.active = !isSSR;
1632
+ this.effect.computed = this;
1633
+ this.effect.active = this._cacheable = !isSSR;
1610
1634
  this["__v_isReadonly" /* IS_READONLY */] = isReadonly;
1611
1635
  }
1612
1636
  get value() {
1613
1637
  // the computed ref may get wrapped by other proxies e.g. readonly() #3376
1614
1638
  const self = toRaw(this);
1615
1639
  trackRefValue(self);
1616
- if (self._dirty) {
1640
+ if (self._dirty || !self._cacheable) {
1617
1641
  self._dirty = false;
1618
1642
  self._value = self.effect.run();
1619
1643
  }
@@ -1790,7 +1814,7 @@ const ErrorTypeStrings = {
1790
1814
  [12 /* FUNCTION_REF */]: 'ref function',
1791
1815
  [13 /* ASYNC_COMPONENT_LOADER */]: 'async component loader',
1792
1816
  [14 /* SCHEDULER */]: 'scheduler flush. This is likely a Vue internals bug. ' +
1793
- 'Please open an issue at https://new-issue.vuejs.org/?repo=vuejs/vue-next'
1817
+ 'Please open an issue at https://new-issue.vuejs.org/?repo=vuejs/core'
1794
1818
  };
1795
1819
  function callWithErrorHandling(fn, instance, type, args) {
1796
1820
  let res;
@@ -2338,7 +2362,7 @@ const deprecationData = {
2338
2362
  ["CONFIG_DEVTOOLS" /* CONFIG_DEVTOOLS */]: {
2339
2363
  message: `config.devtools has been removed. To enable devtools for ` +
2340
2364
  `production, configure the __VUE_PROD_DEVTOOLS__ compile-time flag.`,
2341
- link: `https://github.com/vuejs/vue-next/tree/master/packages/vue#bundler-build-feature-flags`
2365
+ link: `https://github.com/vuejs/core/tree/main/packages/vue#bundler-build-feature-flags`
2342
2366
  },
2343
2367
  ["CONFIG_KEY_CODES" /* CONFIG_KEY_CODES */]: {
2344
2368
  message: `config.keyCodes has been removed. ` +
@@ -2525,7 +2549,7 @@ const deprecationData = {
2525
2549
  (isArray(comp.props)
2526
2550
  ? comp.props.includes('modelValue')
2527
2551
  : hasOwn(comp.props, 'modelValue'))) {
2528
- return (`Component delcares "modelValue" prop, which is Vue 3 usage, but ` +
2552
+ return (`Component declares "modelValue" prop, which is Vue 3 usage, but ` +
2529
2553
  `is running under Vue 2 compat v-model behavior. You can ${configMsg}`);
2530
2554
  }
2531
2555
  return (`v-model usage on component has changed in Vue 3. Component that expects ` +
@@ -2755,6 +2779,7 @@ const compatModelEventPrefix = `onModelCompat:`;
2755
2779
  const warnedTypes = new WeakSet();
2756
2780
  function convertLegacyVModelProps(vnode) {
2757
2781
  const { type, shapeFlag, props, dynamicProps } = vnode;
2782
+ const comp = type;
2758
2783
  if (shapeFlag & 6 /* COMPONENT */ && props && 'modelValue' in props) {
2759
2784
  if (!isCompatEnabled("COMPONENT_V_MODEL" /* COMPONENT_V_MODEL */,
2760
2785
  // this is a special case where we want to use the vnode component's
@@ -2763,16 +2788,18 @@ function convertLegacyVModelProps(vnode) {
2763
2788
  { type })) {
2764
2789
  return;
2765
2790
  }
2766
- if (!warnedTypes.has(type)) {
2791
+ if (!warnedTypes.has(comp)) {
2767
2792
  pushWarningContext(vnode);
2768
- warnDeprecation("COMPONENT_V_MODEL" /* COMPONENT_V_MODEL */, { type }, type);
2793
+ warnDeprecation("COMPONENT_V_MODEL" /* COMPONENT_V_MODEL */, { type }, comp);
2769
2794
  popWarningContext();
2770
- warnedTypes.add(type);
2795
+ warnedTypes.add(comp);
2771
2796
  }
2772
2797
  // v3 compiled model code -> v2 compat props
2773
2798
  // modelValue -> value
2774
2799
  // onUpdate:modelValue -> onModelCompat:input
2775
- const { prop = 'value', event = 'input' } = type.model || {};
2800
+ const model = comp.model || {};
2801
+ applyModelFromMixins(model, comp.mixins);
2802
+ const { prop = 'value', event = 'input' } = model;
2776
2803
  if (prop !== 'modelValue') {
2777
2804
  props[prop] = props.modelValue;
2778
2805
  delete props.modelValue;
@@ -2785,6 +2812,16 @@ function convertLegacyVModelProps(vnode) {
2785
2812
  delete props['onUpdate:modelValue'];
2786
2813
  }
2787
2814
  }
2815
+ function applyModelFromMixins(model, mixins) {
2816
+ if (mixins) {
2817
+ mixins.forEach(m => {
2818
+ if (m.model)
2819
+ extend(model, m.model);
2820
+ if (m.mixins)
2821
+ applyModelFromMixins(model, m.mixins);
2822
+ });
2823
+ }
2824
+ }
2788
2825
  function compatModelEmit(instance, event, args) {
2789
2826
  if (!isCompatEnabled("COMPONENT_V_MODEL" /* COMPONENT_V_MODEL */, instance)) {
2790
2827
  return;
@@ -3787,7 +3824,7 @@ function inject(key, defaultValue, treatDefaultAsFactory = false) {
3787
3824
  if (instance) {
3788
3825
  // #2400
3789
3826
  // to support `app.use` plugins,
3790
- // fallback to appContext's `provides` if the intance is at root
3827
+ // fallback to appContext's `provides` if the instance is at root
3791
3828
  const provides = instance.parent == null
3792
3829
  ? instance.vnode.appContext && instance.vnode.appContext.provides
3793
3830
  : instance.parent.provides;
@@ -3853,7 +3890,7 @@ function doWatch(source, cb, { immediate, deep, flush, onTrack, onTrigger } = EM
3853
3890
  let isMultiSource = false;
3854
3891
  if (isRef(source)) {
3855
3892
  getter = () => source.value;
3856
- forceTrigger = !!source._shallow;
3893
+ forceTrigger = isShallow(source);
3857
3894
  }
3858
3895
  else if (isReactive(source)) {
3859
3896
  getter = () => source;
@@ -4764,7 +4801,7 @@ function matches(pattern, name) {
4764
4801
  return pattern.some((p) => matches(p, name));
4765
4802
  }
4766
4803
  else if (isString(pattern)) {
4767
- return pattern.split(',').indexOf(name) > -1;
4804
+ return pattern.split(',').includes(name);
4768
4805
  }
4769
4806
  else if (pattern.test) {
4770
4807
  return pattern.test(name);
@@ -5032,7 +5069,7 @@ function applyOptions(instance) {
5032
5069
  warn$1(`Write operation failed: computed property "${key}" is readonly.`);
5033
5070
  }
5034
5071
  ;
5035
- const c = computed({
5072
+ const c = computed$1({
5036
5073
  get,
5037
5074
  set
5038
5075
  });
@@ -5513,7 +5550,9 @@ function updateProps(instance, rawProps, rawPrevProps, optimized) {
5513
5550
  // attrs point to the same object so it should already have been updated.
5514
5551
  if (attrs !== rawCurrentProps) {
5515
5552
  for (const key in attrs) {
5516
- if (!rawProps || !hasOwn(rawProps, key)) {
5553
+ if (!rawProps ||
5554
+ (!hasOwn(rawProps, key) &&
5555
+ (!hasOwn(rawProps, key + 'Native')))) {
5517
5556
  delete attrs[key];
5518
5557
  hasAttrsChanged = true;
5519
5558
  }
@@ -6151,7 +6190,7 @@ function createCompatVue(createApp, createSingletonApp) {
6151
6190
  return vm;
6152
6191
  }
6153
6192
  }
6154
- Vue.version = "3.2.27";
6193
+ Vue.version = `2.6.14-compat:${"3.2.28"}`;
6155
6194
  Vue.config = singletonApp.config;
6156
6195
  Vue.use = (p, ...options) => {
6157
6196
  if (p && isFunction(p.install)) {
@@ -7140,6 +7179,7 @@ function createHydrationFunctions(rendererInternals) {
7140
7179
  return [hydrate, hydrateNode];
7141
7180
  }
7142
7181
 
7182
+ /* eslint-disable no-restricted-globals */
7143
7183
  let supported;
7144
7184
  let perf;
7145
7185
  function startMeasure(instance, type) {
@@ -7167,7 +7207,6 @@ function isSupported() {
7167
7207
  if (supported !== undefined) {
7168
7208
  return supported;
7169
7209
  }
7170
- /* eslint-disable no-restricted-globals */
7171
7210
  if (typeof window !== 'undefined' && window.performance) {
7172
7211
  supported = true;
7173
7212
  perf = window.performance;
@@ -7175,7 +7214,6 @@ function isSupported() {
7175
7214
  else {
7176
7215
  supported = false;
7177
7216
  }
7178
- /* eslint-enable no-restricted-globals */
7179
7217
  return supported;
7180
7218
  }
7181
7219
 
@@ -9421,7 +9459,7 @@ function cloneVNode(vnode, extraProps, mergeRef = false) {
9421
9459
  shapeFlag: vnode.shapeFlag,
9422
9460
  // if the vnode is cloned with extra props, we can no longer assume its
9423
9461
  // existing patch flag to be reliable and need to add the FULL_PROPS flag.
9424
- // note: perserve flag for fragments since they use the flag for children
9462
+ // note: preserve flag for fragments since they use the flag for children
9425
9463
  // fast paths only.
9426
9464
  patchFlag: extraProps && vnode.type !== Fragment
9427
9465
  ? patchFlag === -1 // hoisted node
@@ -9586,7 +9624,8 @@ function mergeProps(...args) {
9586
9624
  else if (isOn(key)) {
9587
9625
  const existing = ret[key];
9588
9626
  const incoming = toMerge[key];
9589
- if (existing !== incoming &&
9627
+ if (incoming &&
9628
+ existing !== incoming &&
9590
9629
  !(isArray(existing) && existing.includes(incoming))) {
9591
9630
  ret[key] = existing
9592
9631
  ? [].concat(existing, incoming)
@@ -9862,7 +9901,7 @@ function legacyCheckKeyCodes(instance, eventKeyCode, key, builtInKeyCode, eventK
9862
9901
  }
9863
9902
  function isKeyNotMatch(expect, actual) {
9864
9903
  if (isArray(expect)) {
9865
- return expect.indexOf(actual) === -1;
9904
+ return !expect.includes(actual);
9866
9905
  }
9867
9906
  else {
9868
9907
  return expect !== actual;
@@ -9941,7 +9980,7 @@ function installCompatInstanceProperties(map) {
9941
9980
  extend(map, {
9942
9981
  // needed by many libs / render fns
9943
9982
  $vnode: i => i.vnode,
9944
- // inject addtional properties into $options for compat
9983
+ // inject additional properties into $options for compat
9945
9984
  // e.g. vuex needs this.$options.parent
9946
9985
  $options: i => {
9947
9986
  const res = extend({}, resolveMergedOptions(i));
@@ -10673,7 +10712,7 @@ function defineEmits() {
10673
10712
  * instance properties when it is accessed by a parent component via template
10674
10713
  * refs.
10675
10714
  *
10676
- * `<script setup>` components are closed by default - i.e. varaibles inside
10715
+ * `<script setup>` components are closed by default - i.e. variables inside
10677
10716
  * the `<script setup>` scope is not exposed to parent unless explicitly exposed
10678
10717
  * via `defineExpose`.
10679
10718
  *
@@ -10876,7 +10915,7 @@ function initCustomFormatter() {
10876
10915
  return [
10877
10916
  'div',
10878
10917
  {},
10879
- ['span', vueStyle, 'Reactive'],
10918
+ ['span', vueStyle, isShallow(obj) ? 'ShallowReactive' : 'Reactive'],
10880
10919
  '<',
10881
10920
  formatValue(obj),
10882
10921
  `>${isReadonly(obj) ? ` (readonly)` : ``}`
@@ -10886,7 +10925,7 @@ function initCustomFormatter() {
10886
10925
  return [
10887
10926
  'div',
10888
10927
  {},
10889
- ['span', vueStyle, 'Readonly'],
10928
+ ['span', vueStyle, isShallow(obj) ? 'ShallowReadonly' : 'Readonly'],
10890
10929
  '<',
10891
10930
  formatValue(obj),
10892
10931
  '>'
@@ -11015,7 +11054,7 @@ function initCustomFormatter() {
11015
11054
  }
11016
11055
  }
11017
11056
  function genRefFlag(v) {
11018
- if (v._shallow) {
11057
+ if (isShallow(v)) {
11019
11058
  return `ShallowRef`;
11020
11059
  }
11021
11060
  if (v.effect) {
@@ -11059,7 +11098,7 @@ function isMemoSame(cached, memo) {
11059
11098
  }
11060
11099
 
11061
11100
  // Core API ------------------------------------------------------------------
11062
- const version = "3.2.27";
11101
+ const version = "3.2.28";
11063
11102
  const _ssrUtils = {
11064
11103
  createComponentInstance,
11065
11104
  setupComponent,
@@ -11498,7 +11537,7 @@ function patchStopImmediatePropagation(e, value) {
11498
11537
  originalStop.call(e);
11499
11538
  e._stopped = true;
11500
11539
  };
11501
- return value.map(fn => (e) => !e._stopped && fn(e));
11540
+ return value.map(fn => (e) => !e._stopped && fn && fn(e));
11502
11541
  }
11503
11542
  else {
11504
11543
  return value;
@@ -12864,6 +12903,7 @@ var runtimeDom = /*#__PURE__*/Object.freeze({
12864
12903
  isProxy: isProxy,
12865
12904
  isReactive: isReactive,
12866
12905
  isReadonly: isReadonly,
12906
+ isShallow: isShallow,
12867
12907
  customRef: customRef,
12868
12908
  triggerRef: triggerRef,
12869
12909
  shallowRef: shallowRef,
@@ -14179,7 +14219,7 @@ function parseAttributes(context, type) {
14179
14219
  }
14180
14220
  const attr = parseAttribute(context, attributeNames);
14181
14221
  // Trim whitespace between class
14182
- // https://github.com/vuejs/vue-next/issues/4251
14222
+ // https://github.com/vuejs/core/issues/4251
14183
14223
  if (attr.type === 6 /* ATTRIBUTE */ &&
14184
14224
  attr.value &&
14185
14225
  attr.name === 'class') {
@@ -14415,7 +14455,7 @@ function parseTextData(context, length, mode) {
14415
14455
  advanceBy(context, length);
14416
14456
  if (mode === 2 /* RAWTEXT */ ||
14417
14457
  mode === 3 /* CDATA */ ||
14418
- rawText.indexOf('&') === -1) {
14458
+ !rawText.includes('&')) {
14419
14459
  return rawText;
14420
14460
  }
14421
14461
  else {
@@ -16157,7 +16197,7 @@ function isReferenced(node, parent, grandparent) {
16157
16197
  // no: NODE.target
16158
16198
  case 'MetaProperty':
16159
16199
  return false;
16160
- // yes: type X = { somePropert: NODE }
16200
+ // yes: type X = { someProperty: NODE }
16161
16201
  // no: type X = { NODE: OtherType }
16162
16202
  case 'ObjectTypeProperty':
16163
16203
  return parent.key !== node;
@@ -16668,6 +16708,7 @@ const transformFor = createStructuralDirectiveTransform('for', (node, dir, conte
16668
16708
  const renderExp = createCallExpression(helper(RENDER_LIST), [
16669
16709
  forNode.source
16670
16710
  ]);
16711
+ const isTemplate = isTemplateNode(node);
16671
16712
  const memo = findDir(node, 'memo');
16672
16713
  const keyProp = findProp(node, `key`);
16673
16714
  const keyExp = keyProp &&
@@ -16675,15 +16716,17 @@ const transformFor = createStructuralDirectiveTransform('for', (node, dir, conte
16675
16716
  ? createSimpleExpression(keyProp.value.content, true)
16676
16717
  : keyProp.exp);
16677
16718
  const keyProperty = keyProp ? createObjectProperty(`key`, keyExp) : null;
16678
- if (context.prefixIdentifiers &&
16679
- keyProperty &&
16680
- keyProp.type !== 6 /* ATTRIBUTE */) {
16681
- // #2085 process :key expression needs to be processed in order for it
16682
- // to behave consistently for <template v-for> and <div v-for>.
16683
- // In the case of `<template v-for>`, the node is discarded and never
16684
- // traversed so its key expression won't be processed by the normal
16685
- // transforms.
16686
- keyProperty.value = processExpression(keyProperty.value, context);
16719
+ if (isTemplate) {
16720
+ // #2085 / #5288 process :key and v-memo expressions need to be
16721
+ // processed on `<template v-for>`. In this case the node is discarded
16722
+ // and never traversed so its binding expressions won't be processed
16723
+ // by the normal transforms.
16724
+ if (memo) {
16725
+ memo.exp = processExpression(memo.exp, context);
16726
+ }
16727
+ if (keyProperty && keyProp.type !== 6 /* ATTRIBUTE */) {
16728
+ keyProperty.value = processExpression(keyProperty.value, context);
16729
+ }
16687
16730
  }
16688
16731
  const isStableFragment = forNode.source.type === 4 /* SIMPLE_EXPRESSION */ &&
16689
16732
  forNode.source.constType > 0 /* NOT_CONSTANT */;
@@ -16697,7 +16740,6 @@ const transformFor = createStructuralDirectiveTransform('for', (node, dir, conte
16697
16740
  return () => {
16698
16741
  // finish the codegen now that all children have been traversed
16699
16742
  let childBlock;
16700
- const isTemplate = isTemplateNode(node);
16701
16743
  const { children } = forNode;
16702
16744
  // check <template v-for> key placement
16703
16745
  if (isTemplate) {