@vue/runtime-core 3.1.0 → 3.1.4

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.
@@ -421,11 +421,12 @@ function emit(instance, event, ...rawArgs) {
421
421
  const onceHandler = props[handlerName + `Once`];
422
422
  if (onceHandler) {
423
423
  if (!instance.emitted) {
424
- (instance.emitted = {})[handlerName] = true;
424
+ instance.emitted = {};
425
425
  }
426
426
  else if (instance.emitted[handlerName]) {
427
427
  return;
428
428
  }
429
+ instance.emitted[handlerName] = true;
429
430
  callWithAsyncErrorHandling(onceHandler, instance, 6 /* COMPONENT_EVENT_HANDLER */, args);
430
431
  }
431
432
  }
@@ -839,6 +840,12 @@ const SuspenseImpl = {
839
840
  // Force-casted public typing for h and TSX props inference
840
841
  const Suspense = (SuspenseImpl
841
842
  );
843
+ function triggerEvent(vnode, name) {
844
+ const eventListener = vnode.props && vnode.props[name];
845
+ if (shared.isFunction(eventListener)) {
846
+ eventListener();
847
+ }
848
+ }
842
849
  function mountSuspense(vnode, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, rendererInternals) {
843
850
  const { p: patch, o: { createElement } } = rendererInternals;
844
851
  const hiddenContainer = createElement('div');
@@ -848,6 +855,9 @@ function mountSuspense(vnode, container, anchor, parentComponent, parentSuspense
848
855
  // now check if we have encountered any async deps
849
856
  if (suspense.deps > 0) {
850
857
  // has async
858
+ // invoke @fallback event
859
+ triggerEvent(vnode, 'onPending');
860
+ triggerEvent(vnode, 'onFallback');
851
861
  // mount the fallback tree
852
862
  patch(null, vnode.ssFallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context
853
863
  isSVG, slotScopeIds);
@@ -935,10 +945,7 @@ function patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, slotSc
935
945
  else {
936
946
  // root node toggled
937
947
  // invoke @pending event
938
- const onPending = n2.props && n2.props.onPending;
939
- if (shared.isFunction(onPending)) {
940
- onPending();
941
- }
948
+ triggerEvent(n2, 'onPending');
942
949
  // mount pending branch in off-dom container
943
950
  suspense.pendingBranch = newBranch;
944
951
  suspense.pendingId++;
@@ -1036,10 +1043,7 @@ function createSuspenseBoundary(vnode, parent, parentComponent, container, hidde
1036
1043
  }
1037
1044
  suspense.effects = [];
1038
1045
  // invoke @resolve event
1039
- const onResolve = vnode.props && vnode.props.onResolve;
1040
- if (shared.isFunction(onResolve)) {
1041
- onResolve();
1042
- }
1046
+ triggerEvent(vnode, 'onResolve');
1043
1047
  },
1044
1048
  fallback(fallbackVNode) {
1045
1049
  if (!suspense.pendingBranch) {
@@ -1047,10 +1051,7 @@ function createSuspenseBoundary(vnode, parent, parentComponent, container, hidde
1047
1051
  }
1048
1052
  const { vnode, activeBranch, parentComponent, container, isSVG } = suspense;
1049
1053
  // invoke @fallback event
1050
- const onFallback = vnode.props && vnode.props.onFallback;
1051
- if (shared.isFunction(onFallback)) {
1052
- onFallback();
1053
- }
1054
+ triggerEvent(vnode, 'onFallback');
1054
1055
  const anchor = next(activeBranch);
1055
1056
  const mountFallback = () => {
1056
1057
  if (!suspense.isInFallback) {
@@ -1065,11 +1066,11 @@ function createSuspenseBoundary(vnode, parent, parentComponent, container, hidde
1065
1066
  if (delayEnter) {
1066
1067
  activeBranch.transition.afterLeave = mountFallback;
1067
1068
  }
1069
+ suspense.isInFallback = true;
1068
1070
  // unmount current active branch
1069
1071
  unmount(activeBranch, parentComponent, null, // no suspense so unmount hooks fire now
1070
1072
  true // shouldRemove
1071
1073
  );
1072
- suspense.isInFallback = true;
1073
1074
  if (!delayEnter) {
1074
1075
  mountFallback();
1075
1076
  }
@@ -1251,7 +1252,7 @@ function inject(key, defaultValue, treatDefaultAsFactory = false) {
1251
1252
  }
1252
1253
  else if (arguments.length > 1) {
1253
1254
  return treatDefaultAsFactory && shared.isFunction(defaultValue)
1254
- ? defaultValue()
1255
+ ? defaultValue.call(instance.proxy)
1255
1256
  : defaultValue;
1256
1257
  }
1257
1258
  else ;
@@ -2353,13 +2354,16 @@ function applyOptions(instance) {
2353
2354
  registerLifecycleHook(onServerPrefetch, serverPrefetch);
2354
2355
  if (shared.isArray(expose)) {
2355
2356
  if (expose.length) {
2356
- const exposed = instance.exposed || (instance.exposed = reactivity.proxyRefs({}));
2357
+ const exposed = instance.exposed || (instance.exposed = {});
2357
2358
  expose.forEach(key => {
2358
- exposed[key] = reactivity.toRef(publicThis, key);
2359
+ Object.defineProperty(exposed, key, {
2360
+ get: () => publicThis[key],
2361
+ set: val => (publicThis[key] = val)
2362
+ });
2359
2363
  });
2360
2364
  }
2361
2365
  else if (!instance.exposed) {
2362
- instance.exposed = shared.EMPTY_OBJ;
2366
+ instance.exposed = {};
2363
2367
  }
2364
2368
  }
2365
2369
  // options that are handled when creating the instance but also need to be
@@ -2482,25 +2486,23 @@ const internalOptionMergeStrats = {
2482
2486
  methods: mergeObjectOptions,
2483
2487
  computed: mergeObjectOptions,
2484
2488
  // lifecycle
2485
- beforeCreate: mergeHook,
2486
- created: mergeHook,
2487
- beforeMount: mergeHook,
2488
- mounted: mergeHook,
2489
- beforeUpdate: mergeHook,
2490
- updated: mergeHook,
2491
- beforeDestroy: mergeHook,
2492
- destroyed: mergeHook,
2493
- activated: mergeHook,
2494
- deactivated: mergeHook,
2495
- errorCaptured: mergeHook,
2496
- serverPrefetch: mergeHook,
2489
+ beforeCreate: mergeAsArray,
2490
+ created: mergeAsArray,
2491
+ beforeMount: mergeAsArray,
2492
+ mounted: mergeAsArray,
2493
+ beforeUpdate: mergeAsArray,
2494
+ updated: mergeAsArray,
2495
+ beforeDestroy: mergeAsArray,
2496
+ destroyed: mergeAsArray,
2497
+ activated: mergeAsArray,
2498
+ deactivated: mergeAsArray,
2499
+ errorCaptured: mergeAsArray,
2500
+ serverPrefetch: mergeAsArray,
2497
2501
  // assets
2498
2502
  components: mergeObjectOptions,
2499
2503
  directives: mergeObjectOptions,
2500
- // watch has special merge behavior in v2, but isn't actually needed in v3.
2501
- // since we are only exposing these for compat and nobody should be relying
2502
- // on the watch-specific behavior, just expose the object merge strat.
2503
- watch: mergeObjectOptions,
2504
+ // watch
2505
+ watch: mergeWatchOptions,
2504
2506
  // provide / inject
2505
2507
  provide: mergeDataFn,
2506
2508
  inject: mergeInject
@@ -2529,11 +2531,22 @@ function normalizeInject(raw) {
2529
2531
  }
2530
2532
  return raw;
2531
2533
  }
2532
- function mergeHook(to, from) {
2534
+ function mergeAsArray(to, from) {
2533
2535
  return to ? [...new Set([].concat(to, from))] : from;
2534
2536
  }
2535
2537
  function mergeObjectOptions(to, from) {
2536
2538
  return to ? shared.extend(shared.extend(Object.create(null), to), from) : from;
2539
+ }
2540
+ function mergeWatchOptions(to, from) {
2541
+ if (!to)
2542
+ return from;
2543
+ if (!from)
2544
+ return to;
2545
+ const merged = shared.extend(Object.create(null), to);
2546
+ for (const key in from) {
2547
+ merged[key] = mergeAsArray(to[key], from[key]);
2548
+ }
2549
+ return merged;
2537
2550
  }
2538
2551
 
2539
2552
  function initProps(instance, rawProps, isStateful, // result of bitwise flag comparison
@@ -3018,6 +3031,7 @@ function createAppAPI(render, hydrate) {
3018
3031
  _props: rootProps,
3019
3032
  _container: null,
3020
3033
  _context: context,
3034
+ _instance: null,
3021
3035
  version,
3022
3036
  get config() {
3023
3037
  return context.config;
@@ -3105,6 +3119,11 @@ const isComment = (node) => node.nodeType === 8 /* COMMENT */;
3105
3119
  function createHydrationFunctions(rendererInternals) {
3106
3120
  const { mt: mountComponent, p: patch, o: { patchProp, nextSibling, parentNode, remove, insert, createComment } } = rendererInternals;
3107
3121
  const hydrate = (vnode, container) => {
3122
+ if (!container.hasChildNodes()) {
3123
+ patch(null, vnode, container);
3124
+ flushPostFlushCbs();
3125
+ return;
3126
+ }
3108
3127
  hasMismatch = false;
3109
3128
  hydrateNode(container.firstChild, vnode, null, null, null);
3110
3129
  flushPostFlushCbs();
@@ -3234,19 +3253,24 @@ function createHydrationFunctions(rendererInternals) {
3234
3253
  };
3235
3254
  const hydrateElement = (el, vnode, parentComponent, parentSuspense, slotScopeIds, optimized) => {
3236
3255
  optimized = optimized || !!vnode.dynamicChildren;
3237
- const { props, patchFlag, shapeFlag, dirs } = vnode;
3256
+ const { type, props, patchFlag, shapeFlag, dirs } = vnode;
3257
+ // #4006 for form elements with non-string v-model value bindings
3258
+ // e.g. <option :value="obj">, <input type="checkbox" :true-value="1">
3259
+ const forcePatchValue = (type === 'input' && dirs) || type === 'option';
3238
3260
  // skip props & children if this is hoisted static nodes
3239
- if (patchFlag !== -1 /* HOISTED */) {
3261
+ if (forcePatchValue || patchFlag !== -1 /* HOISTED */) {
3240
3262
  if (dirs) {
3241
3263
  invokeDirectiveHook(vnode, null, parentComponent, 'created');
3242
3264
  }
3243
3265
  // props
3244
3266
  if (props) {
3245
- if (!optimized ||
3267
+ if (forcePatchValue ||
3268
+ !optimized ||
3246
3269
  (patchFlag & 16 /* FULL_PROPS */ ||
3247
3270
  patchFlag & 32 /* HYDRATE_EVENTS */)) {
3248
3271
  for (const key in props) {
3249
- if (!shared.isReservedProp(key) && shared.isOn(key)) {
3272
+ if ((forcePatchValue && key.endsWith('value')) ||
3273
+ (shared.isOn(key) && !shared.isReservedProp(key))) {
3250
3274
  patchProp(el, key, null, props[key]);
3251
3275
  }
3252
3276
  }
@@ -3398,7 +3422,7 @@ const setRef = (rawRef, oldRawRef, parentSuspense, vnode, isUnmount = false) =>
3398
3422
  return;
3399
3423
  }
3400
3424
  const refValue = vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */
3401
- ? vnode.component.exposed || vnode.component.proxy
3425
+ ? getExposeProxy(vnode.component) || vnode.component.proxy
3402
3426
  : vnode.el;
3403
3427
  const value = isUnmount ? null : refValue;
3404
3428
  const { i: owner, r: ref } = rawRef;
@@ -3551,7 +3575,19 @@ function baseCreateRenderer(options, createHydrationFns) {
3551
3575
  }
3552
3576
  };
3553
3577
  const mountStaticNode = (n2, container, anchor, isSVG) => {
3554
- [n2.el, n2.anchor] = hostInsertStaticContent(n2.children, container, anchor, isSVG);
3578
+ // static nodes are only present when used with compiler-dom/runtime-dom
3579
+ // which guarantees presence of hostInsertStaticContent.
3580
+ const nodes = hostInsertStaticContent(n2.children, container, anchor, isSVG,
3581
+ // pass cached nodes if the static node is being mounted multiple times
3582
+ // so that runtime-dom can simply cloneNode() instead of inserting new
3583
+ // HTML
3584
+ n2.staticCache);
3585
+ // first mount - this is the orignal hoisted vnode. cache nodes.
3586
+ if (!n2.el) {
3587
+ n2.staticCache = nodes;
3588
+ }
3589
+ n2.el = nodes[0];
3590
+ n2.anchor = nodes[nodes.length - 1];
3555
3591
  };
3556
3592
  const moveStaticNode = ({ el, anchor }, container, nextSibling) => {
3557
3593
  let next;
@@ -4996,7 +5032,6 @@ function _createVNode(type, props = null, children = null, patchFlag = 0, dynami
4996
5032
  anchor: null,
4997
5033
  target: null,
4998
5034
  targetAnchor: null,
4999
- staticCount: 0,
5000
5035
  shapeFlag,
5001
5036
  patchFlag,
5002
5037
  dynamicProps,
@@ -5052,6 +5087,7 @@ function cloneVNode(vnode, extraProps, mergeRef = false) {
5052
5087
  target: vnode.target,
5053
5088
  targetAnchor: vnode.targetAnchor,
5054
5089
  staticCount: vnode.staticCount,
5090
+ staticCache: vnode.staticCache,
5055
5091
  shapeFlag: vnode.shapeFlag,
5056
5092
  // if the vnode is cloned with extra props, we can no longer assume its
5057
5093
  // existing patch flag to be reliable and need to add the FULL_PROPS flag.
@@ -5342,7 +5378,7 @@ const getPublicInstance = (i) => {
5342
5378
  if (!i)
5343
5379
  return null;
5344
5380
  if (isStatefulComponent(i))
5345
- return i.exposed ? i.exposed : i.proxy;
5381
+ return getExposeProxy(i) || i.proxy;
5346
5382
  return getPublicInstance(i.parent);
5347
5383
  };
5348
5384
  const publicPropertiesMap = shared.extend(Object.create(null), {
@@ -5364,10 +5400,6 @@ const publicPropertiesMap = shared.extend(Object.create(null), {
5364
5400
  const PublicInstanceProxyHandlers = {
5365
5401
  get({ _: instance }, key) {
5366
5402
  const { ctx, setupState, data, props, accessCache, type, appContext } = instance;
5367
- // let @vue/reactivity know it should never observe Vue public instances.
5368
- if (key === "__v_skip" /* SKIP */) {
5369
- return true;
5370
- }
5371
5403
  // data / props / ctx
5372
5404
  // This getter gets called for every property access on the render context
5373
5405
  // during render and is a major hotspot. The most expensive part of this
@@ -5509,6 +5541,7 @@ function createComponentInstance(vnode, parent, suspense) {
5509
5541
  render: null,
5510
5542
  proxy: null,
5511
5543
  exposed: null,
5544
+ exposeProxy: null,
5512
5545
  withProxy: null,
5513
5546
  effects: null,
5514
5547
  provides: parent ? parent.provides : Object.create(appContext.provides),
@@ -5595,7 +5628,7 @@ function setupStatefulComponent(instance, isSSR) {
5595
5628
  instance.accessCache = Object.create(null);
5596
5629
  // 1. create public instance / render proxy
5597
5630
  // also mark it raw so it's never observed
5598
- instance.proxy = new Proxy(instance.ctx, PublicInstanceProxyHandlers);
5631
+ instance.proxy = reactivity.markRaw(new Proxy(instance.ctx, PublicInstanceProxyHandlers));
5599
5632
  // 2. call setup()
5600
5633
  const { setup } = Component;
5601
5634
  if (setup) {
@@ -5607,6 +5640,10 @@ function setupStatefulComponent(instance, isSSR) {
5607
5640
  reactivity.resetTracking();
5608
5641
  currentInstance = null;
5609
5642
  if (shared.isPromise(setupResult)) {
5643
+ const unsetInstance = () => {
5644
+ currentInstance = null;
5645
+ };
5646
+ setupResult.then(unsetInstance, unsetInstance);
5610
5647
  if (isSSR) {
5611
5648
  // return the promise so server-renderer can wait on it
5612
5649
  return setupResult
@@ -5705,7 +5742,7 @@ function finishComponentSetup(instance, isSSR, skipOptions) {
5705
5742
  }
5706
5743
  function createSetupContext(instance) {
5707
5744
  const expose = exposed => {
5708
- instance.exposed = reactivity.proxyRefs(exposed);
5745
+ instance.exposed = exposed || {};
5709
5746
  };
5710
5747
  {
5711
5748
  return {
@@ -5716,6 +5753,21 @@ function createSetupContext(instance) {
5716
5753
  };
5717
5754
  }
5718
5755
  }
5756
+ function getExposeProxy(instance) {
5757
+ if (instance.exposed) {
5758
+ return (instance.exposeProxy ||
5759
+ (instance.exposeProxy = new Proxy(reactivity.proxyRefs(reactivity.markRaw(instance.exposed)), {
5760
+ get(target, key) {
5761
+ if (key in target) {
5762
+ return target[key];
5763
+ }
5764
+ else if (key in publicPropertiesMap) {
5765
+ return publicPropertiesMap[key](instance);
5766
+ }
5767
+ }
5768
+ })));
5769
+ }
5770
+ }
5719
5771
  // record effects created during a component's setup() so that they can be
5720
5772
  // stopped when the component unmounts
5721
5773
  function recordInstanceBoundEffect(effect, instance = currentInstance) {
@@ -5764,17 +5816,111 @@ function computed(getterOrOptions) {
5764
5816
  return c;
5765
5817
  }
5766
5818
 
5819
+ const isFunction = (val) => typeof val === 'function';
5820
+ const isObject = (val) => val !== null && typeof val === 'object';
5821
+ const isPromise = (val) => {
5822
+ return isObject(val) && isFunction(val.then) && isFunction(val.catch);
5823
+ };
5824
+
5767
5825
  // implementation
5768
5826
  function defineProps() {
5769
5827
  return null;
5770
5828
  }
5771
5829
  // implementation
5772
- function defineEmit() {
5830
+ function defineEmits() {
5773
5831
  return null;
5774
5832
  }
5833
+ /**
5834
+ * @deprecated use `defineEmits` instead.
5835
+ */
5836
+ const defineEmit = defineEmits;
5837
+ /**
5838
+ * Vue `<script setup>` compiler macro for declaring a component's exposed
5839
+ * instance properties when it is accessed by a parent component via template
5840
+ * refs.
5841
+ *
5842
+ * `<script setup>` components are closed by default - i.e. varaibles inside
5843
+ * the `<script setup>` scope is not exposed to parent unless explicitly exposed
5844
+ * via `defineExpose`.
5845
+ *
5846
+ * This is only usable inside `<script setup>`, is compiled away in the
5847
+ * output and should **not** be actually called at runtime.
5848
+ */
5849
+ function defineExpose(exposed) {
5850
+ }
5851
+ /**
5852
+ * Vue `<script setup>` compiler macro for providing props default values when
5853
+ * using type-based `defineProps` decalration.
5854
+ *
5855
+ * Example usage:
5856
+ * ```ts
5857
+ * withDefaults(defineProps<{
5858
+ * size?: number
5859
+ * labels?: string[]
5860
+ * }>(), {
5861
+ * size: 3,
5862
+ * labels: () => ['default label']
5863
+ * })
5864
+ * ```
5865
+ *
5866
+ * This is only usable inside `<script setup>`, is compiled away in the output
5867
+ * and should **not** be actually called at runtime.
5868
+ */
5869
+ function withDefaults(props, defaults) {
5870
+ return null;
5871
+ }
5872
+ /**
5873
+ * @deprecated use `useSlots` and `useAttrs` instead.
5874
+ */
5775
5875
  function useContext() {
5876
+ return getContext();
5877
+ }
5878
+ function useSlots() {
5879
+ return getContext().slots;
5880
+ }
5881
+ function useAttrs() {
5882
+ return getContext().attrs;
5883
+ }
5884
+ function getContext() {
5776
5885
  const i = getCurrentInstance();
5777
5886
  return i.setupContext || (i.setupContext = createSetupContext(i));
5887
+ }
5888
+ /**
5889
+ * Runtime helper for merging default declarations. Imported by compiled code
5890
+ * only.
5891
+ * @internal
5892
+ */
5893
+ function mergeDefaults(
5894
+ // the base props is compiler-generated and guaranteed to be in this shape.
5895
+ props, defaults) {
5896
+ for (const key in defaults) {
5897
+ const val = props[key];
5898
+ if (val) {
5899
+ val.default = defaults[key];
5900
+ }
5901
+ else if (val === null) {
5902
+ props[key] = { default: defaults[key] };
5903
+ }
5904
+ else ;
5905
+ }
5906
+ return props;
5907
+ }
5908
+ /**
5909
+ * Runtime helper for storing and resuming current instance context in
5910
+ * async setup().
5911
+ */
5912
+ function withAsyncContext(awaitable) {
5913
+ const ctx = getCurrentInstance();
5914
+ setCurrentInstance(null); // unset after storing instance
5915
+ return isPromise(awaitable)
5916
+ ? awaitable.then(res => {
5917
+ setCurrentInstance(ctx);
5918
+ return res;
5919
+ }, err => {
5920
+ setCurrentInstance(ctx);
5921
+ throw err;
5922
+ })
5923
+ : awaitable;
5778
5924
  }
5779
5925
 
5780
5926
  // Actual implementation
@@ -5825,7 +5971,7 @@ function initCustomFormatter() {
5825
5971
  }
5826
5972
 
5827
5973
  // Core API ------------------------------------------------------------------
5828
- const version = "3.1.0";
5974
+ const version = "3.1.4";
5829
5975
  const _ssrUtils = {
5830
5976
  createComponentInstance,
5831
5977
  setupComponent,
@@ -5894,6 +6040,8 @@ exports.createVNode = createVNode;
5894
6040
  exports.defineAsyncComponent = defineAsyncComponent;
5895
6041
  exports.defineComponent = defineComponent;
5896
6042
  exports.defineEmit = defineEmit;
6043
+ exports.defineEmits = defineEmits;
6044
+ exports.defineExpose = defineExpose;
5897
6045
  exports.defineProps = defineProps;
5898
6046
  exports.getCurrentInstance = getCurrentInstance;
5899
6047
  exports.getTransitionRawChildren = getTransitionRawChildren;
@@ -5903,6 +6051,7 @@ exports.initCustomFormatter = initCustomFormatter;
5903
6051
  exports.inject = inject;
5904
6052
  exports.isRuntimeOnly = isRuntimeOnly;
5905
6053
  exports.isVNode = isVNode;
6054
+ exports.mergeDefaults = mergeDefaults;
5906
6055
  exports.mergeProps = mergeProps;
5907
6056
  exports.nextTick = nextTick;
5908
6057
  exports.onActivated = onActivated;
@@ -5937,13 +6086,17 @@ exports.ssrContextKey = ssrContextKey;
5937
6086
  exports.ssrUtils = ssrUtils;
5938
6087
  exports.toHandlers = toHandlers;
5939
6088
  exports.transformVNodeArgs = transformVNodeArgs;
6089
+ exports.useAttrs = useAttrs;
5940
6090
  exports.useContext = useContext;
5941
6091
  exports.useSSRContext = useSSRContext;
6092
+ exports.useSlots = useSlots;
5942
6093
  exports.useTransitionState = useTransitionState;
5943
6094
  exports.version = version;
5944
6095
  exports.warn = warn;
5945
6096
  exports.watch = watch;
5946
6097
  exports.watchEffect = watchEffect;
6098
+ exports.withAsyncContext = withAsyncContext;
5947
6099
  exports.withCtx = withCtx;
6100
+ exports.withDefaults = withDefaults;
5948
6101
  exports.withDirectives = withDirectives;
5949
6102
  exports.withScopeId = withScopeId;