vue 3.2.21 → 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');
@@ -530,7 +530,7 @@ const targetMap = new WeakMap();
530
530
  let effectTrackDepth = 0;
531
531
  let trackOpBit = 1;
532
532
  /**
533
- * The bitwise track markers support at most 30 levels op recursion.
533
+ * The bitwise track markers support at most 30 levels of recursion.
534
534
  * This value is chosen to enable modern JS engines to use a SMI on all platforms.
535
535
  * When recursion depth is greater, fall back to using a full cleanup.
536
536
  */
@@ -851,7 +851,7 @@ const shallowSet = /*#__PURE__*/ createSetter(true);
851
851
  function createSetter(shallow = false) {
852
852
  return function set(target, key, value, receiver) {
853
853
  let oldValue = target[key];
854
- if (!shallow) {
854
+ if (!shallow && !isReadonly(value)) {
855
855
  value = toRaw(value);
856
856
  oldValue = toRaw(oldValue);
857
857
  if (!isArray(target) && isRef(oldValue) && !isRef(value)) {
@@ -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 {
@@ -1657,6 +1661,7 @@ function emit(event, ...args) {
1657
1661
  }
1658
1662
  }
1659
1663
  function setDevtoolsHook(hook, target) {
1664
+ var _a, _b;
1660
1665
  devtools = hook;
1661
1666
  if (devtools) {
1662
1667
  devtools.enabled = true;
@@ -1669,7 +1674,10 @@ function setDevtoolsHook(hook, target) {
1669
1674
  // (#4815)
1670
1675
  // eslint-disable-next-line no-restricted-globals
1671
1676
  typeof window !== 'undefined' &&
1672
- !navigator.userAgent.includes('jsdom')) {
1677
+ // some envs mock window but not fully
1678
+ window.HTMLElement &&
1679
+ // also exclude jsdom
1680
+ !((_b = (_a = window.navigator) === null || _a === void 0 ? void 0 : _a.userAgent) === null || _b === void 0 ? void 0 : _b.includes('jsdom'))) {
1673
1681
  const replay = (target.__VUE_DEVTOOLS_HOOK_REPLAY__ =
1674
1682
  target.__VUE_DEVTOOLS_HOOK_REPLAY__ || []);
1675
1683
  replay.push((newHook) => {
@@ -2763,7 +2771,8 @@ const BaseTransitionImpl = {
2763
2771
  const rawProps = toRaw(props);
2764
2772
  const { mode } = rawProps;
2765
2773
  // check mode
2766
- if (mode && !['in-out', 'out-in', 'default'].includes(mode)) {
2774
+ if (mode &&
2775
+ mode !== 'in-out' && mode !== 'out-in' && mode !== 'default') {
2767
2776
  warn$1(`invalid <transition> mode: ${mode}`);
2768
2777
  }
2769
2778
  // at this point children has a guaranteed length of 1.
@@ -3403,7 +3412,7 @@ function registerKeepAliveHook(hook, type, target = currentInstance) {
3403
3412
  }
3404
3413
  current = current.parent;
3405
3414
  }
3406
- hook();
3415
+ return hook();
3407
3416
  });
3408
3417
  injectHook(type, wrappedHook, target);
3409
3418
  // In addition to registering it on the target instance, we walk up the parent
@@ -4065,7 +4074,7 @@ function setFullProps(instance, rawProps, props, attrs) {
4065
4074
  }
4066
4075
  }
4067
4076
  else if (!isEmitListener(instance.emitsOptions, key)) {
4068
- if (value !== attrs[key]) {
4077
+ if (!(key in attrs) || value !== attrs[key]) {
4069
4078
  attrs[key] = value;
4070
4079
  hasAttrsChanged = true;
4071
4080
  }
@@ -4705,6 +4714,102 @@ function createAppAPI(render, hydrate) {
4705
4714
  };
4706
4715
  }
4707
4716
 
4717
+ /**
4718
+ * Function for handling a template ref
4719
+ */
4720
+ function setRef(rawRef, oldRawRef, parentSuspense, vnode, isUnmount = false) {
4721
+ if (isArray(rawRef)) {
4722
+ rawRef.forEach((r, i) => setRef(r, oldRawRef && (isArray(oldRawRef) ? oldRawRef[i] : oldRawRef), parentSuspense, vnode, isUnmount));
4723
+ return;
4724
+ }
4725
+ if (isAsyncWrapper(vnode) && !isUnmount) {
4726
+ // when mounting async components, nothing needs to be done,
4727
+ // because the template ref is forwarded to inner component
4728
+ return;
4729
+ }
4730
+ const refValue = vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */
4731
+ ? getExposeProxy(vnode.component) || vnode.component.proxy
4732
+ : vnode.el;
4733
+ const value = isUnmount ? null : refValue;
4734
+ const { i: owner, r: ref } = rawRef;
4735
+ if (!owner) {
4736
+ warn$1(`Missing ref owner context. ref cannot be used on hoisted vnodes. ` +
4737
+ `A vnode with ref must be created inside the render function.`);
4738
+ return;
4739
+ }
4740
+ const oldRef = oldRawRef && oldRawRef.r;
4741
+ const refs = owner.refs === EMPTY_OBJ ? (owner.refs = {}) : owner.refs;
4742
+ const setupState = owner.setupState;
4743
+ // dynamic ref changed. unset old ref
4744
+ if (oldRef != null && oldRef !== ref) {
4745
+ if (isString(oldRef)) {
4746
+ refs[oldRef] = null;
4747
+ if (hasOwn(setupState, oldRef)) {
4748
+ setupState[oldRef] = null;
4749
+ }
4750
+ }
4751
+ else if (isRef(oldRef)) {
4752
+ oldRef.value = null;
4753
+ }
4754
+ }
4755
+ if (isFunction(ref)) {
4756
+ callWithErrorHandling(ref, owner, 12 /* FUNCTION_REF */, [value, refs]);
4757
+ }
4758
+ else {
4759
+ const _isString = isString(ref);
4760
+ const _isRef = isRef(ref);
4761
+ if (_isString || _isRef) {
4762
+ const doSet = () => {
4763
+ if (rawRef.f) {
4764
+ const existing = _isString ? refs[ref] : ref.value;
4765
+ if (isUnmount) {
4766
+ isArray(existing) && remove(existing, refValue);
4767
+ }
4768
+ else {
4769
+ if (!isArray(existing)) {
4770
+ if (_isString) {
4771
+ refs[ref] = [refValue];
4772
+ }
4773
+ else {
4774
+ ref.value = [refValue];
4775
+ if (rawRef.k)
4776
+ refs[rawRef.k] = ref.value;
4777
+ }
4778
+ }
4779
+ else if (!existing.includes(refValue)) {
4780
+ existing.push(refValue);
4781
+ }
4782
+ }
4783
+ }
4784
+ else if (_isString) {
4785
+ refs[ref] = value;
4786
+ if (hasOwn(setupState, ref)) {
4787
+ setupState[ref] = value;
4788
+ }
4789
+ }
4790
+ else if (isRef(ref)) {
4791
+ ref.value = value;
4792
+ if (rawRef.k)
4793
+ refs[rawRef.k] = value;
4794
+ }
4795
+ else {
4796
+ warn$1('Invalid template ref type:', ref, `(${typeof ref})`);
4797
+ }
4798
+ };
4799
+ if (value) {
4800
+ doSet.id = -1;
4801
+ queuePostRenderEffect(doSet, parentSuspense);
4802
+ }
4803
+ else {
4804
+ doSet();
4805
+ }
4806
+ }
4807
+ else {
4808
+ warn$1('Invalid template ref type:', ref, `(${typeof ref})`);
4809
+ }
4810
+ }
4811
+ }
4812
+
4708
4813
  let hasMismatch = false;
4709
4814
  const isSVGContainer = (container) => /svg/.test(container.namespaceURI) && container.tagName !== 'foreignObject';
4710
4815
  const isComment = (node) => node.nodeType === 8 /* COMMENT */;
@@ -5337,12 +5442,15 @@ function baseCreateRenderer(options, createHydrationFns) {
5337
5442
  const oldProps = n1.props || EMPTY_OBJ;
5338
5443
  const newProps = n2.props || EMPTY_OBJ;
5339
5444
  let vnodeHook;
5445
+ // disable recurse in beforeUpdate hooks
5446
+ parentComponent && toggleRecurse(parentComponent, false);
5340
5447
  if ((vnodeHook = newProps.onVnodeBeforeUpdate)) {
5341
5448
  invokeVNodeHook(vnodeHook, parentComponent, n2, n1);
5342
5449
  }
5343
5450
  if (dirs) {
5344
5451
  invokeDirectiveHook(n2, n1, parentComponent, 'beforeUpdate');
5345
5452
  }
5453
+ parentComponent && toggleRecurse(parentComponent, true);
5346
5454
  if (isHmrUpdating) {
5347
5455
  // HMR updated, force full diff
5348
5456
  patchFlag = 0;
@@ -5622,7 +5730,7 @@ function baseCreateRenderer(options, createHydrationFns) {
5622
5730
  const { el, props } = initialVNode;
5623
5731
  const { bm, m, parent } = instance;
5624
5732
  const isAsyncWrapperVNode = isAsyncWrapper(initialVNode);
5625
- effect.allowRecurse = false;
5733
+ toggleRecurse(instance, false);
5626
5734
  // beforeMount hook
5627
5735
  if (bm) {
5628
5736
  invokeArrayFns(bm);
@@ -5632,7 +5740,7 @@ function baseCreateRenderer(options, createHydrationFns) {
5632
5740
  (vnodeHook = props && props.onVnodeBeforeMount)) {
5633
5741
  invokeVNodeHook(vnodeHook, parent, initialVNode);
5634
5742
  }
5635
- effect.allowRecurse = true;
5743
+ toggleRecurse(instance, true);
5636
5744
  if (el && hydrateNode) {
5637
5745
  // vnode has adopted host node - perform hydration instead of mount.
5638
5746
  const hydrateSubTree = () => {
@@ -5714,7 +5822,7 @@ function baseCreateRenderer(options, createHydrationFns) {
5714
5822
  pushWarningContext(next || instance.vnode);
5715
5823
  }
5716
5824
  // Disallow component effect recursion during pre-lifecycle hooks.
5717
- effect.allowRecurse = false;
5825
+ toggleRecurse(instance, false);
5718
5826
  if (next) {
5719
5827
  next.el = vnode.el;
5720
5828
  updateComponentPreRender(instance, next, optimized);
@@ -5730,7 +5838,7 @@ function baseCreateRenderer(options, createHydrationFns) {
5730
5838
  if ((vnodeHook = next.props && next.props.onVnodeBeforeUpdate)) {
5731
5839
  invokeVNodeHook(vnodeHook, parent, next, vnode);
5732
5840
  }
5733
- effect.allowRecurse = true;
5841
+ toggleRecurse(instance, true);
5734
5842
  // render
5735
5843
  {
5736
5844
  startMeasure(instance, `render`);
@@ -5776,13 +5884,13 @@ function baseCreateRenderer(options, createHydrationFns) {
5776
5884
  }
5777
5885
  };
5778
5886
  // create reactive effect for rendering
5779
- const effect = new ReactiveEffect(componentUpdateFn, () => queueJob(instance.update), instance.scope // track it in component's effect scope
5780
- );
5887
+ const effect = (instance.effect = new ReactiveEffect(componentUpdateFn, () => queueJob(instance.update), instance.scope // track it in component's effect scope
5888
+ ));
5781
5889
  const update = (instance.update = effect.run.bind(effect));
5782
5890
  update.id = instance.uid;
5783
5891
  // allowRecurse
5784
5892
  // #1801, #2043 component render effects should allow recursive updates
5785
- effect.allowRecurse = update.allowRecurse = true;
5893
+ toggleRecurse(instance, true);
5786
5894
  {
5787
5895
  effect.onTrack = instance.rtc
5788
5896
  ? e => invokeArrayFns(instance.rtc, e)
@@ -6306,85 +6414,8 @@ function baseCreateRenderer(options, createHydrationFns) {
6306
6414
  createApp: createAppAPI(render, hydrate)
6307
6415
  };
6308
6416
  }
6309
- function setRef(rawRef, oldRawRef, parentSuspense, vnode, isUnmount = false) {
6310
- if (isArray(rawRef)) {
6311
- rawRef.forEach((r, i) => setRef(r, oldRawRef && (isArray(oldRawRef) ? oldRawRef[i] : oldRawRef), parentSuspense, vnode, isUnmount));
6312
- return;
6313
- }
6314
- if (isAsyncWrapper(vnode) && !isUnmount) {
6315
- // when mounting async components, nothing needs to be done,
6316
- // because the template ref is forwarded to inner component
6317
- return;
6318
- }
6319
- const refValue = vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */
6320
- ? getExposeProxy(vnode.component) || vnode.component.proxy
6321
- : vnode.el;
6322
- const value = isUnmount ? null : refValue;
6323
- const { i: owner, r: ref } = rawRef;
6324
- if (!owner) {
6325
- warn$1(`Missing ref owner context. ref cannot be used on hoisted vnodes. ` +
6326
- `A vnode with ref must be created inside the render function.`);
6327
- return;
6328
- }
6329
- const oldRef = oldRawRef && oldRawRef.r;
6330
- const refs = owner.refs === EMPTY_OBJ ? (owner.refs = {}) : owner.refs;
6331
- const setupState = owner.setupState;
6332
- // dynamic ref changed. unset old ref
6333
- if (oldRef != null && oldRef !== ref) {
6334
- if (isString(oldRef)) {
6335
- refs[oldRef] = null;
6336
- if (hasOwn(setupState, oldRef)) {
6337
- setupState[oldRef] = null;
6338
- }
6339
- }
6340
- else if (isRef(oldRef)) {
6341
- oldRef.value = null;
6342
- }
6343
- }
6344
- if (isString(ref)) {
6345
- const doSet = () => {
6346
- {
6347
- refs[ref] = value;
6348
- }
6349
- if (hasOwn(setupState, ref)) {
6350
- setupState[ref] = value;
6351
- }
6352
- };
6353
- // #1789: for non-null values, set them after render
6354
- // null values means this is unmount and it should not overwrite another
6355
- // ref with the same key
6356
- if (value) {
6357
- doSet.id = -1;
6358
- queuePostRenderEffect(doSet, parentSuspense);
6359
- }
6360
- else {
6361
- doSet();
6362
- }
6363
- }
6364
- else if (isRef(ref)) {
6365
- const doSet = () => {
6366
- ref.value = value;
6367
- };
6368
- if (value) {
6369
- doSet.id = -1;
6370
- queuePostRenderEffect(doSet, parentSuspense);
6371
- }
6372
- else {
6373
- doSet();
6374
- }
6375
- }
6376
- else if (isFunction(ref)) {
6377
- callWithErrorHandling(ref, owner, 12 /* FUNCTION_REF */, [value, refs]);
6378
- }
6379
- else {
6380
- warn$1('Invalid template ref type:', value, `(${typeof value})`);
6381
- }
6382
- }
6383
- function invokeVNodeHook(hook, instance, vnode, prevVNode = null) {
6384
- callWithAsyncErrorHandling(hook, instance, 7 /* VNODE_HOOK */, [
6385
- vnode,
6386
- prevVNode
6387
- ]);
6417
+ function toggleRecurse({ effect, update }, allowed) {
6418
+ effect.allowRecurse = update.allowRecurse = allowed;
6388
6419
  }
6389
6420
  /**
6390
6421
  * #1156
@@ -6394,8 +6425,8 @@ function invokeVNodeHook(hook, instance, vnode, prevVNode = null) {
6394
6425
  *
6395
6426
  * #2080
6396
6427
  * Inside keyed `template` fragment static children, if a fragment is moved,
6397
- * the children will always moved so that need inherit el form previous nodes
6398
- * to ensure correct moved position.
6428
+ * the children will always be moved. Therefore, in order to ensure correct move
6429
+ * position, el should be inherited from previous nodes.
6399
6430
  */
6400
6431
  function traverseStaticChildren(n1, n2, shallow = false) {
6401
6432
  const ch1 = n1.children;
@@ -6843,10 +6874,10 @@ const createVNodeWithArgsTransform = (...args) => {
6843
6874
  };
6844
6875
  const InternalObjectKey = `__vInternal`;
6845
6876
  const normalizeKey = ({ key }) => key != null ? key : null;
6846
- const normalizeRef = ({ ref }) => {
6877
+ const normalizeRef = ({ ref, ref_key, ref_for }) => {
6847
6878
  return (ref != null
6848
6879
  ? isString(ref) || isRef(ref) || isFunction(ref)
6849
- ? { i: currentRenderingInstance, r: ref }
6880
+ ? { i: currentRenderingInstance, r: ref, k: ref_key, f: !!ref_for }
6850
6881
  : ref
6851
6882
  : null);
6852
6883
  };
@@ -7175,7 +7206,8 @@ function mergeProps(...args) {
7175
7206
  else if (isOn(key)) {
7176
7207
  const existing = ret[key];
7177
7208
  const incoming = toMerge[key];
7178
- if (existing !== incoming) {
7209
+ if (existing !== incoming &&
7210
+ !(isArray(existing) && existing.includes(incoming))) {
7179
7211
  ret[key] = existing
7180
7212
  ? [].concat(existing, incoming)
7181
7213
  : incoming;
@@ -7187,6 +7219,12 @@ function mergeProps(...args) {
7187
7219
  }
7188
7220
  }
7189
7221
  return ret;
7222
+ }
7223
+ function invokeVNodeHook(hook, instance, vnode, prevVNode = null) {
7224
+ callWithAsyncErrorHandling(hook, instance, 7 /* VNODE_HOOK */, [
7225
+ vnode,
7226
+ prevVNode
7227
+ ]);
7190
7228
  }
7191
7229
 
7192
7230
  /**
@@ -7378,23 +7416,23 @@ const PublicInstanceProxyHandlers = {
7378
7416
  const n = accessCache[key];
7379
7417
  if (n !== undefined) {
7380
7418
  switch (n) {
7381
- case 0 /* SETUP */:
7419
+ case 1 /* SETUP */:
7382
7420
  return setupState[key];
7383
- case 1 /* DATA */:
7421
+ case 2 /* DATA */:
7384
7422
  return data[key];
7385
- case 3 /* CONTEXT */:
7423
+ case 4 /* CONTEXT */:
7386
7424
  return ctx[key];
7387
- case 2 /* PROPS */:
7425
+ case 3 /* PROPS */:
7388
7426
  return props[key];
7389
7427
  // default: just fallthrough
7390
7428
  }
7391
7429
  }
7392
7430
  else if (setupState !== EMPTY_OBJ && hasOwn(setupState, key)) {
7393
- accessCache[key] = 0 /* SETUP */;
7431
+ accessCache[key] = 1 /* SETUP */;
7394
7432
  return setupState[key];
7395
7433
  }
7396
7434
  else if (data !== EMPTY_OBJ && hasOwn(data, key)) {
7397
- accessCache[key] = 1 /* DATA */;
7435
+ accessCache[key] = 2 /* DATA */;
7398
7436
  return data[key];
7399
7437
  }
7400
7438
  else if (
@@ -7402,15 +7440,15 @@ const PublicInstanceProxyHandlers = {
7402
7440
  // props
7403
7441
  (normalizedProps = instance.propsOptions[0]) &&
7404
7442
  hasOwn(normalizedProps, key)) {
7405
- accessCache[key] = 2 /* PROPS */;
7443
+ accessCache[key] = 3 /* PROPS */;
7406
7444
  return props[key];
7407
7445
  }
7408
7446
  else if (ctx !== EMPTY_OBJ && hasOwn(ctx, key)) {
7409
- accessCache[key] = 3 /* CONTEXT */;
7447
+ accessCache[key] = 4 /* CONTEXT */;
7410
7448
  return ctx[key];
7411
7449
  }
7412
7450
  else if (shouldCacheAccess) {
7413
- accessCache[key] = 4 /* OTHER */;
7451
+ accessCache[key] = 0 /* OTHER */;
7414
7452
  }
7415
7453
  }
7416
7454
  const publicGetter = publicPropertiesMap[key];
@@ -7431,7 +7469,7 @@ const PublicInstanceProxyHandlers = {
7431
7469
  }
7432
7470
  else if (ctx !== EMPTY_OBJ && hasOwn(ctx, key)) {
7433
7471
  // user may set custom properties to `this` that start with `$`
7434
- accessCache[key] = 3 /* CONTEXT */;
7472
+ accessCache[key] = 4 /* CONTEXT */;
7435
7473
  return ctx[key];
7436
7474
  }
7437
7475
  else if (
@@ -7492,7 +7530,7 @@ const PublicInstanceProxyHandlers = {
7492
7530
  },
7493
7531
  has({ _: { data, setupState, accessCache, ctx, appContext, propsOptions } }, key) {
7494
7532
  let normalizedProps;
7495
- return (accessCache[key] !== undefined ||
7533
+ return (!!accessCache[key] ||
7496
7534
  (data !== EMPTY_OBJ && hasOwn(data, key)) ||
7497
7535
  (setupState !== EMPTY_OBJ && hasOwn(setupState, key)) ||
7498
7536
  ((normalizedProps = propsOptions[0]) && hasOwn(normalizedProps, key)) ||
@@ -7598,6 +7636,7 @@ function createComponentInstance(vnode, parent, suspense) {
7598
7636
  root: null,
7599
7637
  next: null,
7600
7638
  subTree: null,
7639
+ effect: null,
7601
7640
  update: null,
7602
7641
  scope: new EffectScope(true /* detached */),
7603
7642
  render: null,
@@ -9039,7 +9078,7 @@ function isMemoSame(cached, memo) {
9039
9078
  }
9040
9079
 
9041
9080
  // Core API ------------------------------------------------------------------
9042
- const version = "3.2.21";
9081
+ const version = "3.2.25";
9043
9082
  /**
9044
9083
  * SSR utils for \@vue/server-renderer. Only exposed in cjs builds.
9045
9084
  * @internal
@@ -9272,12 +9311,19 @@ prevChildren, parentComponent, parentSuspense, unmountChildren) {
9272
9311
  el[key] = value == null ? '' : value;
9273
9312
  return;
9274
9313
  }
9275
- if (key === 'value' && el.tagName !== 'PROGRESS') {
9314
+ if (key === 'value' &&
9315
+ el.tagName !== 'PROGRESS' &&
9316
+ // custom elements may use _value internally
9317
+ !el.tagName.includes('-')) {
9276
9318
  // store value as _value as well since
9277
9319
  // non-string values will be stringified.
9278
9320
  el._value = value;
9279
9321
  const newValue = value == null ? '' : value;
9280
- if (el.value !== newValue) {
9322
+ if (el.value !== newValue ||
9323
+ // #4956: always set for OPTION elements because its value falls back to
9324
+ // textContent if no value attribute is present. And setting .value for
9325
+ // OPTION has no side effect
9326
+ el.tagName === 'OPTION') {
9281
9327
  el.value = newValue;
9282
9328
  }
9283
9329
  if (value == null) {
@@ -9663,7 +9709,7 @@ class VueElement extends BaseClass {
9663
9709
  // HMR
9664
9710
  {
9665
9711
  instance.ceReload = newStyles => {
9666
- // alawys reset styles
9712
+ // always reset styles
9667
9713
  if (this._styles) {
9668
9714
  this._styles.forEach(s => this.shadowRoot.removeChild(s));
9669
9715
  this._styles.length = 0;
@@ -11287,12 +11333,12 @@ function findProp(node, name, dynamicOnly = false, allowEmpty = false) {
11287
11333
  }
11288
11334
  else if (p.name === 'bind' &&
11289
11335
  (p.exp || allowEmpty) &&
11290
- isBindKey(p.arg, name)) {
11336
+ isStaticArgOf(p.arg, name)) {
11291
11337
  return p;
11292
11338
  }
11293
11339
  }
11294
11340
  }
11295
- function isBindKey(arg, name) {
11341
+ function isStaticArgOf(arg, name) {
11296
11342
  return !!(arg && isStaticExp(arg) && arg.content === name);
11297
11343
  }
11298
11344
  function hasDynamicKeyVBind(node) {
@@ -11335,7 +11381,6 @@ function getUnnormalizedProps(props, callPath = []) {
11335
11381
  }
11336
11382
  function injectProp(node, prop, context) {
11337
11383
  let propsWithInjection;
11338
- const originalProps = node.type === 13 /* VNODE_CALL */ ? node.props : node.arguments[2];
11339
11384
  /**
11340
11385
  * 1. mergeProps(...)
11341
11386
  * 2. toHandlers(...)
@@ -11344,7 +11389,7 @@ function injectProp(node, prop, context) {
11344
11389
  *
11345
11390
  * we need to get the real props before normalization
11346
11391
  */
11347
- let props = originalProps;
11392
+ let props = node.type === 13 /* VNODE_CALL */ ? node.props : node.arguments[2];
11348
11393
  let callPath = [];
11349
11394
  let parentCall;
11350
11395
  if (props &&
@@ -11483,11 +11528,6 @@ const deprecationData = {
11483
11528
  `data source.`,
11484
11529
  link: `https://v3.vuejs.org/guide/migration/v-if-v-for.html`
11485
11530
  },
11486
- ["COMPILER_V_FOR_REF" /* COMPILER_V_FOR_REF */]: {
11487
- message: `Ref usage on v-for no longer creates array ref values in Vue 3. ` +
11488
- `Consider using function refs or refactor to avoid ref usage altogether.`,
11489
- link: `https://v3.vuejs.org/guide/migration/array-refs.html`
11490
- },
11491
11531
  ["COMPILER_NATIVE_TEMPLATE" /* COMPILER_NATIVE_TEMPLATE */]: {
11492
11532
  message: `<template> with no special directives will render as a native template ` +
11493
11533
  `element instead of its inner content in Vue 3.`
@@ -11960,7 +12000,7 @@ function isComponent(tag, props, context) {
11960
12000
  else if (
11961
12001
  // :is on plain element - only treat as component in compat mode
11962
12002
  p.name === 'bind' &&
11963
- isBindKey(p.arg, 'is') &&
12003
+ isStaticArgOf(p.arg, 'is') &&
11964
12004
  false &&
11965
12005
  checkCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context, p.loc)) {
11966
12006
  return true;
@@ -12309,15 +12349,6 @@ function isSingleElementRoot(root, child) {
12309
12349
  !isSlotOutlet(child));
12310
12350
  }
12311
12351
  function walk(node, context, doNotHoistNode = false) {
12312
- // Some transforms, e.g. transformAssetUrls from @vue/compiler-sfc, replaces
12313
- // static bindings with expressions. These expressions are guaranteed to be
12314
- // constant so they are still eligible for hoisting, but they are only
12315
- // available at runtime and therefore cannot be evaluated ahead of time.
12316
- // This is only a concern for pre-stringification (via transformHoist by
12317
- // @vue/compiler-dom), but doing it here allows us to perform only one full
12318
- // walk of the AST and allow `stringifyStatic` to stop walking as soon as its
12319
- // stringification threshold is met.
12320
- let canStringify = true;
12321
12352
  const { children } = node;
12322
12353
  const originalCount = children.length;
12323
12354
  let hoistedCount = 0;
@@ -12330,9 +12361,6 @@ function walk(node, context, doNotHoistNode = false) {
12330
12361
  ? 0 /* NOT_CONSTANT */
12331
12362
  : getConstantType(child, context);
12332
12363
  if (constantType > 0 /* NOT_CONSTANT */) {
12333
- if (constantType < 3 /* CAN_STRINGIFY */) {
12334
- canStringify = false;
12335
- }
12336
12364
  if (constantType >= 2 /* CAN_HOIST */) {
12337
12365
  child.codegenNode.patchFlag =
12338
12366
  -1 /* HOISTED */ + (` /* HOISTED */` );
@@ -12363,17 +12391,10 @@ function walk(node, context, doNotHoistNode = false) {
12363
12391
  }
12364
12392
  }
12365
12393
  }
12366
- else if (child.type === 12 /* TEXT_CALL */) {
12367
- const contentType = getConstantType(child.content, context);
12368
- if (contentType > 0) {
12369
- if (contentType < 3 /* CAN_STRINGIFY */) {
12370
- canStringify = false;
12371
- }
12372
- if (contentType >= 2 /* CAN_HOIST */) {
12373
- child.codegenNode = context.hoist(child.codegenNode);
12374
- hoistedCount++;
12375
- }
12376
- }
12394
+ else if (child.type === 12 /* TEXT_CALL */ &&
12395
+ getConstantType(child.content, context) >= 2 /* CAN_HOIST */) {
12396
+ child.codegenNode = context.hoist(child.codegenNode);
12397
+ hoistedCount++;
12377
12398
  }
12378
12399
  // walk further
12379
12400
  if (child.type === 1 /* ELEMENT */) {
@@ -12397,7 +12418,7 @@ function walk(node, context, doNotHoistNode = false) {
12397
12418
  }
12398
12419
  }
12399
12420
  }
12400
- if (canStringify && hoistedCount && context.transformHoist) {
12421
+ if (hoistedCount && context.transformHoist) {
12401
12422
  context.transformHoist(children, context, node);
12402
12423
  }
12403
12424
  // all children were hoisted - the entire children array is hoistable.
@@ -12426,6 +12447,11 @@ function getConstantType(node, context) {
12426
12447
  if (codegenNode.type !== 13 /* VNODE_CALL */) {
12427
12448
  return 0 /* NOT_CONSTANT */;
12428
12449
  }
12450
+ if (codegenNode.isBlock &&
12451
+ node.tag !== 'svg' &&
12452
+ node.tag !== 'foreignObject') {
12453
+ return 0 /* NOT_CONSTANT */;
12454
+ }
12429
12455
  const flag = getPatchFlag(codegenNode);
12430
12456
  if (!flag) {
12431
12457
  let returnType = 3 /* CAN_STRINGIFY */;
@@ -12562,7 +12588,7 @@ function getGeneratedPropsConstantType(node, context) {
12562
12588
  else if (value.type === 14 /* JS_CALL_EXPRESSION */) {
12563
12589
  // some helper calls can be hoisted,
12564
12590
  // such as the `normalizeProps` generated by the compiler for pre-normalize class,
12565
- // in this case we need to respect the ConstantType of the helper's argments
12591
+ // in this case we need to respect the ConstantType of the helper's arguments
12566
12592
  valueType = getConstantTypeOfHelperCall(value, context);
12567
12593
  }
12568
12594
  else {
@@ -14210,10 +14236,7 @@ const transformElement = (node, context) => {
14210
14236
  // updates inside get proper isSVG flag at runtime. (#639, #643)
14211
14237
  // This is technically web-specific, but splitting the logic out of core
14212
14238
  // leads to too much unnecessary complexity.
14213
- (tag === 'svg' ||
14214
- tag === 'foreignObject' ||
14215
- // #938: elements with dynamic keys should be forced into blocks
14216
- findProp(node, 'key', true)));
14239
+ (tag === 'svg' || tag === 'foreignObject'));
14217
14240
  // props
14218
14241
  if (props.length > 0) {
14219
14242
  const propsBuildResult = buildProps(node, context);
@@ -14225,6 +14248,9 @@ const transformElement = (node, context) => {
14225
14248
  directives && directives.length
14226
14249
  ? createArrayExpression(directives.map(dir => buildDirectiveArgs(dir, context)))
14227
14250
  : undefined;
14251
+ if (propsBuildResult.shouldUseBlock) {
14252
+ shouldUseBlock = true;
14253
+ }
14228
14254
  }
14229
14255
  // children
14230
14256
  if (node.children.length > 0) {
@@ -14353,11 +14379,13 @@ function resolveComponentType(node, context, ssr = false) {
14353
14379
  return toValidAssetId(tag, `component`);
14354
14380
  }
14355
14381
  function buildProps(node, context, props = node.props, ssr = false) {
14356
- const { tag, loc: elementLoc } = node;
14382
+ const { tag, loc: elementLoc, children } = node;
14357
14383
  const isComponent = node.tagType === 1 /* COMPONENT */;
14358
14384
  let properties = [];
14359
14385
  const mergeArgs = [];
14360
14386
  const runtimeDirectives = [];
14387
+ const hasChildren = children.length > 0;
14388
+ let shouldUseBlock = false;
14361
14389
  // patchFlag analysis
14362
14390
  let patchFlag = 0;
14363
14391
  let hasRef = false;
@@ -14420,9 +14448,12 @@ function buildProps(node, context, props = node.props, ssr = false) {
14420
14448
  const prop = props[i];
14421
14449
  if (prop.type === 6 /* ATTRIBUTE */) {
14422
14450
  const { loc, name, value } = prop;
14423
- let valueNode = createSimpleExpression(value ? value.content : '', true, value ? value.loc : loc);
14451
+ let isStatic = true;
14424
14452
  if (name === 'ref') {
14425
14453
  hasRef = true;
14454
+ if (context.scopes.vFor > 0) {
14455
+ properties.push(createObjectProperty(createSimpleExpression('ref_for', true), createSimpleExpression('true')));
14456
+ }
14426
14457
  }
14427
14458
  // skip is on <component>, or is="vue:xxx"
14428
14459
  if (name === 'is' &&
@@ -14431,7 +14462,7 @@ function buildProps(node, context, props = node.props, ssr = false) {
14431
14462
  (false ))) {
14432
14463
  continue;
14433
14464
  }
14434
- properties.push(createObjectProperty(createSimpleExpression(name, true, getInnerRange(loc, 0, name.length)), valueNode));
14465
+ properties.push(createObjectProperty(createSimpleExpression(name, true, getInnerRange(loc, 0, name.length)), createSimpleExpression(value ? value.content : '', isStatic, value ? value.loc : loc)));
14435
14466
  }
14436
14467
  else {
14437
14468
  // directives
@@ -14452,7 +14483,7 @@ function buildProps(node, context, props = node.props, ssr = false) {
14452
14483
  // skip v-is and :is on <component>
14453
14484
  if (name === 'is' ||
14454
14485
  (isVBind &&
14455
- isBindKey(arg, 'is') &&
14486
+ isStaticArgOf(arg, 'is') &&
14456
14487
  (isComponentTag(tag) ||
14457
14488
  (false )))) {
14458
14489
  continue;
@@ -14461,6 +14492,17 @@ function buildProps(node, context, props = node.props, ssr = false) {
14461
14492
  if (isVOn && ssr) {
14462
14493
  continue;
14463
14494
  }
14495
+ if (
14496
+ // #938: elements with dynamic keys should be forced into blocks
14497
+ (isVBind && isStaticArgOf(arg, 'key')) ||
14498
+ // inline before-update hooks need to force block so that it is invoked
14499
+ // before children
14500
+ (isVOn && hasChildren && isStaticArgOf(arg, 'vue:before-update'))) {
14501
+ shouldUseBlock = true;
14502
+ }
14503
+ if (isVBind && isStaticArgOf(arg, 'ref') && context.scopes.vFor > 0) {
14504
+ properties.push(createObjectProperty(createSimpleExpression('ref_for', true), createSimpleExpression('true')));
14505
+ }
14464
14506
  // special case for v-bind and v-on with no argument
14465
14507
  if (!arg && (isVBind || isVOn)) {
14466
14508
  hasDynamicKeys = true;
@@ -14505,6 +14547,11 @@ function buildProps(node, context, props = node.props, ssr = false) {
14505
14547
  else {
14506
14548
  // no built-in transform, this is a user custom directive.
14507
14549
  runtimeDirectives.push(prop);
14550
+ // custom dirs may use beforeUpdate so they need to force blocks
14551
+ // to ensure before-update gets called before children update
14552
+ if (hasChildren) {
14553
+ shouldUseBlock = true;
14554
+ }
14508
14555
  }
14509
14556
  }
14510
14557
  }
@@ -14543,7 +14590,8 @@ function buildProps(node, context, props = node.props, ssr = false) {
14543
14590
  patchFlag |= 32 /* HYDRATE_EVENTS */;
14544
14591
  }
14545
14592
  }
14546
- if ((patchFlag === 0 || patchFlag === 32 /* HYDRATE_EVENTS */) &&
14593
+ if (!shouldUseBlock &&
14594
+ (patchFlag === 0 || patchFlag === 32 /* HYDRATE_EVENTS */) &&
14547
14595
  (hasRef || hasVnodeHook || runtimeDirectives.length > 0)) {
14548
14596
  patchFlag |= 512 /* NEED_PATCH */;
14549
14597
  }
@@ -14610,7 +14658,8 @@ function buildProps(node, context, props = node.props, ssr = false) {
14610
14658
  props: propsExpression,
14611
14659
  directives: runtimeDirectives,
14612
14660
  patchFlag,
14613
- dynamicPropNames
14661
+ dynamicPropNames,
14662
+ shouldUseBlock
14614
14663
  };
14615
14664
  }
14616
14665
  // Dedupe props in an object literal.
@@ -14698,7 +14747,7 @@ function stringifyDynamicPropNames(props) {
14698
14747
  return propsNamesString + `]`;
14699
14748
  }
14700
14749
  function isComponentTag(tag) {
14701
- return tag[0].toLowerCase() + tag.slice(1) === 'component';
14750
+ return tag === 'component' || tag === 'Component';
14702
14751
  }
14703
14752
 
14704
14753
  const transformSlotOutlet = (node, context) => {
@@ -14746,7 +14795,7 @@ function processSlotOutlet(node, context) {
14746
14795
  }
14747
14796
  }
14748
14797
  else {
14749
- if (p.name === 'bind' && isBindKey(p.arg, 'name')) {
14798
+ if (p.name === 'bind' && isStaticArgOf(p.arg, 'name')) {
14750
14799
  if (p.exp)
14751
14800
  slotName = p.exp;
14752
14801
  }
@@ -14780,7 +14829,11 @@ const transformOn = (dir, node, context, augmentor) => {
14780
14829
  let eventName;
14781
14830
  if (arg.type === 4 /* SIMPLE_EXPRESSION */) {
14782
14831
  if (arg.isStatic) {
14783
- const rawName = arg.content;
14832
+ let rawName = arg.content;
14833
+ // TODO deprecate @vnodeXXX usage
14834
+ if (rawName.startsWith('vue:')) {
14835
+ rawName = `vnode-${rawName.slice(4)}`;
14836
+ }
14784
14837
  // for all event listeners, auto convert it to camelCase. See issue #2249
14785
14838
  eventName = createSimpleExpression(toHandlerKey(camelize(rawName)), true, arg.loc);
14786
14839
  }