diff --git a/packages/uni-h5-vue/dist/vue.runtime.esm.js b/packages/uni-h5-vue/dist/vue.runtime.esm.js
index e9f493eec75300d11e7a2b48f756bc63ac81e003..f7842e3e4436e971aec039919d3efa4f878faa6d 100644
--- a/packages/uni-h5-vue/dist/vue.runtime.esm.js
+++ b/packages/uni-h5-vue/dist/vue.runtime.esm.js
@@ -1,5 +1,5 @@
-import { isSymbol, extend, isMap, isObject, toRawType, def, isArray, isString, isFunction, isPromise, capitalize, EMPTY_ARR, normalizeClass, normalizeStyle, isOn, remove, EMPTY_OBJ, NOOP, isGloballyWhitelisted, toNumber, invokeArrayFns, looseIndexOf, isSet, looseHas, looseEqual, hyphenate, isHTMLTag, isSVGTag, isIntegerKey, hasOwn, hasChanged, camelize, getGlobalThis, isReservedProp, NO, isModelListener, makeMap, isSpecialBooleanAttr } from '@vue/shared';
-export { camelize, capitalize, toDisplayString } from '@vue/shared';
+import { isSymbol, extend, isMap, isObject, toRawType, def, isArray, isString, isFunction, isPromise, toHandlerKey, remove, EMPTY_OBJ, camelize, capitalize, EMPTY_ARR, normalizeClass, normalizeStyle, isOn, NOOP, isGloballyWhitelisted, toNumber, invokeArrayFns, looseIndexOf, isSet, looseEqual, hyphenate, isHTMLTag, isSVGTag, isIntegerKey, hasOwn, hasChanged, getGlobalThis, isReservedProp, NO, isModelListener, makeMap, isSpecialBooleanAttr } from '@vue/shared';
+export { camelize, capitalize, toDisplayString, toHandlerKey } from '@vue/shared';
const targetMap = new WeakMap();
const effectStack = [];
@@ -50,6 +50,7 @@ function createReactiveEffect(fn, options) {
}
};
effect.id = uid++;
+ effect.allowRecurse = !!options.allowRecurse;
effect._isEffect = true;
effect.active = true;
effect.raw = fn;
@@ -115,7 +116,7 @@ function trigger(target, type, key, newValue, oldValue, oldTarget) {
const add = (effectsToAdd) => {
if (effectsToAdd) {
effectsToAdd.forEach(effect => {
- if (effect !== activeEffect || effect.options.allowRecurse) {
+ if (effect !== activeEffect || effect.allowRecurse) {
effects.add(effect);
}
});
@@ -220,7 +221,7 @@ const arrayInstrumentations = {};
arrayInstrumentations[key] = function (...args) {
pauseTracking();
const res = method.apply(this, args);
- enableTracking();
+ resetTracking();
return res;
};
});
@@ -241,8 +242,7 @@ function createGetter(isReadonly = false, shallow = false) {
return Reflect.get(arrayInstrumentations, key, receiver);
}
const res = Reflect.get(target, key, receiver);
- const keyIsSymbol = isSymbol(key);
- if (keyIsSymbol
+ if (isSymbol(key)
? builtInSymbols.has(key)
: key === `__proto__` || key === `__v_isRef`) {
return res;
@@ -312,7 +312,7 @@ function has(target, key) {
return result;
}
function ownKeys(target) {
- track(target, "iterate" /* ITERATE */, ITERATE_KEY);
+ track(target, "iterate" /* ITERATE */, isArray(target) ? 'length' : ITERATE_KEY);
return Reflect.ownKeys(target);
}
const mutableHandlers = {
@@ -595,7 +595,7 @@ function checkIdentityKeys(target, has, key) {
if (rawKey !== key && has.call(target, rawKey)) {
const type = toRawType(target);
console.warn(`Reactive ${type} contains both the raw and reactive ` +
- `versions of the same object${type === `Map` ? `as keys` : ``}, ` +
+ `versions of the same object${type === `Map` ? ` as keys` : ``}, ` +
`which can lead to inconsistencies. ` +
`Avoid differentiating between the raw and reactive versions ` +
`of an object and only use the reactive version if possible.`);
@@ -730,7 +730,7 @@ function createRef(rawValue, shallow = false) {
return new RefImpl(rawValue, shallow);
}
function triggerRef(ref) {
- trigger(ref, "set" /* SET */, 'value', (process.env.NODE_ENV !== 'production') ? ref.value : void 0);
+ trigger(toRaw(ref), "set" /* SET */, 'value', (process.env.NODE_ENV !== 'production') ? ref.value : void 0);
}
function unref(ref) {
return isRef(ref) ? ref.value : ref;
@@ -1028,7 +1028,7 @@ function handleError(err, instance, type, throwInDev = true) {
const errorCapturedHooks = cur.ec;
if (errorCapturedHooks) {
for (let i = 0; i < errorCapturedHooks.length; i++) {
- if (errorCapturedHooks[i](err, exposedInstance, errorInfo)) {
+ if (errorCapturedHooks[i](err, exposedInstance, errorInfo) === false) {
return;
}
}
@@ -1084,7 +1084,7 @@ let currentPreFlushParentJob = null;
const RECURSION_LIMIT = 100;
function nextTick(fn) {
const p = currentFlushPromise || resolvedPromise;
- return fn ? p.then(fn) : p;
+ return fn ? p.then(this ? fn.bind(this) : fn) : p;
}
function queueJob(job) {
// the dedupe search uses the startIndex argument of Array.includes()
@@ -1247,7 +1247,7 @@ const hmrDirtyComponents = new Set();
// it easier to be used in toolings like vue-loader
// Note: for a component to be eligible for HMR it also needs the __hmrId option
// to be set so that its instances can be registered / removed.
-if ((process.env.NODE_ENV !== 'production')) {
+if ((process.env.NODE_ENV !== 'production') && (true )) {
const globalObject = typeof global !== 'undefined'
? global
: typeof self !== 'undefined'
@@ -1391,21 +1391,21 @@ function devtoolsComponentEmit(component, event, params) {
devtools.emit("component:emit" /* COMPONENT_EMIT */, component.appContext.app, component, event, params);
}
-function emit(instance, event, ...args) {
+function emit(instance, event, ...rawArgs) {
const props = instance.vnode.props || EMPTY_OBJ;
if ((process.env.NODE_ENV !== 'production')) {
const { emitsOptions, propsOptions: [propsOptions] } = instance;
if (emitsOptions) {
if (!(event in emitsOptions)) {
- if (!propsOptions || !(`on` + capitalize(event) in propsOptions)) {
+ if (!propsOptions || !(toHandlerKey(event) in propsOptions)) {
warn(`Component emitted event "${event}" but it is neither declared in ` +
- `the emits option nor as an "on${capitalize(event)}" prop.`);
+ `the emits option nor as an "${toHandlerKey(event)}" prop.`);
}
}
else {
const validator = emitsOptions[event];
if (isFunction(validator)) {
- const isValid = validator(...args);
+ const isValid = validator(...rawArgs);
if (!isValid) {
warn(`Invalid event arguments: event validation failed for event "${event}".`);
}
@@ -1413,36 +1413,59 @@ function emit(instance, event, ...args) {
}
}
}
+ let args = rawArgs;
+ const isModelListener = event.startsWith('update:');
+ // for v-model update:xxx events, apply modifiers on args
+ const modelArg = isModelListener && event.slice(7);
+ if (modelArg && modelArg in props) {
+ const modifiersKey = `${modelArg === 'modelValue' ? 'model' : modelArg}Modifiers`;
+ const { number, trim } = props[modifiersKey] || EMPTY_OBJ;
+ if (trim) {
+ args = rawArgs.map(a => a.trim());
+ }
+ else if (number) {
+ args = rawArgs.map(toNumber);
+ }
+ }
if ((process.env.NODE_ENV !== 'production') || __VUE_PROD_DEVTOOLS__) {
devtoolsComponentEmit(instance, event, args);
}
- let handlerName = `on${capitalize(event)}`;
+ if ((process.env.NODE_ENV !== 'production')) {
+ const lowerCaseEvent = event.toLowerCase();
+ if (lowerCaseEvent !== event && props[toHandlerKey(lowerCaseEvent)]) {
+ warn(`Event "${lowerCaseEvent}" is emitted in component ` +
+ `${formatComponentName(instance, instance.type)} but the handler is registered for "${event}". ` +
+ `Note that HTML attributes are case-insensitive and you cannot use ` +
+ `v-on to listen to camelCase events when using in-DOM templates. ` +
+ `You should probably use "${hyphenate(event)}" instead of "${event}".`);
+ }
+ }
+ // convert handler name to camelCase. See issue #2249
+ let handlerName = toHandlerKey(camelize(event));
let handler = props[handlerName];
// for v-model update:xxx events, also trigger kebab-case equivalent
// for props passed via kebab-case
- if (!handler && event.startsWith('update:')) {
- handlerName = `on${capitalize(hyphenate(event))}`;
+ if (!handler && isModelListener) {
+ handlerName = toHandlerKey(hyphenate(event));
handler = props[handlerName];
}
- if (!handler) {
- handler = props[handlerName + `Once`];
+ if (handler) {
+ callWithAsyncErrorHandling(handler, instance, 6 /* COMPONENT_EVENT_HANDLER */, args);
+ }
+ const onceHandler = props[handlerName + `Once`];
+ if (onceHandler) {
if (!instance.emitted) {
(instance.emitted = {})[handlerName] = true;
}
else if (instance.emitted[handlerName]) {
return;
}
- }
- if (handler) {
- callWithAsyncErrorHandling(handler, instance, 6 /* COMPONENT_EVENT_HANDLER */, args);
+ callWithAsyncErrorHandling(onceHandler, instance, 6 /* COMPONENT_EVENT_HANDLER */, args);
}
}
function normalizeEmitsOptions(comp, appContext, asMixin = false) {
- const appId = appContext.app ? appContext.app._uid : -1;
- const cache = comp.__emits || (comp.__emits = {});
- const cached = cache[appId];
- if (cached !== undefined) {
- return cached;
+ if (!appContext.deopt && comp.__emits !== undefined) {
+ return comp.__emits;
}
const raw = comp.emits;
let normalized = {};
@@ -1464,7 +1487,7 @@ function normalizeEmitsOptions(comp, appContext, asMixin = false) {
}
}
if (!raw && !hasExtends) {
- return (cache[appId] = null);
+ return (comp.__emits = null);
}
if (isArray(raw)) {
raw.forEach(key => (normalized[key] = null));
@@ -1472,7 +1495,7 @@ function normalizeEmitsOptions(comp, appContext, asMixin = false) {
else {
extend(normalized, raw);
}
- return (cache[appId] = normalized);
+ return (comp.__emits = normalized);
}
// Check if an incoming prop key is a declared emit event listener.
// e.g. With `emits: { click: null }`, props named `onClick` and `onclick` are
@@ -1603,7 +1626,7 @@ function renderComponentRoot(instance) {
warn(`Runtime directive used on component with non-element root node. ` +
`The directives will not function as intended.`);
}
- root.dirs = vnode.dirs;
+ root.dirs = root.dirs ? root.dirs.concat(vnode.dirs) : vnode.dirs;
}
// inherit transition data
if (vnode.transition) {
@@ -1647,11 +1670,13 @@ const getChildRoot = (vnode) => {
const dynamicIndex = dynamicChildren ? dynamicChildren.indexOf(childRoot) : -1;
const setRoot = (updatedRoot) => {
rawChildren[index] = updatedRoot;
- if (dynamicIndex > -1) {
- dynamicChildren[dynamicIndex] = updatedRoot;
- }
- else if (dynamicChildren && updatedRoot.patchFlag > 0) {
- dynamicChildren.push(updatedRoot);
+ if (dynamicChildren) {
+ if (dynamicIndex > -1) {
+ dynamicChildren[dynamicIndex] = updatedRoot;
+ }
+ else if (updatedRoot.patchFlag > 0) {
+ vnode.dynamicChildren = [...dynamicChildren, updatedRoot];
+ }
}
};
return [normalizeVNode(childRoot), setRoot];
@@ -1789,7 +1814,7 @@ const SuspenseImpl = {
mountSuspense(n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized, rendererInternals);
}
else {
- patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, optimized, rendererInternals);
+ patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, rendererInternals);
}
},
hydrate: hydrateSuspense,
@@ -1803,13 +1828,13 @@ function mountSuspense(vnode, container, anchor, parentComponent, parentSuspense
const hiddenContainer = createElement('div');
const suspense = (vnode.suspense = createSuspenseBoundary(vnode, parentSuspense, parentComponent, container, hiddenContainer, anchor, isSVG, optimized, rendererInternals));
// start mounting the content subtree in an off-dom container
- patch(null, (suspense.pendingBranch = vnode.ssContent), hiddenContainer, null, parentComponent, suspense, isSVG, optimized);
+ patch(null, (suspense.pendingBranch = vnode.ssContent), hiddenContainer, null, parentComponent, suspense, isSVG);
// now check if we have encountered any async deps
if (suspense.deps > 0) {
// has async
// mount the fallback tree
patch(null, vnode.ssFallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context
- isSVG, optimized);
+ isSVG);
setActiveBranch(suspense, vnode.ssFallback);
}
else {
@@ -1817,7 +1842,7 @@ function mountSuspense(vnode, container, anchor, parentComponent, parentSuspense
suspense.resolve();
}
}
-function patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, optimized, { p: patch, um: unmount, o: { createElement } }) {
+function patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, { p: patch, um: unmount, o: { createElement } }) {
const suspense = (n2.suspense = n1.suspense);
suspense.vnode = n2;
n2.el = n1.el;
@@ -1828,13 +1853,13 @@ function patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, optimi
suspense.pendingBranch = newBranch;
if (isSameVNodeType(newBranch, pendingBranch)) {
// same root type but content may have changed.
- patch(pendingBranch, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, optimized);
+ patch(pendingBranch, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG);
if (suspense.deps <= 0) {
suspense.resolve();
}
else if (isInFallback) {
patch(activeBranch, newFallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context
- isSVG, optimized);
+ isSVG);
setActiveBranch(suspense, newFallback);
}
}
@@ -1860,25 +1885,25 @@ function patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, optimi
suspense.hiddenContainer = createElement('div');
if (isInFallback) {
// already in fallback state
- patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, optimized);
+ patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG);
if (suspense.deps <= 0) {
suspense.resolve();
}
else {
patch(activeBranch, newFallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context
- isSVG, optimized);
+ isSVG);
setActiveBranch(suspense, newFallback);
}
}
else if (activeBranch && isSameVNodeType(newBranch, activeBranch)) {
// toggled "back" to current active branch
- patch(activeBranch, newBranch, container, anchor, parentComponent, suspense, isSVG, optimized);
+ patch(activeBranch, newBranch, container, anchor, parentComponent, suspense, isSVG);
// force resolve
suspense.resolve(true);
}
else {
// switched to a 3rd branch
- patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, optimized);
+ patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG);
if (suspense.deps <= 0) {
suspense.resolve();
}
@@ -1888,7 +1913,7 @@ function patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, optimi
else {
if (activeBranch && isSameVNodeType(newBranch, activeBranch)) {
// root did not change, just normal patch
- patch(activeBranch, newBranch, container, anchor, parentComponent, suspense, isSVG, optimized);
+ patch(activeBranch, newBranch, container, anchor, parentComponent, suspense, isSVG);
setActiveBranch(suspense, newBranch);
}
else {
@@ -1901,7 +1926,7 @@ function patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, optimi
// mount pending branch in off-dom container
suspense.pendingBranch = newBranch;
suspense.pendingId++;
- patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, optimized);
+ patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG);
if (suspense.deps <= 0) {
// incoming branch has no async deps, resolve now.
suspense.resolve();
@@ -1937,7 +1962,6 @@ function createSuspenseBoundary(vnode, parent, parentComponent, container, hidde
parent,
parentComponent,
isSVG,
- optimized,
container,
hiddenContainer,
anchor,
@@ -2020,7 +2044,7 @@ function createSuspenseBoundary(vnode, parent, parentComponent, container, hidde
if (!suspense.pendingBranch) {
return;
}
- const { vnode, activeBranch, parentComponent, container, isSVG, optimized } = suspense;
+ const { vnode, activeBranch, parentComponent, container, isSVG } = suspense;
// invoke @fallback event
const onFallback = vnode.props && vnode.props.onFallback;
if (isFunction(onFallback)) {
@@ -2033,7 +2057,7 @@ function createSuspenseBoundary(vnode, parent, parentComponent, container, hidde
}
// mount the fallback tree
patch(null, fallbackVNode, container, anchor, parentComponent, null, // fallback tree will not have suspense context
- isSVG, optimized);
+ isSVG);
setActiveBranch(suspense, fallbackVNode);
};
const delayEnter = fallbackVNode.transition && fallbackVNode.transition.mode === 'out-in';
@@ -2277,1128 +2301,655 @@ function withScopeId(id) {
}));
}
-const isTeleport = (type) => type.__isTeleport;
-const isTeleportDisabled = (props) => props && (props.disabled || props.disabled === '');
-const resolveTarget = (props, select) => {
- const targetSelector = props && props.to;
- if (isString(targetSelector)) {
- if (!select) {
- (process.env.NODE_ENV !== 'production') &&
- warn(`Current renderer does not support string target for Teleports. ` +
- `(missing querySelector renderer option)`);
- return null;
- }
- else {
- const target = select(targetSelector);
- if (!target) {
- (process.env.NODE_ENV !== 'production') &&
- warn(`Failed to locate Teleport target with selector "${targetSelector}". ` +
- `Note the target element must exist before the component is mounted - ` +
- `i.e. the target cannot be rendered by the component itself, and ` +
- `ideally should be outside of the entire Vue component tree.`);
- }
- return target;
- }
+function initProps(instance, rawProps, isStateful, // result of bitwise flag comparison
+isSSR = false) {
+ const props = {};
+ const attrs = {};
+ def(attrs, InternalObjectKey, 1);
+ setFullProps(instance, rawProps, props, attrs);
+ // validation
+ if ((process.env.NODE_ENV !== 'production')) {
+ validateProps(props, instance);
}
- else {
- if ((process.env.NODE_ENV !== 'production') && !targetSelector && !isTeleportDisabled(props)) {
- warn(`Invalid Teleport target: ${targetSelector}`);
- }
- return targetSelector;
+ if (isStateful) {
+ // stateful
+ instance.props = isSSR ? props : shallowReactive(props);
}
-};
-const TeleportImpl = {
- __isTeleport: true,
- process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized, internals) {
- const { mc: mountChildren, pc: patchChildren, pbc: patchBlockChildren, o: { insert, querySelector, createText, createComment } } = internals;
- const disabled = isTeleportDisabled(n2.props);
- const { shapeFlag, children } = n2;
- if (n1 == null) {
- // insert anchors in the main view
- const placeholder = (n2.el = (process.env.NODE_ENV !== 'production')
- ? createComment('teleport start')
- : createText(''));
- const mainAnchor = (n2.anchor = (process.env.NODE_ENV !== 'production')
- ? createComment('teleport end')
- : createText(''));
- insert(placeholder, container, anchor);
- insert(mainAnchor, container, anchor);
- const target = (n2.target = resolveTarget(n2.props, querySelector));
- const targetAnchor = (n2.targetAnchor = createText(''));
- if (target) {
- insert(targetAnchor, target);
- }
- else if ((process.env.NODE_ENV !== 'production') && !disabled) {
- warn('Invalid Teleport target on mount:', target, `(${typeof target})`);
- }
- const mount = (container, anchor) => {
- // Teleport *always* has Array children. This is enforced in both the
- // compiler and vnode children normalization.
- if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
- mountChildren(children, container, anchor, parentComponent, parentSuspense, isSVG, optimized);
- }
- };
- if (disabled) {
- mount(container, mainAnchor);
- }
- else if (target) {
- mount(target, targetAnchor);
- }
+ else {
+ if (!instance.type.props) {
+ // functional w/ optional props, props === attrs
+ instance.props = attrs;
}
else {
- // update content
- n2.el = n1.el;
- const mainAnchor = (n2.anchor = n1.anchor);
- const target = (n2.target = n1.target);
- const targetAnchor = (n2.targetAnchor = n1.targetAnchor);
- const wasDisabled = isTeleportDisabled(n1.props);
- const currentContainer = wasDisabled ? container : target;
- const currentAnchor = wasDisabled ? mainAnchor : targetAnchor;
- if (n2.dynamicChildren) {
- // fast path when the teleport happens to be a block root
- patchBlockChildren(n1.dynamicChildren, n2.dynamicChildren, currentContainer, parentComponent, parentSuspense, isSVG);
- // even in block tree mode we need to make sure all root-level nodes
- // in the teleport inherit previous DOM references so that they can
- // be moved in future patches.
- if (n2.shapeFlag & 16 /* ARRAY_CHILDREN */) {
- const oldChildren = n1.children;
- const children = n2.children;
- for (let i = 0; i < children.length; i++) {
- // only inherit for non-patched nodes (i.e. static ones)
- if (!children[i].el) {
- children[i].el = oldChildren[i].el;
- }
+ // functional w/ declared props
+ instance.props = props;
+ }
+ }
+ instance.attrs = attrs;
+}
+function updateProps(instance, rawProps, rawPrevProps, optimized) {
+ const { props, attrs, vnode: { patchFlag } } = instance;
+ const rawCurrentProps = toRaw(props);
+ const [options] = instance.propsOptions;
+ if (
+ // always force full diff in dev
+ // - #1942 if hmr is enabled with sfc component
+ // - vite#872 non-sfc component used by sfc component
+ !((process.env.NODE_ENV !== 'production') &&
+ (instance.type.__hmrId ||
+ (instance.parent && instance.parent.type.__hmrId))) &&
+ (optimized || patchFlag > 0) &&
+ !(patchFlag & 16 /* FULL_PROPS */)) {
+ if (patchFlag & 8 /* PROPS */) {
+ // Compiler-generated props & no keys change, just set the updated
+ // the props.
+ const propsToUpdate = instance.vnode.dynamicProps;
+ for (let i = 0; i < propsToUpdate.length; i++) {
+ const key = propsToUpdate[i];
+ // PROPS flag guarantees rawProps to be non-null
+ const value = rawProps[key];
+ if (options) {
+ // attr / props separation was done on init and will be consistent
+ // in this code path, so just check if attrs have it.
+ if (hasOwn(attrs, key)) {
+ attrs[key] = value;
+ }
+ else {
+ const camelizedKey = camelize(key);
+ props[camelizedKey] = resolvePropValue(options, rawCurrentProps, camelizedKey, value, instance);
}
}
- }
- else if (!optimized) {
- patchChildren(n1, n2, currentContainer, currentAnchor, parentComponent, parentSuspense, isSVG);
- }
- if (disabled) {
- if (!wasDisabled) {
- // enabled -> disabled
- // move into main container
- moveTeleport(n2, container, mainAnchor, internals, 1 /* TOGGLE */);
+ else {
+ attrs[key] = value;
}
}
- else {
- // target changed
- if ((n2.props && n2.props.to) !== (n1.props && n1.props.to)) {
- const nextTarget = (n2.target = resolveTarget(n2.props, querySelector));
- if (nextTarget) {
- moveTeleport(n2, nextTarget, null, internals, 0 /* TARGET_CHANGE */);
- }
- else if ((process.env.NODE_ENV !== 'production')) {
- warn('Invalid Teleport target on update:', target, `(${typeof target})`);
+ }
+ }
+ else {
+ // full props update.
+ setFullProps(instance, rawProps, props, attrs);
+ // in case of dynamic props, check if we need to delete keys from
+ // the props object
+ let kebabKey;
+ for (const key in rawCurrentProps) {
+ if (!rawProps ||
+ // for camelCase
+ (!hasOwn(rawProps, key) &&
+ // it's possible the original props was passed in as kebab-case
+ // and converted to camelCase (#955)
+ ((kebabKey = hyphenate(key)) === key || !hasOwn(rawProps, kebabKey)))) {
+ if (options) {
+ if (rawPrevProps &&
+ // for camelCase
+ (rawPrevProps[key] !== undefined ||
+ // for kebab-case
+ rawPrevProps[kebabKey] !== undefined)) {
+ props[key] = resolvePropValue(options, rawProps || EMPTY_OBJ, key, undefined, instance);
}
}
- else if (wasDisabled) {
- // disabled -> enabled
- // move into teleport target
- moveTeleport(n2, target, targetAnchor, internals, 1 /* TOGGLE */);
+ else {
+ delete props[key];
}
}
}
- },
- remove(vnode, { r: remove, o: { remove: hostRemove } }) {
- const { shapeFlag, children, anchor } = vnode;
- hostRemove(anchor);
- if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
- for (let i = 0; i < children.length; i++) {
- remove(children[i]);
+ // in the case of functional component w/o props declaration, props and
+ // attrs point to the same object so it should already have been updated.
+ if (attrs !== rawCurrentProps) {
+ for (const key in attrs) {
+ if (!rawProps || !hasOwn(rawProps, key)) {
+ delete attrs[key];
+ }
}
}
- },
- move: moveTeleport,
- hydrate: hydrateTeleport
-};
-function moveTeleport(vnode, container, parentAnchor, { o: { insert }, m: move }, moveType = 2 /* REORDER */) {
- // move target anchor if this is a target change.
- if (moveType === 0 /* TARGET_CHANGE */) {
- insert(vnode.targetAnchor, container, parentAnchor);
}
- const { el, anchor, shapeFlag, children, props } = vnode;
- const isReorder = moveType === 2 /* REORDER */;
- // move main view anchor if this is a re-order.
- if (isReorder) {
- insert(el, container, parentAnchor);
+ // trigger updates for $attrs in case it's used in component slots
+ trigger(instance, "set" /* SET */, '$attrs');
+ if ((process.env.NODE_ENV !== 'production') && rawProps) {
+ validateProps(props, instance);
}
- // if this is a re-order and teleport is enabled (content is in target)
- // do not move children. So the opposite is: only move children if this
- // is not a reorder, or the teleport is disabled
- if (!isReorder || isTeleportDisabled(props)) {
- // Teleport has either Array children or no children.
- if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
- for (let i = 0; i < children.length; i++) {
- move(children[i], container, parentAnchor, 2 /* REORDER */);
+}
+function setFullProps(instance, rawProps, props, attrs) {
+ const [options, needCastKeys] = instance.propsOptions;
+ if (rawProps) {
+ for (const key in rawProps) {
+ const value = rawProps[key];
+ // key, ref are reserved and never passed down
+ if (isReservedProp(key)) {
+ continue;
+ }
+ // prop option names are camelized during normalization, so to support
+ // kebab -> camel conversion here we need to camelize the key.
+ let camelKey;
+ if (options && hasOwn(options, (camelKey = camelize(key)))) {
+ props[camelKey] = value;
+ }
+ else if (!isEmitListener(instance.emitsOptions, key)) {
+ // Any non-declared (either as a prop or an emitted event) props are put
+ // into a separate `attrs` object for spreading. Make sure to preserve
+ // original key casing
+ attrs[key] = value;
}
}
}
- // move main view anchor if this is a re-order.
- if (isReorder) {
- insert(anchor, container, parentAnchor);
+ if (needCastKeys) {
+ const rawCurrentProps = toRaw(props);
+ for (let i = 0; i < needCastKeys.length; i++) {
+ const key = needCastKeys[i];
+ props[key] = resolvePropValue(options, rawCurrentProps, key, rawCurrentProps[key], instance);
+ }
}
}
-function hydrateTeleport(node, vnode, parentComponent, parentSuspense, optimized, { o: { nextSibling, parentNode, querySelector } }, hydrateChildren) {
- const target = (vnode.target = resolveTarget(vnode.props, querySelector));
- if (target) {
- // if multiple teleports rendered to the same target element, we need to
- // pick up from where the last teleport finished instead of the first node
- const targetNode = target._lpa || target.firstChild;
- if (vnode.shapeFlag & 16 /* ARRAY_CHILDREN */) {
- if (isTeleportDisabled(vnode.props)) {
- vnode.anchor = hydrateChildren(nextSibling(node), vnode, parentNode(node), parentComponent, parentSuspense, optimized);
- vnode.targetAnchor = targetNode;
+function resolvePropValue(options, props, key, value, instance) {
+ const opt = options[key];
+ if (opt != null) {
+ const hasDefault = hasOwn(opt, 'default');
+ // default values
+ if (hasDefault && value === undefined) {
+ const defaultValue = opt.default;
+ if (opt.type !== Function && isFunction(defaultValue)) {
+ setCurrentInstance(instance);
+ value = defaultValue(props);
+ setCurrentInstance(null);
}
else {
- vnode.anchor = nextSibling(node);
- vnode.targetAnchor = hydrateChildren(targetNode, vnode, target, parentComponent, parentSuspense, optimized);
+ value = defaultValue;
+ }
+ }
+ // boolean casting
+ if (opt[0 /* shouldCast */]) {
+ if (!hasOwn(props, key) && !hasDefault) {
+ value = false;
+ }
+ else if (opt[1 /* shouldCastTrue */] &&
+ (value === '' || value === hyphenate(key))) {
+ value = true;
}
- target._lpa =
- vnode.targetAnchor && nextSibling(vnode.targetAnchor);
}
}
- return vnode.anchor && nextSibling(vnode.anchor);
-}
-// Force-casted public typing for h and TSX props inference
-const Teleport = TeleportImpl;
-
-const COMPONENTS = 'components';
-const DIRECTIVES = 'directives';
-/**
- * @private
- */
-function resolveComponent(name) {
- return resolveAsset(COMPONENTS, name) || name;
+ return value;
}
-const NULL_DYNAMIC_COMPONENT = Symbol();
-/**
- * @private
- */
-function resolveDynamicComponent(component) {
- if (isString(component)) {
- return resolveAsset(COMPONENTS, component, false) || component;
+function normalizePropsOptions(comp, appContext, asMixin = false) {
+ if (!appContext.deopt && comp.__props) {
+ return comp.__props;
}
- else {
- // invalid types will fallthrough to createVNode and raise warning
- return (component || NULL_DYNAMIC_COMPONENT);
+ const raw = comp.props;
+ const normalized = {};
+ const needCastKeys = [];
+ // apply mixin/extends props
+ let hasExtends = false;
+ if (__VUE_OPTIONS_API__ && !isFunction(comp)) {
+ const extendProps = (raw) => {
+ hasExtends = true;
+ const [props, keys] = normalizePropsOptions(raw, appContext, true);
+ extend(normalized, props);
+ if (keys)
+ needCastKeys.push(...keys);
+ };
+ if (!asMixin && appContext.mixins.length) {
+ appContext.mixins.forEach(extendProps);
+ }
+ if (comp.extends) {
+ extendProps(comp.extends);
+ }
+ if (comp.mixins) {
+ comp.mixins.forEach(extendProps);
+ }
}
-}
-/**
- * @private
- */
-function resolveDirective(name) {
- return resolveAsset(DIRECTIVES, name);
-}
-// implementation
-function resolveAsset(type, name, warnMissing = true) {
- const instance = currentRenderingInstance || currentInstance;
- if (instance) {
- const Component = instance.type;
- // self name has highest priority
- if (type === COMPONENTS) {
- const selfName = Component.displayName || Component.name;
- if (selfName &&
- (selfName === name ||
- selfName === camelize(name) ||
- selfName === capitalize(camelize(name)))) {
- return Component;
+ if (!raw && !hasExtends) {
+ return (comp.__props = EMPTY_ARR);
+ }
+ if (isArray(raw)) {
+ for (let i = 0; i < raw.length; i++) {
+ if ((process.env.NODE_ENV !== 'production') && !isString(raw[i])) {
+ warn(`props must be strings when using array syntax.`, raw[i]);
+ }
+ const normalizedKey = camelize(raw[i]);
+ if (validatePropName(normalizedKey)) {
+ normalized[normalizedKey] = EMPTY_OBJ;
}
}
- const res =
- // local registration
- // check instance[type] first for components with mixin or extends.
- resolve(instance[type] || Component[type], name) ||
- // global registration
- resolve(instance.appContext[type], name);
- if ((process.env.NODE_ENV !== 'production') && warnMissing && !res) {
- warn(`Failed to resolve ${type.slice(0, -1)}: ${name}`);
+ }
+ else if (raw) {
+ if ((process.env.NODE_ENV !== 'production') && !isObject(raw)) {
+ warn(`invalid props options`, raw);
}
- return res;
+ for (const key in raw) {
+ const normalizedKey = camelize(key);
+ if (validatePropName(normalizedKey)) {
+ const opt = raw[key];
+ const prop = (normalized[normalizedKey] =
+ isArray(opt) || isFunction(opt) ? { type: opt } : opt);
+ if (prop) {
+ const booleanIndex = getTypeIndex(Boolean, prop.type);
+ const stringIndex = getTypeIndex(String, prop.type);
+ prop[0 /* shouldCast */] = booleanIndex > -1;
+ prop[1 /* shouldCastTrue */] =
+ stringIndex < 0 || booleanIndex < stringIndex;
+ // if the prop needs boolean casting or default value
+ if (booleanIndex > -1 || hasOwn(prop, 'default')) {
+ needCastKeys.push(normalizedKey);
+ }
+ }
+ }
+ }
+ }
+ return (comp.__props = [normalized, needCastKeys]);
+}
+function validatePropName(key) {
+ if (key[0] !== '$') {
+ return true;
}
else if ((process.env.NODE_ENV !== 'production')) {
- warn(`resolve${capitalize(type.slice(0, -1))} ` +
- `can only be used in render() or setup().`);
+ warn(`Invalid prop name: "${key}" is a reserved property.`);
}
+ return false;
}
-function resolve(registry, name) {
- return (registry &&
- (registry[name] ||
- registry[camelize(name)] ||
- registry[capitalize(camelize(name))]));
-}
-
-const Fragment = Symbol((process.env.NODE_ENV !== 'production') ? 'Fragment' : undefined);
-const Text = Symbol((process.env.NODE_ENV !== 'production') ? 'Text' : undefined);
-const Comment = Symbol((process.env.NODE_ENV !== 'production') ? 'Comment' : undefined);
-const Static = Symbol((process.env.NODE_ENV !== 'production') ? 'Static' : undefined);
-// Since v-if and v-for are the two possible ways node structure can dynamically
-// change, once we consider v-if branches and each v-for fragment a block, we
-// can divide a template into nested blocks, and within each block the node
-// structure would be stable. This allows us to skip most children diffing
-// and only worry about the dynamic nodes (indicated by patch flags).
-const blockStack = [];
-let currentBlock = null;
-/**
- * Open a block.
- * This must be called before `createBlock`. It cannot be part of `createBlock`
- * because the children of the block are evaluated before `createBlock` itself
- * is called. The generated code typically looks like this:
- *
- * ```js
- * function render() {
- * return (openBlock(),createBlock('div', null, [...]))
- * }
- * ```
- * disableTracking is true when creating a v-for fragment block, since a v-for
- * fragment always diffs its children.
- *
- * @private
- */
-function openBlock(disableTracking = false) {
- blockStack.push((currentBlock = disableTracking ? null : []));
+// use function string name to check type constructors
+// so that it works across vms / iframes.
+function getType(ctor) {
+ const match = ctor && ctor.toString().match(/^\s*function (\w+)/);
+ return match ? match[1] : '';
}
-function closeBlock() {
- blockStack.pop();
- currentBlock = blockStack[blockStack.length - 1] || null;
+function isSameType(a, b) {
+ return getType(a) === getType(b);
+}
+function getTypeIndex(type, expectedTypes) {
+ if (isArray(expectedTypes)) {
+ for (let i = 0, len = expectedTypes.length; i < len; i++) {
+ if (isSameType(expectedTypes[i], type)) {
+ return i;
+ }
+ }
+ }
+ else if (isFunction(expectedTypes)) {
+ return isSameType(expectedTypes, type) ? 0 : -1;
+ }
+ return -1;
}
-// Whether we should be tracking dynamic child nodes inside a block.
-// Only tracks when this value is > 0
-// We are not using a simple boolean because this value may need to be
-// incremented/decremented by nested usage of v-once (see below)
-let shouldTrack$1 = 1;
/**
- * Block tracking sometimes needs to be disabled, for example during the
- * creation of a tree that needs to be cached by v-once. The compiler generates
- * code like this:
- *
- * ``` js
- * _cache[1] || (
- * setBlockTracking(-1),
- * _cache[1] = createVNode(...),
- * setBlockTracking(1),
- * _cache[1]
- * )
- * ```
- *
- * @private
+ * dev only
*/
-function setBlockTracking(value) {
- shouldTrack$1 += value;
+function validateProps(props, instance) {
+ const rawValues = toRaw(props);
+ const options = instance.propsOptions[0];
+ for (const key in options) {
+ let opt = options[key];
+ if (opt == null)
+ continue;
+ validateProp(key, rawValues[key], opt, !hasOwn(rawValues, key));
+ }
}
/**
- * Create a block root vnode. Takes the same exact arguments as `createVNode`.
- * A block root keeps track of dynamic nodes within the block in the
- * `dynamicChildren` array.
- *
- * @private
+ * dev only
*/
-function createBlock(type, props, children, patchFlag, dynamicProps) {
- const vnode = createVNode(type, props, children, patchFlag, dynamicProps, true /* isBlock: prevent a block from tracking itself */);
- // save current block children on the block vnode
- vnode.dynamicChildren = currentBlock || EMPTY_ARR;
- // close block
- closeBlock();
- // a block is always going to be patched, so track it as a child of its
- // parent block
- if (shouldTrack$1 > 0 && currentBlock) {
- currentBlock.push(vnode);
+function validateProp(name, value, prop, isAbsent) {
+ const { type, required, validator } = prop;
+ // required!
+ if (required && isAbsent) {
+ warn('Missing required prop: "' + name + '"');
+ return;
}
- return vnode;
-}
-function isVNode(value) {
- return value ? value.__v_isVNode === true : false;
-}
-function isSameVNodeType(n1, n2) {
- if ((process.env.NODE_ENV !== 'production') &&
- n2.shapeFlag & 6 /* COMPONENT */ &&
- hmrDirtyComponents.has(n2.type)) {
- // HMR only: if the component has been hot-updated, force a reload.
- return false;
+ // missing but optional
+ if (value == null && !prop.required) {
+ return;
}
- return n1.type === n2.type && n1.key === n2.key;
-}
-let vnodeArgsTransformer;
-/**
- * Internal API for registering an arguments transform for createVNode
- * used for creating stubs in the test-utils
- * It is *internal* but needs to be exposed for test-utils to pick up proper
- * typings
- */
-function transformVNodeArgs(transformer) {
- vnodeArgsTransformer = transformer;
-}
-const createVNodeWithArgsTransform = (...args) => {
- return _createVNode(...(vnodeArgsTransformer
- ? vnodeArgsTransformer(args, currentRenderingInstance)
- : args));
-};
-const InternalObjectKey = `__vInternal`;
-const normalizeKey = ({ key }) => key != null ? key : null;
-const normalizeRef = ({ ref }) => {
- return (ref != null
- ? isArray(ref)
- ? ref
- : { i: currentRenderingInstance, r: ref }
- : null);
-};
-const createVNode = ((process.env.NODE_ENV !== 'production')
- ? createVNodeWithArgsTransform
- : _createVNode);
-function _createVNode(type, props = null, children = null, patchFlag = 0, dynamicProps = null, isBlockNode = false) {
- if (!type || type === NULL_DYNAMIC_COMPONENT) {
- if ((process.env.NODE_ENV !== 'production') && !type) {
- warn(`Invalid vnode type when creating vnode: ${type}.`);
+ // type check
+ if (type != null && type !== true) {
+ let isValid = false;
+ const types = isArray(type) ? type : [type];
+ const expectedTypes = [];
+ // value is valid as long as one of the specified types match
+ for (let i = 0; i < types.length && !isValid; i++) {
+ const { valid, expectedType } = assertType(value, types[i]);
+ expectedTypes.push(expectedType || '');
+ isValid = valid;
}
- type = Comment;
- }
- if (isVNode(type)) {
- // createVNode receiving an existing vnode. This happens in cases like
- //
- // #2078 make sure to merge refs during the clone instead of overwriting it
- const cloned = cloneVNode(type, props, true /* mergeRef: true */);
- if (children) {
- normalizeChildren(cloned, children);
+ if (!isValid) {
+ warn(getInvalidTypeMessage(name, value, expectedTypes));
+ return;
}
- return cloned;
}
- // class component normalization.
- if (isClassComponent(type)) {
- type = type.__vccOpts;
+ // custom validator
+ if (validator && !validator(value)) {
+ warn('Invalid prop: custom validator check failed for prop "' + name + '".');
}
- // class & style normalization.
- if (props) {
- // for reactive or proxy objects, we need to clone it to enable mutation.
- if (isProxy(props) || InternalObjectKey in props) {
- props = extend({}, props);
- }
- let { class: klass, style } = props;
- if (klass && !isString(klass)) {
- props.class = normalizeClass(klass);
- }
- if (isObject(style)) {
- // reactive state objects need to be cloned since they are likely to be
- // mutated
- if (isProxy(style) && !isArray(style)) {
- style = extend({}, style);
- }
- props.style = normalizeStyle(style);
+}
+const isSimpleType = /*#__PURE__*/ makeMap('String,Number,Boolean,Function,Symbol');
+/**
+ * dev only
+ */
+function assertType(value, type) {
+ let valid;
+ const expectedType = getType(type);
+ if (isSimpleType(expectedType)) {
+ const t = typeof value;
+ valid = t === expectedType.toLowerCase();
+ // for primitive wrapper objects
+ if (!valid && t === 'object') {
+ valid = value instanceof type;
}
}
- // encode the vnode type information into a bitmap
- const shapeFlag = isString(type)
- ? 1 /* ELEMENT */
- : isSuspense(type)
- ? 128 /* SUSPENSE */
- : isTeleport(type)
- ? 64 /* TELEPORT */
- : isObject(type)
- ? 4 /* STATEFUL_COMPONENT */
- : isFunction(type)
- ? 2 /* FUNCTIONAL_COMPONENT */
- : 0;
- if ((process.env.NODE_ENV !== 'production') && shapeFlag & 4 /* STATEFUL_COMPONENT */ && isProxy(type)) {
- type = toRaw(type);
- warn(`Vue received a Component which was made a reactive object. This can ` +
- `lead to unnecessary performance overhead, and should be avoided by ` +
- `marking the component with \`markRaw\` or using \`shallowRef\` ` +
- `instead of \`ref\`.`, `\nComponent that was made reactive: `, type);
- }
- const vnode = {
- __v_isVNode: true,
- ["__v_skip" /* SKIP */]: true,
- type,
- props,
- key: props && normalizeKey(props),
- ref: props && normalizeRef(props),
- scopeId: currentScopeId,
- children: null,
- component: null,
- suspense: null,
- ssContent: null,
- ssFallback: null,
- dirs: null,
- transition: null,
- el: null,
- anchor: null,
- target: null,
- targetAnchor: null,
- staticCount: 0,
- shapeFlag,
- patchFlag,
- dynamicProps,
- dynamicChildren: null,
- appContext: null
- };
- // validate key
- if ((process.env.NODE_ENV !== 'production') && vnode.key !== vnode.key) {
- warn(`VNode created with invalid key (NaN). VNode type:`, vnode.type);
+ else if (expectedType === 'Object') {
+ valid = isObject(value);
}
- normalizeChildren(vnode, children);
- // normalize suspense children
- if ( shapeFlag & 128 /* SUSPENSE */) {
- const { content, fallback } = normalizeSuspenseChildren(vnode);
- vnode.ssContent = content;
- vnode.ssFallback = fallback;
+ else if (expectedType === 'Array') {
+ valid = isArray(value);
}
- if (shouldTrack$1 > 0 &&
- // avoid a block node from tracking itself
- !isBlockNode &&
- // has current parent block
- currentBlock &&
- // presence of a patch flag indicates this node needs patching on updates.
- // component nodes also should always be patched, because even if the
- // component doesn't need to update, it needs to persist the instance on to
- // the next vnode so that it can be properly unmounted later.
- (patchFlag > 0 || shapeFlag & 6 /* COMPONENT */) &&
- // the EVENTS flag is only for hydration and if it is the only flag, the
- // vnode should not be considered dynamic due to handler caching.
- patchFlag !== 32 /* HYDRATE_EVENTS */) {
- currentBlock.push(vnode);
+ else {
+ valid = value instanceof type;
}
- return vnode;
-}
-function cloneVNode(vnode, extraProps, mergeRef = false) {
- // This is intentionally NOT using spread or extend to avoid the runtime
- // key enumeration cost.
- const { props, ref, patchFlag } = vnode;
- const mergedProps = extraProps ? mergeProps(props || {}, extraProps) : props;
return {
- __v_isVNode: true,
- ["__v_skip" /* SKIP */]: true,
- type: vnode.type,
- props: mergedProps,
- key: mergedProps && normalizeKey(mergedProps),
- ref: extraProps && extraProps.ref
- ? // #2078 in the case of
- // if the vnode itself already has a ref, cloneVNode will need to merge
- // the refs so the single vnode can be set on multiple refs
- mergeRef && ref
- ? isArray(ref)
- ? ref.concat(normalizeRef(extraProps))
- : [ref, normalizeRef(extraProps)]
- : normalizeRef(extraProps)
- : ref,
- scopeId: vnode.scopeId,
- children: vnode.children,
- target: vnode.target,
- targetAnchor: vnode.targetAnchor,
- staticCount: vnode.staticCount,
- shapeFlag: vnode.shapeFlag,
- // if the vnode is cloned with extra props, we can no longer assume its
- // existing patch flag to be reliable and need to add the FULL_PROPS flag.
- // note: perserve flag for fragments since they use the flag for children
- // fast paths only.
- patchFlag: extraProps && vnode.type !== Fragment
- ? patchFlag === -1 // hoisted node
- ? 16 /* FULL_PROPS */
- : patchFlag | 16 /* FULL_PROPS */
- : patchFlag,
- dynamicProps: vnode.dynamicProps,
- dynamicChildren: vnode.dynamicChildren,
- appContext: vnode.appContext,
- dirs: vnode.dirs,
- transition: vnode.transition,
- // These should technically only be non-null on mounted VNodes. However,
- // they *should* be copied for kept-alive vnodes. So we just always copy
- // them since them being non-null during a mount doesn't affect the logic as
- // they will simply be overwritten.
- component: vnode.component,
- suspense: vnode.suspense,
- ssContent: vnode.ssContent && cloneVNode(vnode.ssContent),
- ssFallback: vnode.ssFallback && cloneVNode(vnode.ssFallback),
- el: vnode.el,
- anchor: vnode.anchor
+ valid,
+ expectedType
};
}
/**
- * @private
+ * dev only
*/
-function createTextVNode(text = ' ', flag = 0) {
- return createVNode(Text, null, text, flag);
-}
-/**
- * @private
- */
-function createStaticVNode(content, numberOfNodes) {
- // A static vnode can contain multiple stringified elements, and the number
- // of elements is necessary for hydration.
- const vnode = createVNode(Static, null, content);
- vnode.staticCount = numberOfNodes;
- return vnode;
+function getInvalidTypeMessage(name, value, expectedTypes) {
+ let message = `Invalid prop: type check failed for prop "${name}".` +
+ ` Expected ${expectedTypes.map(capitalize).join(', ')}`;
+ const expectedType = expectedTypes[0];
+ const receivedType = toRawType(value);
+ const expectedValue = styleValue(value, expectedType);
+ const receivedValue = styleValue(value, receivedType);
+ // check if we need to specify expected value
+ if (expectedTypes.length === 1 &&
+ isExplicable(expectedType) &&
+ !isBoolean(expectedType, receivedType)) {
+ message += ` with value ${expectedValue}`;
+ }
+ message += `, got ${receivedType} `;
+ // check if we need to specify received value
+ if (isExplicable(receivedType)) {
+ message += `with value ${receivedValue}.`;
+ }
+ return message;
}
/**
- * @private
+ * dev only
*/
-function createCommentVNode(text = '',
-// when used as the v-else branch, the comment node must be created as a
-// block to ensure correct updates.
-asBlock = false) {
- return asBlock
- ? (openBlock(), createBlock(Comment, null, text))
- : createVNode(Comment, null, text);
-}
-function normalizeVNode(child) {
- if (child == null || typeof child === 'boolean') {
- // empty placeholder
- return createVNode(Comment);
- }
- else if (isArray(child)) {
- // fragment
- return createVNode(Fragment, null, child);
+function styleValue(value, type) {
+ if (type === 'String') {
+ return `"${value}"`;
}
- else if (typeof child === 'object') {
- // already vnode, this should be the most common since compiled templates
- // always produce all-vnode children arrays
- return child.el === null ? child : cloneVNode(child);
+ else if (type === 'Number') {
+ return `${Number(value)}`;
}
else {
- // strings and numbers
- return createVNode(Text, null, String(child));
+ return `${value}`;
}
}
-// optimized normalization for template-compiled render fns
-function cloneIfMounted(child) {
- return child.el === null ? child : cloneVNode(child);
+/**
+ * dev only
+ */
+function isExplicable(type) {
+ const explicitTypes = ['string', 'number', 'boolean'];
+ return explicitTypes.some(elem => type.toLowerCase() === elem);
}
-function normalizeChildren(vnode, children) {
- let type = 0;
- const { shapeFlag } = vnode;
- if (children == null) {
- children = null;
- }
- else if (isArray(children)) {
- type = 16 /* ARRAY_CHILDREN */;
- }
- else if (typeof children === 'object') {
- if (shapeFlag & 1 /* ELEMENT */ || shapeFlag & 64 /* TELEPORT */) {
- // Normalize slot to plain children for plain element and Teleport
- const slot = children.default;
- if (slot) {
- // _c marker is added by withCtx() indicating this is a compiled slot
- slot._c && setCompiledSlotRendering(1);
- normalizeChildren(vnode, slot());
- slot._c && setCompiledSlotRendering(-1);
- }
- return;
+/**
+ * dev only
+ */
+function isBoolean(...args) {
+ return args.some(elem => elem.toLowerCase() === 'boolean');
+}
+
+function injectHook(type, hook, target = currentInstance, prepend = false) {
+ if (target) {
+ const hooks = target[type] || (target[type] = []);
+ // cache the error handling wrapper for injected hooks so the same hook
+ // can be properly deduped by the scheduler. "__weh" stands for "with error
+ // handling".
+ const wrappedHook = hook.__weh ||
+ (hook.__weh = (...args) => {
+ if (target.isUnmounted) {
+ return;
+ }
+ // disable tracking inside all lifecycle hooks
+ // since they can potentially be called inside effects.
+ pauseTracking();
+ // Set currentInstance during hook invocation.
+ // This assumes the hook does not synchronously trigger other hooks, which
+ // can only be false when the user does something really funky.
+ setCurrentInstance(target);
+ const res = callWithAsyncErrorHandling(hook, target, type, args);
+ setCurrentInstance(null);
+ resetTracking();
+ return res;
+ });
+ if (prepend) {
+ hooks.unshift(wrappedHook);
}
else {
- type = 32 /* SLOTS_CHILDREN */;
- const slotFlag = children._;
- if (!slotFlag && !(InternalObjectKey in children)) {
- children._ctx = currentRenderingInstance;
- }
- else if (slotFlag === 3 /* FORWARDED */ && currentRenderingInstance) {
- // a child component receives forwarded slots from the parent.
- // its slot type is determined by its parent's slot type.
- if (currentRenderingInstance.vnode.patchFlag & 1024 /* DYNAMIC_SLOTS */) {
- children._ = 2 /* DYNAMIC */;
- vnode.patchFlag |= 1024 /* DYNAMIC_SLOTS */;
- }
- else {
- children._ = 1 /* STABLE */;
- }
- }
+ hooks.push(wrappedHook);
}
+ return wrappedHook;
}
- else if (isFunction(children)) {
- children = { default: children, _ctx: currentRenderingInstance };
- type = 32 /* SLOTS_CHILDREN */;
+ else if ((process.env.NODE_ENV !== 'production')) {
+ const apiName = toHandlerKey(ErrorTypeStrings[type].replace(/ hook$/, ''));
+ warn(`${apiName} is called when there is no active component instance to be ` +
+ `associated with. ` +
+ `Lifecycle injection APIs can only be used during execution of setup().` +
+ ( ` If you are using async setup(), make sure to register lifecycle ` +
+ `hooks before the first await statement.`
+ ));
}
- else {
- children = String(children);
- // force teleport children to array so it can be moved around
- if (shapeFlag & 64 /* TELEPORT */) {
- type = 16 /* ARRAY_CHILDREN */;
- children = [createTextVNode(children)];
+}
+const createHook = (lifecycle) => (hook, target = currentInstance) =>
+// post-create lifecycle registrations are noops during SSR
+!isInSSRComponentSetup && injectHook(lifecycle, hook, target);
+const onBeforeMount = createHook("bm" /* BEFORE_MOUNT */);
+const onMounted = createHook("m" /* MOUNTED */);
+const onBeforeUpdate = createHook("bu" /* BEFORE_UPDATE */);
+const onUpdated = createHook("u" /* UPDATED */);
+const onBeforeUnmount = createHook("bum" /* BEFORE_UNMOUNT */);
+const onUnmounted = createHook("um" /* UNMOUNTED */);
+const onRenderTriggered = createHook("rtg" /* RENDER_TRIGGERED */);
+const onRenderTracked = createHook("rtc" /* RENDER_TRACKED */);
+const onErrorCaptured = (hook, target = currentInstance) => {
+ injectHook("ec" /* ERROR_CAPTURED */, hook, target);
+};
+
+// Simple effect.
+function watchEffect(effect, options) {
+ return doWatch(effect, null, options);
+}
+// initial value for watchers to trigger on undefined initial values
+const INITIAL_WATCHER_VALUE = {};
+// implementation
+function watch(source, cb, options) {
+ if ((process.env.NODE_ENV !== 'production') && !isFunction(cb)) {
+ warn(`\`watch(fn, options?)\` signature has been moved to a separate API. ` +
+ `Use \`watchEffect(fn, options?)\` instead. \`watch\` now only ` +
+ `supports \`watch(source, cb, options?) signature.`);
+ }
+ return doWatch(source, cb, options);
+}
+function doWatch(source, cb, { immediate, deep, flush, onTrack, onTrigger } = EMPTY_OBJ, instance = currentInstance) {
+ if ((process.env.NODE_ENV !== 'production') && !cb) {
+ if (immediate !== undefined) {
+ warn(`watch() "immediate" option is only respected when using the ` +
+ `watch(source, callback, options?) signature.`);
}
- else {
- type = 8 /* TEXT_CHILDREN */;
+ if (deep !== undefined) {
+ warn(`watch() "deep" option is only respected when using the ` +
+ `watch(source, callback, options?) signature.`);
}
}
- vnode.children = children;
- vnode.shapeFlag |= type;
-}
-function mergeProps(...args) {
- const ret = extend({}, args[0]);
- for (let i = 1; i < args.length; i++) {
- const toMerge = args[i];
- for (const key in toMerge) {
- if (key === 'class') {
- if (ret.class !== toMerge.class) {
- ret.class = normalizeClass([ret.class, toMerge.class]);
- }
+ const warnInvalidSource = (s) => {
+ warn(`Invalid watch source: `, s, `A watch source can only be a getter/effect function, a ref, ` +
+ `a reactive object, or an array of these types.`);
+ };
+ let getter;
+ let forceTrigger = false;
+ if (isRef(source)) {
+ getter = () => source.value;
+ forceTrigger = !!source._shallow;
+ }
+ else if (isReactive(source)) {
+ getter = () => source;
+ deep = true;
+ }
+ else if (isArray(source)) {
+ getter = () => source.map(s => {
+ if (isRef(s)) {
+ return s.value;
}
- else if (key === 'style') {
- ret.style = normalizeStyle([ret.style, toMerge.style]);
+ else if (isReactive(s)) {
+ return traverse(s);
}
- else if (isOn(key)) {
- const existing = ret[key];
- const incoming = toMerge[key];
- if (existing !== incoming) {
- ret[key] = existing
- ? [].concat(existing, toMerge[key])
- : incoming;
- }
+ else if (isFunction(s)) {
+ return callWithErrorHandling(s, instance, 2 /* WATCH_GETTER */);
}
else {
- ret[key] = toMerge[key];
+ (process.env.NODE_ENV !== 'production') && warnInvalidSource(s);
}
+ });
+ }
+ else if (isFunction(source)) {
+ if (cb) {
+ // getter with cb
+ getter = () => callWithErrorHandling(source, instance, 2 /* WATCH_GETTER */);
+ }
+ else {
+ // no cb -> simple effect
+ getter = () => {
+ if (instance && instance.isUnmounted) {
+ return;
+ }
+ if (cleanup) {
+ cleanup();
+ }
+ return callWithErrorHandling(source, instance, 3 /* WATCH_CALLBACK */, [onInvalidate]);
+ };
}
}
- return ret;
-}
-
-function initProps(instance, rawProps, isStateful, // result of bitwise flag comparison
-isSSR = false) {
- const props = {};
- const attrs = {};
- def(attrs, InternalObjectKey, 1);
- setFullProps(instance, rawProps, props, attrs);
- // validation
- if ((process.env.NODE_ENV !== 'production')) {
- validateProps(props, instance);
- }
- if (isStateful) {
- // stateful
- instance.props = isSSR ? props : shallowReactive(props);
- }
else {
- if (!instance.type.props) {
- // functional w/ optional props, props === attrs
- instance.props = attrs;
- }
- else {
- // functional w/ declared props
- instance.props = props;
- }
+ getter = NOOP;
+ (process.env.NODE_ENV !== 'production') && warnInvalidSource(source);
}
- instance.attrs = attrs;
-}
-function updateProps(instance, rawProps, rawPrevProps, optimized) {
- const { props, attrs, vnode: { patchFlag } } = instance;
- const rawCurrentProps = toRaw(props);
- const [options] = instance.propsOptions;
- if (
- // always force full diff if hmr is enabled
- !((process.env.NODE_ENV !== 'production') && instance.type.__hmrId) &&
- (optimized || patchFlag > 0) &&
- !(patchFlag & 16 /* FULL_PROPS */)) {
- if (patchFlag & 8 /* PROPS */) {
- // Compiler-generated props & no keys change, just set the updated
- // the props.
- const propsToUpdate = instance.vnode.dynamicProps;
- for (let i = 0; i < propsToUpdate.length; i++) {
- const key = propsToUpdate[i];
- // PROPS flag guarantees rawProps to be non-null
- const value = rawProps[key];
- if (options) {
- // attr / props separation was done on init and will be consistent
- // in this code path, so just check if attrs have it.
- if (hasOwn(attrs, key)) {
- attrs[key] = value;
- }
- else {
- const camelizedKey = camelize(key);
- props[camelizedKey] = resolvePropValue(options, rawCurrentProps, camelizedKey, value, instance);
- }
- }
- else {
- attrs[key] = value;
- }
- }
- }
+ if (cb && deep) {
+ const baseGetter = getter;
+ getter = () => traverse(baseGetter());
}
- else {
- // full props update.
- setFullProps(instance, rawProps, props, attrs);
- // in case of dynamic props, check if we need to delete keys from
- // the props object
- let kebabKey;
- for (const key in rawCurrentProps) {
- if (!rawProps ||
- // for camelCase
- (!hasOwn(rawProps, key) &&
- // it's possible the original props was passed in as kebab-case
- // and converted to camelCase (#955)
- ((kebabKey = hyphenate(key)) === key || !hasOwn(rawProps, kebabKey)))) {
- if (options) {
- if (rawPrevProps &&
- // for camelCase
- (rawPrevProps[key] !== undefined ||
- // for kebab-case
- rawPrevProps[kebabKey] !== undefined)) {
- props[key] = resolvePropValue(options, rawProps || EMPTY_OBJ, key, undefined, instance);
- }
- }
- else {
- delete props[key];
- }
- }
+ let cleanup;
+ const onInvalidate = (fn) => {
+ cleanup = runner.options.onStop = () => {
+ callWithErrorHandling(fn, instance, 4 /* WATCH_CLEANUP */);
+ };
+ };
+ let oldValue = isArray(source) ? [] : INITIAL_WATCHER_VALUE;
+ const job = () => {
+ if (!runner.active) {
+ return;
}
- // in the case of functional component w/o props declaration, props and
- // attrs point to the same object so it should already have been updated.
- if (attrs !== rawCurrentProps) {
- for (const key in attrs) {
- if (!rawProps || !hasOwn(rawProps, key)) {
- delete attrs[key];
+ if (cb) {
+ // watch(source, cb)
+ const newValue = runner();
+ if (deep || forceTrigger || hasChanged(newValue, oldValue)) {
+ // cleanup before running cb again
+ if (cleanup) {
+ cleanup();
}
+ callWithAsyncErrorHandling(cb, instance, 3 /* WATCH_CALLBACK */, [
+ newValue,
+ // pass undefined as the old value when it's changed for the first time
+ oldValue === INITIAL_WATCHER_VALUE ? undefined : oldValue,
+ onInvalidate
+ ]);
+ oldValue = newValue;
}
}
- }
- // trigger updates for $attrs in case it's used in component slots
- trigger(instance, "set" /* SET */, '$attrs');
- if ((process.env.NODE_ENV !== 'production') && rawProps) {
- validateProps(props, instance);
- }
-}
-function setFullProps(instance, rawProps, props, attrs) {
- const [options, needCastKeys] = instance.propsOptions;
- if (rawProps) {
- for (const key in rawProps) {
- const value = rawProps[key];
- // key, ref are reserved and never passed down
- if (isReservedProp(key)) {
- continue;
- }
- // prop option names are camelized during normalization, so to support
- // kebab -> camel conversion here we need to camelize the key.
- let camelKey;
- if (options && hasOwn(options, (camelKey = camelize(key)))) {
- props[camelKey] = value;
- }
- else if (!isEmitListener(instance.emitsOptions, key)) {
- // Any non-declared (either as a prop or an emitted event) props are put
- // into a separate `attrs` object for spreading. Make sure to preserve
- // original key casing
- attrs[key] = value;
- }
+ else {
+ // watchEffect
+ runner();
}
+ };
+ // important: mark the job as a watcher callback so that scheduler knows
+ // it is allowed to self-trigger (#1727)
+ job.allowRecurse = !!cb;
+ let scheduler;
+ if (flush === 'sync') {
+ scheduler = job;
}
- if (needCastKeys) {
- const rawCurrentProps = toRaw(props);
- for (let i = 0; i < needCastKeys.length; i++) {
- const key = needCastKeys[i];
- props[key] = resolvePropValue(options, rawCurrentProps, key, rawCurrentProps[key], instance);
- }
+ else if (flush === 'post') {
+ scheduler = () => queuePostRenderEffect(job, instance && instance.suspense);
}
-}
-function resolvePropValue(options, props, key, value, instance) {
- const opt = options[key];
- if (opt != null) {
- const hasDefault = hasOwn(opt, 'default');
- // default values
- if (hasDefault && value === undefined) {
- const defaultValue = opt.default;
- if (opt.type !== Function && isFunction(defaultValue)) {
- setCurrentInstance(instance);
- value = defaultValue(props);
- setCurrentInstance(null);
+ else {
+ // default: 'pre'
+ scheduler = () => {
+ if (!instance || instance.isMounted) {
+ queuePreFlushCb(job);
}
else {
- value = defaultValue;
- }
- }
- // boolean casting
- if (opt[0 /* shouldCast */]) {
- if (!hasOwn(props, key) && !hasDefault) {
- value = false;
- }
- else if (opt[1 /* shouldCastTrue */] &&
- (value === '' || value === hyphenate(key))) {
- value = true;
+ // with 'pre' option, the first call must happen before
+ // the component is mounted so it is called synchronously.
+ job();
}
- }
- }
- return value;
-}
-function normalizePropsOptions(comp, appContext, asMixin = false) {
- const appId = appContext.app ? appContext.app._uid : -1;
- const cache = comp.__props || (comp.__props = {});
- const cached = cache[appId];
- if (cached) {
- return cached;
- }
- const raw = comp.props;
- const normalized = {};
- const needCastKeys = [];
- // apply mixin/extends props
- let hasExtends = false;
- if (__VUE_OPTIONS_API__ && !isFunction(comp)) {
- const extendProps = (raw) => {
- hasExtends = true;
- const [props, keys] = normalizePropsOptions(raw, appContext, true);
- extend(normalized, props);
- if (keys)
- needCastKeys.push(...keys);
};
- if (!asMixin && appContext.mixins.length) {
- appContext.mixins.forEach(extendProps);
- }
- if (comp.extends) {
- extendProps(comp.extends);
+ }
+ const runner = effect(getter, {
+ lazy: true,
+ onTrack,
+ onTrigger,
+ scheduler
+ });
+ recordInstanceBoundEffect(runner);
+ // initial run
+ if (cb) {
+ if (immediate) {
+ job();
}
- if (comp.mixins) {
- comp.mixins.forEach(extendProps);
+ else {
+ oldValue = runner();
}
}
- if (!raw && !hasExtends) {
- return (cache[appId] = EMPTY_ARR);
+ else if (flush === 'post') {
+ queuePostRenderEffect(runner, instance && instance.suspense);
}
- if (isArray(raw)) {
- for (let i = 0; i < raw.length; i++) {
- if ((process.env.NODE_ENV !== 'production') && !isString(raw[i])) {
- warn(`props must be strings when using array syntax.`, raw[i]);
- }
- const normalizedKey = camelize(raw[i]);
- if (validatePropName(normalizedKey)) {
- normalized[normalizedKey] = EMPTY_OBJ;
- }
- }
+ else {
+ runner();
}
- else if (raw) {
- if ((process.env.NODE_ENV !== 'production') && !isObject(raw)) {
- warn(`invalid props options`, raw);
+ return () => {
+ stop(runner);
+ if (instance) {
+ remove(instance.effects, runner);
}
- for (const key in raw) {
- const normalizedKey = camelize(key);
- if (validatePropName(normalizedKey)) {
- const opt = raw[key];
- const prop = (normalized[normalizedKey] =
- isArray(opt) || isFunction(opt) ? { type: opt } : opt);
- if (prop) {
- const booleanIndex = getTypeIndex(Boolean, prop.type);
- const stringIndex = getTypeIndex(String, prop.type);
- prop[0 /* shouldCast */] = booleanIndex > -1;
- prop[1 /* shouldCastTrue */] =
- stringIndex < 0 || booleanIndex < stringIndex;
- // if the prop needs boolean casting or default value
- if (booleanIndex > -1 || hasOwn(prop, 'default')) {
- needCastKeys.push(normalizedKey);
- }
- }
- }
- }
- }
- return (cache[appId] = [normalized, needCastKeys]);
-}
-// use function string name to check type constructors
-// so that it works across vms / iframes.
-function getType(ctor) {
- const match = ctor && ctor.toString().match(/^\s*function (\w+)/);
- return match ? match[1] : '';
-}
-function isSameType(a, b) {
- return getType(a) === getType(b);
-}
-function getTypeIndex(type, expectedTypes) {
- if (isArray(expectedTypes)) {
- for (let i = 0, len = expectedTypes.length; i < len; i++) {
- if (isSameType(expectedTypes[i], type)) {
- return i;
- }
- }
- }
- else if (isFunction(expectedTypes)) {
- return isSameType(expectedTypes, type) ? 0 : -1;
- }
- return -1;
-}
-/**
- * dev only
- */
-function validateProps(props, instance) {
- const rawValues = toRaw(props);
- const options = instance.propsOptions[0];
- for (const key in options) {
- let opt = options[key];
- if (opt == null)
- continue;
- validateProp(key, rawValues[key], opt, !hasOwn(rawValues, key));
- }
+ };
}
-/**
- * dev only
- */
-function validatePropName(key) {
- if (key[0] !== '$') {
- return true;
- }
- else if ((process.env.NODE_ENV !== 'production')) {
- warn(`Invalid prop name: "${key}" is a reserved property.`);
- }
- return false;
+// this.$watch
+function instanceWatch(source, cb, options) {
+ const publicThis = this.proxy;
+ const getter = isString(source)
+ ? () => publicThis[source]
+ : source.bind(publicThis);
+ return doWatch(getter, cb.bind(publicThis), options, this);
}
-/**
- * dev only
- */
-function validateProp(name, value, prop, isAbsent) {
- const { type, required, validator } = prop;
- // required!
- if (required && isAbsent) {
- warn('Missing required prop: "' + name + '"');
- return;
- }
- // missing but optional
- if (value == null && !prop.required) {
- return;
- }
- // type check
- if (type != null && type !== true) {
- let isValid = false;
- const types = isArray(type) ? type : [type];
- const expectedTypes = [];
- // value is valid as long as one of the specified types match
- for (let i = 0; i < types.length && !isValid; i++) {
- const { valid, expectedType } = assertType(value, types[i]);
- expectedTypes.push(expectedType || '');
- isValid = valid;
- }
- if (!isValid) {
- warn(getInvalidTypeMessage(name, value, expectedTypes));
- return;
- }
+function traverse(value, seen = new Set()) {
+ if (!isObject(value) || seen.has(value)) {
+ return value;
}
- // custom validator
- if (validator && !validator(value)) {
- warn('Invalid prop: custom validator check failed for prop "' + name + '".');
+ seen.add(value);
+ if (isRef(value)) {
+ traverse(value.value, seen);
}
-}
-const isSimpleType = /*#__PURE__*/ makeMap('String,Number,Boolean,Function,Symbol');
-/**
- * dev only
- */
-function assertType(value, type) {
- let valid;
- const expectedType = getType(type);
- if (isSimpleType(expectedType)) {
- const t = typeof value;
- valid = t === expectedType.toLowerCase();
- // for primitive wrapper objects
- if (!valid && t === 'object') {
- valid = value instanceof type;
+ else if (isArray(value)) {
+ for (let i = 0; i < value.length; i++) {
+ traverse(value[i], seen);
}
}
- else if (expectedType === 'Object') {
- valid = isObject(value);
- }
- else if (expectedType === 'Array') {
- valid = isArray(value);
- }
- else {
- valid = value instanceof type;
- }
- return {
- valid,
- expectedType
- };
-}
-/**
- * dev only
- */
-function getInvalidTypeMessage(name, value, expectedTypes) {
- let message = `Invalid prop: type check failed for prop "${name}".` +
- ` Expected ${expectedTypes.map(capitalize).join(', ')}`;
- const expectedType = expectedTypes[0];
- const receivedType = toRawType(value);
- const expectedValue = styleValue(value, expectedType);
- const receivedValue = styleValue(value, receivedType);
- // check if we need to specify expected value
- if (expectedTypes.length === 1 &&
- isExplicable(expectedType) &&
- !isBoolean(expectedType, receivedType)) {
- message += ` with value ${expectedValue}`;
- }
- message += `, got ${receivedType} `;
- // check if we need to specify received value
- if (isExplicable(receivedType)) {
- message += `with value ${receivedValue}.`;
- }
- return message;
-}
-/**
- * dev only
- */
-function styleValue(value, type) {
- if (type === 'String') {
- return `"${value}"`;
- }
- else if (type === 'Number') {
- return `${Number(value)}`;
+ else if (isSet(value) || isMap(value)) {
+ value.forEach((v) => {
+ traverse(v, seen);
+ });
}
else {
- return `${value}`;
- }
-}
-/**
- * dev only
- */
-function isExplicable(type) {
- const explicitTypes = ['string', 'number', 'boolean'];
- return explicitTypes.some(elem => type.toLowerCase() === elem);
-}
-/**
- * dev only
- */
-function isBoolean(...args) {
- return args.some(elem => elem.toLowerCase() === 'boolean');
-}
-
-function injectHook(type, hook, target = currentInstance, prepend = false) {
- if (target) {
- const hooks = target[type] || (target[type] = []);
- // cache the error handling wrapper for injected hooks so the same hook
- // can be properly deduped by the scheduler. "__weh" stands for "with error
- // handling".
- const wrappedHook = hook.__weh ||
- (hook.__weh = (...args) => {
- if (target.isUnmounted) {
- return;
- }
- // disable tracking inside all lifecycle hooks
- // since they can potentially be called inside effects.
- pauseTracking();
- // Set currentInstance during hook invocation.
- // This assumes the hook does not synchronously trigger other hooks, which
- // can only be false when the user does something really funky.
- setCurrentInstance(target);
- const res = callWithAsyncErrorHandling(hook, target, type, args);
- setCurrentInstance(null);
- resetTracking();
- return res;
- });
- if (prepend) {
- hooks.unshift(wrappedHook);
- }
- else {
- hooks.push(wrappedHook);
+ for (const key in value) {
+ traverse(value[key], seen);
}
- return wrappedHook;
}
- else if ((process.env.NODE_ENV !== 'production')) {
- const apiName = `on${capitalize(ErrorTypeStrings[type].replace(/ hook$/, ''))}`;
- warn(`${apiName} is called when there is no active component instance to be ` +
- `associated with. ` +
- `Lifecycle injection APIs can only be used during execution of setup().` +
- ( ` If you are using async setup(), make sure to register lifecycle ` +
- `hooks before the first await statement.`
- ));
- }
-}
-const createHook = (lifecycle) => (hook, target = currentInstance) =>
-// post-create lifecycle registrations are noops during SSR
-!isInSSRComponentSetup && injectHook(lifecycle, hook, target);
-const onBeforeMount = createHook("bm" /* BEFORE_MOUNT */);
-const onMounted = createHook("m" /* MOUNTED */);
-const onBeforeUpdate = createHook("bu" /* BEFORE_UPDATE */);
-const onUpdated = createHook("u" /* UPDATED */);
-const onBeforeUnmount = createHook("bum" /* BEFORE_UNMOUNT */);
-const onUnmounted = createHook("um" /* UNMOUNTED */);
-const onRenderTriggered = createHook("rtg" /* RENDER_TRIGGERED */);
-const onRenderTracked = createHook("rtc" /* RENDER_TRACKED */);
-const onErrorCaptured = (hook, target = currentInstance) => {
- injectHook("ec" /* ERROR_CAPTURED */, hook, target);
-};
+ return value;
+}
function useTransitionState() {
const state = {
@@ -4215,6 +3766,11 @@ function createAppAPI(render, hydrate) {
if (__VUE_OPTIONS_API__) {
if (!context.mixins.includes(mixin)) {
context.mixins.push(mixin);
+ // global mixin with props/emits de-optimizes props/emits
+ // normalization caching.
+ if (mixin.props || mixin.emits) {
+ context.deopt = true;
+ }
}
else if ((process.env.NODE_ENV !== 'production')) {
warn('Mixin has already been applied to target app' +
@@ -5037,7 +4593,7 @@ function baseCreateRenderer(options, createHydrationFns) {
if (dirs) {
invokeDirectiveHook(n2, n1, parentComponent, 'beforeUpdate');
}
- if ((process.env.NODE_ENV !== 'production') && isHmrUpdating) {
+ if ((process.env.NODE_ENV !== 'production') && (true ) && isHmrUpdating) {
// HMR updated, force full diff
patchFlag = 0;
optimized = false;
@@ -5100,7 +4656,10 @@ function baseCreateRenderer(options, createHydrationFns) {
const areChildrenSVG = isSVG && n2.type !== 'foreignObject';
if (dynamicChildren) {
patchBlockChildren(n1.dynamicChildren, dynamicChildren, el, parentComponent, parentSuspense, areChildrenSVG);
- if ((process.env.NODE_ENV !== 'production') && parentComponent && parentComponent.type.__hmrId) {
+ if ((process.env.NODE_ENV !== 'production') &&
+ (true ) &&
+ parentComponent &&
+ parentComponent.type.__hmrId) {
traverseStaticChildren(n1, n2);
}
}
@@ -5141,6 +4700,7 @@ function baseCreateRenderer(options, createHydrationFns) {
const patchProps = (el, vnode, oldProps, newProps, parentComponent, parentSuspense, isSVG) => {
if (oldProps !== newProps) {
for (const key in newProps) {
+ // empty string is not valid prop
if (isReservedProp(key))
continue;
const next = newProps[key];
@@ -5224,7 +4784,7 @@ function baseCreateRenderer(options, createHydrationFns) {
};
const mountComponent = (initialVNode, container, anchor, parentComponent, parentSuspense, isSVG, optimized) => {
const instance = (initialVNode.component = createComponentInstance(initialVNode, parentComponent, parentSuspense));
- if ((process.env.NODE_ENV !== 'production') && instance.type.__hmrId) {
+ if ((process.env.NODE_ENV !== 'production') && (true ) && instance.type.__hmrId) {
registerHMR(instance);
}
if ((process.env.NODE_ENV !== 'production')) {
@@ -5369,12 +4929,12 @@ function baseCreateRenderer(options, createHydrationFns) {
pushWarningContext(next || instance.vnode);
}
if (next) {
+ next.el = vnode.el;
updateComponentPreRender(instance, next, optimized);
}
else {
next = vnode;
}
- next.el = vnode.el;
// beforeUpdate hook
if (bu) {
invokeArrayFns(bu);
@@ -5393,11 +4953,6 @@ function baseCreateRenderer(options, createHydrationFns) {
}
const prevTree = instance.subTree;
instance.subTree = nextTree;
- // reset refs
- // only needed if previous patch had refs
- if (instance.refs !== EMPTY_OBJ) {
- instance.refs = {};
- }
if ((process.env.NODE_ENV !== 'production')) {
startMeasure(instance, `patch`);
}
@@ -5515,7 +5070,7 @@ function baseCreateRenderer(options, createHydrationFns) {
}
if (oldLength > newLength) {
// remove old
- unmountChildren(c1, parentComponent, parentSuspense, true, commonLength);
+ unmountChildren(c1, parentComponent, parentSuspense, true, false, commonLength);
}
else {
// mount new
@@ -5752,7 +5307,7 @@ function baseCreateRenderer(options, createHydrationFns) {
hostInsert(el, container, anchor);
}
};
- const unmount = (vnode, parentComponent, parentSuspense, doRemove = false) => {
+ const unmount = (vnode, parentComponent, parentSuspense, doRemove = false, optimized = false) => {
const { type, props, ref, children, dynamicChildren, shapeFlag, patchFlag, dirs } = vnode;
// unset ref
if (ref != null && parentComponent) {
@@ -5783,13 +5338,17 @@ function baseCreateRenderer(options, createHydrationFns) {
(type !== Fragment ||
(patchFlag > 0 && patchFlag & 64 /* STABLE_FRAGMENT */))) {
// fast path for block nodes: only need to unmount dynamic children.
- unmountChildren(dynamicChildren, parentComponent, parentSuspense);
+ unmountChildren(dynamicChildren, parentComponent, parentSuspense, false, true);
}
- else if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
+ else if ((type === Fragment &&
+ (patchFlag & 128 /* KEYED_FRAGMENT */ ||
+ patchFlag & 256 /* UNKEYED_FRAGMENT */)) ||
+ (!optimized && shapeFlag & 16 /* ARRAY_CHILDREN */)) {
unmountChildren(children, parentComponent, parentSuspense);
}
- // an unmounted teleport should always remove its children
- if (shapeFlag & 64 /* TELEPORT */) {
+ // an unmounted teleport should always remove its children if not disabled
+ if (shapeFlag & 64 /* TELEPORT */ &&
+ (doRemove || !isTeleportDisabled(vnode.props))) {
vnode.type.remove(vnode, internals);
}
if (doRemove) {
@@ -5848,7 +5407,7 @@ function baseCreateRenderer(options, createHydrationFns) {
hostRemove(end);
};
const unmountComponent = (instance, parentSuspense, doRemove) => {
- if ((process.env.NODE_ENV !== 'production') && instance.type.__hmrId) {
+ if ((process.env.NODE_ENV !== 'production') && (true ) && instance.type.__hmrId) {
unregisterHMR(instance);
}
const { bum, effects, update, subTree, um } = instance;
@@ -5893,9 +5452,9 @@ function baseCreateRenderer(options, createHydrationFns) {
devtoolsComponentRemoved(instance);
}
};
- const unmountChildren = (children, parentComponent, parentSuspense, doRemove = false, start = 0) => {
+ const unmountChildren = (children, parentComponent, parentSuspense, doRemove = false, optimized = false, start = 0) => {
for (let i = start; i < children.length; i++) {
- unmount(children[i], parentComponent, parentSuspense, doRemove);
+ unmount(children[i], parentComponent, parentSuspense, doRemove, optimized);
}
};
const getNextHostNode = vnode => {
@@ -5907,39 +5466,6 @@ function baseCreateRenderer(options, createHydrationFns) {
}
return hostNextSibling((vnode.anchor || vnode.el));
};
- /**
- * #1156
- * When a component is HMR-enabled, we need to make sure that all static nodes
- * inside a block also inherit the DOM element from the previous tree so that
- * HMR updates (which are full updates) can retrieve the element for patching.
- *
- * #2080
- * Inside keyed `template` fragment static children, if a fragment is moved,
- * the children will always moved so that need inherit el form previous nodes
- * to ensure correct moved position.
- */
- const traverseStaticChildren = (n1, n2, shallow = false) => {
- const ch1 = n1.children;
- const ch2 = n2.children;
- if (isArray(ch1) && isArray(ch2)) {
- for (let i = 0; i < ch1.length; i++) {
- // this is only called in the optimized path so array children are
- // guaranteed to be vnodes
- const c1 = ch1[i];
- const c2 = (ch2[i] = cloneIfMounted(ch2[i]));
- if (c2.shapeFlag & 1 /* ELEMENT */ && !c2.dynamicChildren) {
- if (c2.patchFlag <= 0 || c2.patchFlag === 32 /* HYDRATE_EVENTS */) {
- c2.el = c1.el;
- }
- if (!shallow)
- traverseStaticChildren(c1, c2);
- }
- if ((process.env.NODE_ENV !== 'production') && c2.type === Comment) {
- c2.el = c1.el;
- }
- }
- }
- };
const render = (vnode, container) => {
if (vnode == null) {
if (container._vnode) {
@@ -5981,6 +5507,42 @@ function invokeVNodeHook(hook, instance, vnode, prevVNode = null) {
prevVNode
]);
}
+/**
+ * #1156
+ * When a component is HMR-enabled, we need to make sure that all static nodes
+ * inside a block also inherit the DOM element from the previous tree so that
+ * HMR updates (which are full updates) can retrieve the element for patching.
+ *
+ * #2080
+ * Inside keyed `template` fragment static children, if a fragment is moved,
+ * the children will always moved so that need inherit el form previous nodes
+ * to ensure correct moved position.
+ */
+function traverseStaticChildren(n1, n2, shallow = false) {
+ const ch1 = n1.children;
+ const ch2 = n2.children;
+ if (isArray(ch1) && isArray(ch2)) {
+ for (let i = 0; i < ch1.length; i++) {
+ // this is only called in the optimized path so array children are
+ // guaranteed to be vnodes
+ const c1 = ch1[i];
+ let c2 = ch2[i];
+ if (c2.shapeFlag & 1 /* ELEMENT */ && !c2.dynamicChildren) {
+ if (c2.patchFlag <= 0 || c2.patchFlag === 32 /* HYDRATE_EVENTS */) {
+ c2 = ch2[i] = cloneIfMounted(ch2[i]);
+ c2.el = c1.el;
+ }
+ if (!shallow)
+ traverseStaticChildren(c1, c2);
+ }
+ // also inherit for comment nodes, but not placeholders (e.g. v-if which
+ // would have received .el during block patch)
+ if ((process.env.NODE_ENV !== 'production') && c2.type === Comment && !c2.el) {
+ c2.el = c1.el;
+ }
+ }
+ }
+}
// https://en.wikipedia.org/wiki/Longest_increasing_subsequence
function getSequence(arr) {
const p = arr.slice();
@@ -6024,210 +5586,667 @@ function getSequence(arr) {
return result;
}
-// Simple effect.
-function watchEffect(effect, options) {
- return doWatch(effect, null, options);
-}
-// initial value for watchers to trigger on undefined initial values
-const INITIAL_WATCHER_VALUE = {};
-// implementation
-function watch(source, cb, options) {
- if ((process.env.NODE_ENV !== 'production') && !isFunction(cb)) {
- warn(`\`watch(fn, options?)\` signature has been moved to a separate API. ` +
- `Use \`watchEffect(fn, options?)\` instead. \`watch\` now only ` +
- `supports \`watch(source, cb, options?) signature.`);
- }
- return doWatch(source, cb, options);
-}
-function doWatch(source, cb, { immediate, deep, flush, onTrack, onTrigger } = EMPTY_OBJ, instance = currentInstance) {
- if ((process.env.NODE_ENV !== 'production') && !cb) {
- if (immediate !== undefined) {
- warn(`watch() "immediate" option is only respected when using the ` +
- `watch(source, callback, options?) signature.`);
+const isTeleport = (type) => type.__isTeleport;
+const isTeleportDisabled = (props) => props && (props.disabled || props.disabled === '');
+const resolveTarget = (props, select) => {
+ const targetSelector = props && props.to;
+ if (isString(targetSelector)) {
+ if (!select) {
+ (process.env.NODE_ENV !== 'production') &&
+ warn(`Current renderer does not support string target for Teleports. ` +
+ `(missing querySelector renderer option)`);
+ return null;
}
- if (deep !== undefined) {
- warn(`watch() "deep" option is only respected when using the ` +
- `watch(source, callback, options?) signature.`);
+ else {
+ const target = select(targetSelector);
+ if (!target) {
+ (process.env.NODE_ENV !== 'production') &&
+ warn(`Failed to locate Teleport target with selector "${targetSelector}". ` +
+ `Note the target element must exist before the component is mounted - ` +
+ `i.e. the target cannot be rendered by the component itself, and ` +
+ `ideally should be outside of the entire Vue component tree.`);
+ }
+ return target;
}
}
- const warnInvalidSource = (s) => {
- warn(`Invalid watch source: `, s, `A watch source can only be a getter/effect function, a ref, ` +
- `a reactive object, or an array of these types.`);
- };
- let getter;
- const isRefSource = isRef(source);
- if (isRefSource) {
- getter = () => source.value;
- }
- else if (isReactive(source)) {
- getter = () => source;
- deep = true;
+ else {
+ if ((process.env.NODE_ENV !== 'production') && !targetSelector && !isTeleportDisabled(props)) {
+ warn(`Invalid Teleport target: ${targetSelector}`);
+ }
+ return targetSelector;
}
- else if (isArray(source)) {
- getter = () => source.map(s => {
- if (isRef(s)) {
- return s.value;
+};
+const TeleportImpl = {
+ __isTeleport: true,
+ process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized, internals) {
+ const { mc: mountChildren, pc: patchChildren, pbc: patchBlockChildren, o: { insert, querySelector, createText, createComment } } = internals;
+ const disabled = isTeleportDisabled(n2.props);
+ const { shapeFlag, children } = n2;
+ if (n1 == null) {
+ // insert anchors in the main view
+ const placeholder = (n2.el = (process.env.NODE_ENV !== 'production')
+ ? createComment('teleport start')
+ : createText(''));
+ const mainAnchor = (n2.anchor = (process.env.NODE_ENV !== 'production')
+ ? createComment('teleport end')
+ : createText(''));
+ insert(placeholder, container, anchor);
+ insert(mainAnchor, container, anchor);
+ const target = (n2.target = resolveTarget(n2.props, querySelector));
+ const targetAnchor = (n2.targetAnchor = createText(''));
+ if (target) {
+ insert(targetAnchor, target);
}
- else if (isReactive(s)) {
- return traverse(s);
+ else if ((process.env.NODE_ENV !== 'production') && !disabled) {
+ warn('Invalid Teleport target on mount:', target, `(${typeof target})`);
}
- else if (isFunction(s)) {
- return callWithErrorHandling(s, instance, 2 /* WATCH_GETTER */);
+ const mount = (container, anchor) => {
+ // Teleport *always* has Array children. This is enforced in both the
+ // compiler and vnode children normalization.
+ if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
+ mountChildren(children, container, anchor, parentComponent, parentSuspense, isSVG, optimized);
+ }
+ };
+ if (disabled) {
+ mount(container, mainAnchor);
}
- else {
- (process.env.NODE_ENV !== 'production') && warnInvalidSource(s);
+ else if (target) {
+ mount(target, targetAnchor);
}
- });
- }
- else if (isFunction(source)) {
- if (cb) {
- // getter with cb
- getter = () => callWithErrorHandling(source, instance, 2 /* WATCH_GETTER */);
}
else {
- // no cb -> simple effect
- getter = () => {
- if (instance && instance.isUnmounted) {
- return;
+ // update content
+ n2.el = n1.el;
+ const mainAnchor = (n2.anchor = n1.anchor);
+ const target = (n2.target = n1.target);
+ const targetAnchor = (n2.targetAnchor = n1.targetAnchor);
+ const wasDisabled = isTeleportDisabled(n1.props);
+ const currentContainer = wasDisabled ? container : target;
+ const currentAnchor = wasDisabled ? mainAnchor : targetAnchor;
+ if (n2.dynamicChildren) {
+ // fast path when the teleport happens to be a block root
+ patchBlockChildren(n1.dynamicChildren, n2.dynamicChildren, currentContainer, parentComponent, parentSuspense, isSVG);
+ // even in block tree mode we need to make sure all root-level nodes
+ // in the teleport inherit previous DOM references so that they can
+ // be moved in future patches.
+ traverseStaticChildren(n1, n2, true);
+ }
+ else if (!optimized) {
+ patchChildren(n1, n2, currentContainer, currentAnchor, parentComponent, parentSuspense, isSVG);
+ }
+ if (disabled) {
+ if (!wasDisabled) {
+ // enabled -> disabled
+ // move into main container
+ moveTeleport(n2, container, mainAnchor, internals, 1 /* TOGGLE */);
}
- if (cleanup) {
- cleanup();
+ }
+ else {
+ // target changed
+ if ((n2.props && n2.props.to) !== (n1.props && n1.props.to)) {
+ const nextTarget = (n2.target = resolveTarget(n2.props, querySelector));
+ if (nextTarget) {
+ moveTeleport(n2, nextTarget, null, internals, 0 /* TARGET_CHANGE */);
+ }
+ else if ((process.env.NODE_ENV !== 'production')) {
+ warn('Invalid Teleport target on update:', target, `(${typeof target})`);
+ }
}
- return callWithErrorHandling(source, instance, 3 /* WATCH_CALLBACK */, [onInvalidate]);
- };
+ else if (wasDisabled) {
+ // disabled -> enabled
+ // move into teleport target
+ moveTeleport(n2, target, targetAnchor, internals, 1 /* TOGGLE */);
+ }
+ }
+ }
+ },
+ remove(vnode, { r: remove, o: { remove: hostRemove } }) {
+ const { shapeFlag, children, anchor } = vnode;
+ hostRemove(anchor);
+ if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
+ for (let i = 0; i < children.length; i++) {
+ remove(children[i]);
+ }
+ }
+ },
+ move: moveTeleport,
+ hydrate: hydrateTeleport
+};
+function moveTeleport(vnode, container, parentAnchor, { o: { insert }, m: move }, moveType = 2 /* REORDER */) {
+ // move target anchor if this is a target change.
+ if (moveType === 0 /* TARGET_CHANGE */) {
+ insert(vnode.targetAnchor, container, parentAnchor);
+ }
+ const { el, anchor, shapeFlag, children, props } = vnode;
+ const isReorder = moveType === 2 /* REORDER */;
+ // move main view anchor if this is a re-order.
+ if (isReorder) {
+ insert(el, container, parentAnchor);
+ }
+ // if this is a re-order and teleport is enabled (content is in target)
+ // do not move children. So the opposite is: only move children if this
+ // is not a reorder, or the teleport is disabled
+ if (!isReorder || isTeleportDisabled(props)) {
+ // Teleport has either Array children or no children.
+ if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
+ for (let i = 0; i < children.length; i++) {
+ move(children[i], container, parentAnchor, 2 /* REORDER */);
+ }
+ }
+ }
+ // move main view anchor if this is a re-order.
+ if (isReorder) {
+ insert(anchor, container, parentAnchor);
+ }
+}
+function hydrateTeleport(node, vnode, parentComponent, parentSuspense, optimized, { o: { nextSibling, parentNode, querySelector } }, hydrateChildren) {
+ const target = (vnode.target = resolveTarget(vnode.props, querySelector));
+ if (target) {
+ // if multiple teleports rendered to the same target element, we need to
+ // pick up from where the last teleport finished instead of the first node
+ const targetNode = target._lpa || target.firstChild;
+ if (vnode.shapeFlag & 16 /* ARRAY_CHILDREN */) {
+ if (isTeleportDisabled(vnode.props)) {
+ vnode.anchor = hydrateChildren(nextSibling(node), vnode, parentNode(node), parentComponent, parentSuspense, optimized);
+ vnode.targetAnchor = targetNode;
+ }
+ else {
+ vnode.anchor = nextSibling(node);
+ vnode.targetAnchor = hydrateChildren(targetNode, vnode, target, parentComponent, parentSuspense, optimized);
+ }
+ target._lpa =
+ vnode.targetAnchor && nextSibling(vnode.targetAnchor);
}
}
+ return vnode.anchor && nextSibling(vnode.anchor);
+}
+// Force-casted public typing for h and TSX props inference
+const Teleport = TeleportImpl;
+
+const COMPONENTS = 'components';
+const DIRECTIVES = 'directives';
+/**
+ * @private
+ */
+function resolveComponent(name) {
+ return resolveAsset(COMPONENTS, name) || name;
+}
+const NULL_DYNAMIC_COMPONENT = Symbol();
+/**
+ * @private
+ */
+function resolveDynamicComponent(component) {
+ if (isString(component)) {
+ return resolveAsset(COMPONENTS, component, false) || component;
+ }
+ else {
+ // invalid types will fallthrough to createVNode and raise warning
+ return (component || NULL_DYNAMIC_COMPONENT);
+ }
+}
+/**
+ * @private
+ */
+function resolveDirective(name) {
+ return resolveAsset(DIRECTIVES, name);
+}
+// implementation
+function resolveAsset(type, name, warnMissing = true) {
+ const instance = currentRenderingInstance || currentInstance;
+ if (instance) {
+ const Component = instance.type;
+ // self name has highest priority
+ if (type === COMPONENTS) {
+ const selfName = Component.displayName || Component.name;
+ if (selfName &&
+ (selfName === name ||
+ selfName === camelize(name) ||
+ selfName === capitalize(camelize(name)))) {
+ return Component;
+ }
+ }
+ const res =
+ // local registration
+ // check instance[type] first for components with mixin or extends.
+ resolve(instance[type] || Component[type], name) ||
+ // global registration
+ resolve(instance.appContext[type], name);
+ if ((process.env.NODE_ENV !== 'production') && warnMissing && !res) {
+ warn(`Failed to resolve ${type.slice(0, -1)}: ${name}`);
+ }
+ return res;
+ }
+ else if ((process.env.NODE_ENV !== 'production')) {
+ warn(`resolve${capitalize(type.slice(0, -1))} ` +
+ `can only be used in render() or setup().`);
+ }
+}
+function resolve(registry, name) {
+ return (registry &&
+ (registry[name] ||
+ registry[camelize(name)] ||
+ registry[capitalize(camelize(name))]));
+}
+
+const Fragment = Symbol((process.env.NODE_ENV !== 'production') ? 'Fragment' : undefined);
+const Text = Symbol((process.env.NODE_ENV !== 'production') ? 'Text' : undefined);
+const Comment = Symbol((process.env.NODE_ENV !== 'production') ? 'Comment' : undefined);
+const Static = Symbol((process.env.NODE_ENV !== 'production') ? 'Static' : undefined);
+// Since v-if and v-for are the two possible ways node structure can dynamically
+// change, once we consider v-if branches and each v-for fragment a block, we
+// can divide a template into nested blocks, and within each block the node
+// structure would be stable. This allows us to skip most children diffing
+// and only worry about the dynamic nodes (indicated by patch flags).
+const blockStack = [];
+let currentBlock = null;
+/**
+ * Open a block.
+ * This must be called before `createBlock`. It cannot be part of `createBlock`
+ * because the children of the block are evaluated before `createBlock` itself
+ * is called. The generated code typically looks like this:
+ *
+ * ```js
+ * function render() {
+ * return (openBlock(),createBlock('div', null, [...]))
+ * }
+ * ```
+ * disableTracking is true when creating a v-for fragment block, since a v-for
+ * fragment always diffs its children.
+ *
+ * @private
+ */
+function openBlock(disableTracking = false) {
+ blockStack.push((currentBlock = disableTracking ? null : []));
+}
+function closeBlock() {
+ blockStack.pop();
+ currentBlock = blockStack[blockStack.length - 1] || null;
+}
+// Whether we should be tracking dynamic child nodes inside a block.
+// Only tracks when this value is > 0
+// We are not using a simple boolean because this value may need to be
+// incremented/decremented by nested usage of v-once (see below)
+let shouldTrack$1 = 1;
+/**
+ * Block tracking sometimes needs to be disabled, for example during the
+ * creation of a tree that needs to be cached by v-once. The compiler generates
+ * code like this:
+ *
+ * ``` js
+ * _cache[1] || (
+ * setBlockTracking(-1),
+ * _cache[1] = createVNode(...),
+ * setBlockTracking(1),
+ * _cache[1]
+ * )
+ * ```
+ *
+ * @private
+ */
+function setBlockTracking(value) {
+ shouldTrack$1 += value;
+}
+/**
+ * Create a block root vnode. Takes the same exact arguments as `createVNode`.
+ * A block root keeps track of dynamic nodes within the block in the
+ * `dynamicChildren` array.
+ *
+ * @private
+ */
+function createBlock(type, props, children, patchFlag, dynamicProps) {
+ const vnode = createVNode(type, props, children, patchFlag, dynamicProps, true /* isBlock: prevent a block from tracking itself */);
+ // save current block children on the block vnode
+ vnode.dynamicChildren = currentBlock || EMPTY_ARR;
+ // close block
+ closeBlock();
+ // a block is always going to be patched, so track it as a child of its
+ // parent block
+ if (shouldTrack$1 > 0 && currentBlock) {
+ currentBlock.push(vnode);
+ }
+ return vnode;
+}
+function isVNode(value) {
+ return value ? value.__v_isVNode === true : false;
+}
+function isSameVNodeType(n1, n2) {
+ if ((process.env.NODE_ENV !== 'production') &&
+ n2.shapeFlag & 6 /* COMPONENT */ &&
+ hmrDirtyComponents.has(n2.type)) {
+ // HMR only: if the component has been hot-updated, force a reload.
+ return false;
+ }
+ return n1.type === n2.type && n1.key === n2.key;
+}
+let vnodeArgsTransformer;
+/**
+ * Internal API for registering an arguments transform for createVNode
+ * used for creating stubs in the test-utils
+ * It is *internal* but needs to be exposed for test-utils to pick up proper
+ * typings
+ */
+function transformVNodeArgs(transformer) {
+ vnodeArgsTransformer = transformer;
+}
+const createVNodeWithArgsTransform = (...args) => {
+ return _createVNode(...(vnodeArgsTransformer
+ ? vnodeArgsTransformer(args, currentRenderingInstance)
+ : args));
+};
+const InternalObjectKey = `__vInternal`;
+const normalizeKey = ({ key }) => key != null ? key : null;
+const normalizeRef = ({ ref }) => {
+ return (ref != null
+ ? isArray(ref)
+ ? ref
+ : { i: currentRenderingInstance, r: ref }
+ : null);
+};
+const createVNode = ((process.env.NODE_ENV !== 'production')
+ ? createVNodeWithArgsTransform
+ : _createVNode);
+function _createVNode(type, props = null, children = null, patchFlag = 0, dynamicProps = null, isBlockNode = false) {
+ if (!type || type === NULL_DYNAMIC_COMPONENT) {
+ if ((process.env.NODE_ENV !== 'production') && !type) {
+ warn(`Invalid vnode type when creating vnode: ${type}.`);
+ }
+ type = Comment;
+ }
+ if (isVNode(type)) {
+ // createVNode receiving an existing vnode. This happens in cases like
+ //
+ // #2078 make sure to merge refs during the clone instead of overwriting it
+ const cloned = cloneVNode(type, props, true /* mergeRef: true */);
+ if (children) {
+ normalizeChildren(cloned, children);
+ }
+ return cloned;
+ }
+ // class component normalization.
+ if (isClassComponent(type)) {
+ type = type.__vccOpts;
+ }
+ // class & style normalization.
+ if (props) {
+ // for reactive or proxy objects, we need to clone it to enable mutation.
+ if (isProxy(props) || InternalObjectKey in props) {
+ props = extend({}, props);
+ }
+ let { class: klass, style } = props;
+ if (klass && !isString(klass)) {
+ props.class = normalizeClass(klass);
+ }
+ if (isObject(style)) {
+ // reactive state objects need to be cloned since they are likely to be
+ // mutated
+ if (isProxy(style) && !isArray(style)) {
+ style = extend({}, style);
+ }
+ props.style = normalizeStyle(style);
+ }
+ }
+ // encode the vnode type information into a bitmap
+ const shapeFlag = isString(type)
+ ? 1 /* ELEMENT */
+ : isSuspense(type)
+ ? 128 /* SUSPENSE */
+ : isTeleport(type)
+ ? 64 /* TELEPORT */
+ : isObject(type)
+ ? 4 /* STATEFUL_COMPONENT */
+ : isFunction(type)
+ ? 2 /* FUNCTIONAL_COMPONENT */
+ : 0;
+ if ((process.env.NODE_ENV !== 'production') && shapeFlag & 4 /* STATEFUL_COMPONENT */ && isProxy(type)) {
+ type = toRaw(type);
+ warn(`Vue received a Component which was made a reactive object. This can ` +
+ `lead to unnecessary performance overhead, and should be avoided by ` +
+ `marking the component with \`markRaw\` or using \`shallowRef\` ` +
+ `instead of \`ref\`.`, `\nComponent that was made reactive: `, type);
+ }
+ const vnode = {
+ __v_isVNode: true,
+ ["__v_skip" /* SKIP */]: true,
+ type,
+ props,
+ key: props && normalizeKey(props),
+ ref: props && normalizeRef(props),
+ scopeId: currentScopeId,
+ children: null,
+ component: null,
+ suspense: null,
+ ssContent: null,
+ ssFallback: null,
+ dirs: null,
+ transition: null,
+ el: null,
+ anchor: null,
+ target: null,
+ targetAnchor: null,
+ staticCount: 0,
+ shapeFlag,
+ patchFlag,
+ dynamicProps,
+ dynamicChildren: null,
+ appContext: null
+ };
+ // validate key
+ if ((process.env.NODE_ENV !== 'production') && vnode.key !== vnode.key) {
+ warn(`VNode created with invalid key (NaN). VNode type:`, vnode.type);
+ }
+ normalizeChildren(vnode, children);
+ // normalize suspense children
+ if ( shapeFlag & 128 /* SUSPENSE */) {
+ const { content, fallback } = normalizeSuspenseChildren(vnode);
+ vnode.ssContent = content;
+ vnode.ssFallback = fallback;
+ }
+ if (shouldTrack$1 > 0 &&
+ // avoid a block node from tracking itself
+ !isBlockNode &&
+ // has current parent block
+ currentBlock &&
+ // presence of a patch flag indicates this node needs patching on updates.
+ // component nodes also should always be patched, because even if the
+ // component doesn't need to update, it needs to persist the instance on to
+ // the next vnode so that it can be properly unmounted later.
+ (patchFlag > 0 || shapeFlag & 6 /* COMPONENT */) &&
+ // the EVENTS flag is only for hydration and if it is the only flag, the
+ // vnode should not be considered dynamic due to handler caching.
+ patchFlag !== 32 /* HYDRATE_EVENTS */) {
+ currentBlock.push(vnode);
+ }
+ return vnode;
+}
+function cloneVNode(vnode, extraProps, mergeRef = false) {
+ // This is intentionally NOT using spread or extend to avoid the runtime
+ // key enumeration cost.
+ const { props, ref, patchFlag } = vnode;
+ const mergedProps = extraProps ? mergeProps(props || {}, extraProps) : props;
+ return {
+ __v_isVNode: true,
+ ["__v_skip" /* SKIP */]: true,
+ type: vnode.type,
+ props: mergedProps,
+ key: mergedProps && normalizeKey(mergedProps),
+ ref: extraProps && extraProps.ref
+ ? // #2078 in the case of
+ // if the vnode itself already has a ref, cloneVNode will need to merge
+ // the refs so the single vnode can be set on multiple refs
+ mergeRef && ref
+ ? isArray(ref)
+ ? ref.concat(normalizeRef(extraProps))
+ : [ref, normalizeRef(extraProps)]
+ : normalizeRef(extraProps)
+ : ref,
+ scopeId: vnode.scopeId,
+ children: vnode.children,
+ target: vnode.target,
+ targetAnchor: vnode.targetAnchor,
+ staticCount: vnode.staticCount,
+ shapeFlag: vnode.shapeFlag,
+ // if the vnode is cloned with extra props, we can no longer assume its
+ // existing patch flag to be reliable and need to add the FULL_PROPS flag.
+ // note: perserve flag for fragments since they use the flag for children
+ // fast paths only.
+ patchFlag: extraProps && vnode.type !== Fragment
+ ? patchFlag === -1 // hoisted node
+ ? 16 /* FULL_PROPS */
+ : patchFlag | 16 /* FULL_PROPS */
+ : patchFlag,
+ dynamicProps: vnode.dynamicProps,
+ dynamicChildren: vnode.dynamicChildren,
+ appContext: vnode.appContext,
+ dirs: vnode.dirs,
+ transition: vnode.transition,
+ // These should technically only be non-null on mounted VNodes. However,
+ // they *should* be copied for kept-alive vnodes. So we just always copy
+ // them since them being non-null during a mount doesn't affect the logic as
+ // they will simply be overwritten.
+ component: vnode.component,
+ suspense: vnode.suspense,
+ ssContent: vnode.ssContent && cloneVNode(vnode.ssContent),
+ ssFallback: vnode.ssFallback && cloneVNode(vnode.ssFallback),
+ el: vnode.el,
+ anchor: vnode.anchor
+ };
+}
+/**
+ * @private
+ */
+function createTextVNode(text = ' ', flag = 0) {
+ return createVNode(Text, null, text, flag);
+}
+/**
+ * @private
+ */
+function createStaticVNode(content, numberOfNodes) {
+ // A static vnode can contain multiple stringified elements, and the number
+ // of elements is necessary for hydration.
+ const vnode = createVNode(Static, null, content);
+ vnode.staticCount = numberOfNodes;
+ return vnode;
+}
+/**
+ * @private
+ */
+function createCommentVNode(text = '',
+// when used as the v-else branch, the comment node must be created as a
+// block to ensure correct updates.
+asBlock = false) {
+ return asBlock
+ ? (openBlock(), createBlock(Comment, null, text))
+ : createVNode(Comment, null, text);
+}
+function normalizeVNode(child) {
+ if (child == null || typeof child === 'boolean') {
+ // empty placeholder
+ return createVNode(Comment);
+ }
+ else if (isArray(child)) {
+ // fragment
+ return createVNode(Fragment, null, child);
+ }
+ else if (typeof child === 'object') {
+ // already vnode, this should be the most common since compiled templates
+ // always produce all-vnode children arrays
+ return child.el === null ? child : cloneVNode(child);
+ }
else {
- getter = NOOP;
- (process.env.NODE_ENV !== 'production') && warnInvalidSource(source);
+ // strings and numbers
+ return createVNode(Text, null, String(child));
}
- if (cb && deep) {
- const baseGetter = getter;
- getter = () => traverse(baseGetter());
+}
+// optimized normalization for template-compiled render fns
+function cloneIfMounted(child) {
+ return child.el === null ? child : cloneVNode(child);
+}
+function normalizeChildren(vnode, children) {
+ let type = 0;
+ const { shapeFlag } = vnode;
+ if (children == null) {
+ children = null;
}
- let cleanup;
- const onInvalidate = (fn) => {
- cleanup = runner.options.onStop = () => {
- callWithErrorHandling(fn, instance, 4 /* WATCH_CLEANUP */);
- };
- };
- let oldValue = isArray(source) ? [] : INITIAL_WATCHER_VALUE;
- const job = () => {
- if (!runner.active) {
+ else if (isArray(children)) {
+ type = 16 /* ARRAY_CHILDREN */;
+ }
+ else if (typeof children === 'object') {
+ if (shapeFlag & 1 /* ELEMENT */ || shapeFlag & 64 /* TELEPORT */) {
+ // Normalize slot to plain children for plain element and Teleport
+ const slot = children.default;
+ if (slot) {
+ // _c marker is added by withCtx() indicating this is a compiled slot
+ slot._c && setCompiledSlotRendering(1);
+ normalizeChildren(vnode, slot());
+ slot._c && setCompiledSlotRendering(-1);
+ }
return;
}
- if (cb) {
- // watch(source, cb)
- const newValue = runner();
- if (deep || isRefSource || hasChanged(newValue, oldValue)) {
- // cleanup before running cb again
- if (cleanup) {
- cleanup();
+ else {
+ type = 32 /* SLOTS_CHILDREN */;
+ const slotFlag = children._;
+ if (!slotFlag && !(InternalObjectKey in children)) {
+ children._ctx = currentRenderingInstance;
+ }
+ else if (slotFlag === 3 /* FORWARDED */ && currentRenderingInstance) {
+ // a child component receives forwarded slots from the parent.
+ // its slot type is determined by its parent's slot type.
+ if (currentRenderingInstance.vnode.patchFlag & 1024 /* DYNAMIC_SLOTS */) {
+ children._ = 2 /* DYNAMIC */;
+ vnode.patchFlag |= 1024 /* DYNAMIC_SLOTS */;
+ }
+ else {
+ children._ = 1 /* STABLE */;
}
- callWithAsyncErrorHandling(cb, instance, 3 /* WATCH_CALLBACK */, [
- newValue,
- // pass undefined as the old value when it's changed for the first time
- oldValue === INITIAL_WATCHER_VALUE ? undefined : oldValue,
- onInvalidate
- ]);
- oldValue = newValue;
}
}
- else {
- // watchEffect
- runner();
- }
- };
- // important: mark the job as a watcher callback so that scheduler knows it
- // it is allowed to self-trigger (#1727)
- job.allowRecurse = !!cb;
- let scheduler;
- if (flush === 'sync') {
- scheduler = job;
}
- else if (flush === 'post') {
- scheduler = () => queuePostRenderEffect(job, instance && instance.suspense);
+ else if (isFunction(children)) {
+ children = { default: children, _ctx: currentRenderingInstance };
+ type = 32 /* SLOTS_CHILDREN */;
}
else {
- // default: 'pre'
- scheduler = () => {
- if (!instance || instance.isMounted) {
- queuePreFlushCb(job);
- }
- else {
- // with 'pre' option, the first call must happen before
- // the component is mounted so it is called synchronously.
- job();
- }
- };
- }
- const runner = effect(getter, {
- lazy: true,
- onTrack,
- onTrigger,
- scheduler
- });
- recordInstanceBoundEffect(runner);
- // initial run
- if (cb) {
- if (immediate) {
- job();
+ children = String(children);
+ // force teleport children to array so it can be moved around
+ if (shapeFlag & 64 /* TELEPORT */) {
+ type = 16 /* ARRAY_CHILDREN */;
+ children = [createTextVNode(children)];
}
else {
- oldValue = runner();
+ type = 8 /* TEXT_CHILDREN */;
}
}
- else if (flush === 'post') {
- queuePostRenderEffect(runner, instance && instance.suspense);
- }
- else {
- runner();
- }
- return () => {
- stop(runner);
- if (instance) {
- remove(instance.effects, runner);
- }
- };
-}
-// this.$watch
-function instanceWatch(source, cb, options) {
- const publicThis = this.proxy;
- const getter = isString(source)
- ? () => publicThis[source]
- : source.bind(publicThis);
- return doWatch(getter, cb.bind(publicThis), options, this);
+ vnode.children = children;
+ vnode.shapeFlag |= type;
}
-function traverse(value, seen = new Set()) {
- if (!isObject(value) || seen.has(value)) {
- return value;
- }
- seen.add(value);
- if (isRef(value)) {
- traverse(value.value, seen);
- }
- else if (isArray(value)) {
- for (let i = 0; i < value.length; i++) {
- traverse(value[i], seen);
- }
- }
- else if (isMap(value)) {
- value.forEach((_, key) => {
- // to register mutation dep for existing keys
- traverse(value.get(key), seen);
- });
- }
- else if (isSet(value)) {
- value.forEach(v => {
- traverse(v, seen);
- });
- }
- else {
- for (const key in value) {
- traverse(value[key], seen);
+function mergeProps(...args) {
+ const ret = extend({}, args[0]);
+ for (let i = 1; i < args.length; i++) {
+ const toMerge = args[i];
+ for (const key in toMerge) {
+ if (key === 'class') {
+ if (ret.class !== toMerge.class) {
+ ret.class = normalizeClass([ret.class, toMerge.class]);
+ }
+ }
+ else if (key === 'style') {
+ ret.style = normalizeStyle([ret.style, toMerge.style]);
+ }
+ else if (isOn(key)) {
+ const existing = ret[key];
+ const incoming = toMerge[key];
+ if (existing !== incoming) {
+ ret[key] = existing
+ ? [].concat(existing, toMerge[key])
+ : incoming;
+ }
+ }
+ else if (key !== '') {
+ ret[key] = toMerge[key];
+ }
}
}
- return value;
+ return ret;
}
function provide(key, value) {
@@ -6256,8 +6275,13 @@ function inject(key, defaultValue, treatDefaultAsFactory = false) {
// a functional component
const instance = currentInstance || currentRenderingInstance;
if (instance) {
- const provides = instance.provides;
- if (key in provides) {
+ // #2400
+ // to support `app.use` plugins,
+ // fallback to appContext's `provides` if the intance is at root
+ const provides = instance.parent == null
+ ? instance.vnode.appContext && instance.vnode.appContext.provides
+ : instance.parent.provides;
+ if (provides && key in provides) {
// TS doesn't allow symbol as index type
return provides[key];
}
@@ -6287,7 +6311,7 @@ function createDuplicateChecker() {
};
}
let isInBeforeCreate = false;
-function applyOptions(instance, options, deferredData = [], deferredWatch = [], asMixin = false) {
+function applyOptions(instance, options, deferredData = [], deferredWatch = [], deferredProvide = [], asMixin = false) {
const {
// composition
mixins, extends: extendsOptions,
@@ -6306,18 +6330,18 @@ function applyOptions(instance, options, deferredData = [], deferredWatch = [],
// applyOptions is called non-as-mixin once per instance
if (!asMixin) {
isInBeforeCreate = true;
- callSyncHook('beforeCreate', options, publicThis, globalMixins);
+ callSyncHook('beforeCreate', "bc" /* BEFORE_CREATE */, options, instance, globalMixins);
isInBeforeCreate = false;
// global mixins are applied first
- applyMixins(instance, globalMixins, deferredData, deferredWatch);
+ applyMixins(instance, globalMixins, deferredData, deferredWatch, deferredProvide);
}
// extending a base component...
if (extendsOptions) {
- applyOptions(instance, extendsOptions, deferredData, deferredWatch, true);
+ applyOptions(instance, extendsOptions, deferredData, deferredWatch, deferredProvide, true);
}
// local mixins
if (mixins) {
- applyMixins(instance, mixins, deferredData, deferredWatch);
+ applyMixins(instance, mixins, deferredData, deferredWatch, deferredProvide);
}
const checkDuplicateProperties = (process.env.NODE_ENV !== 'production') ? createDuplicateChecker() : null;
if ((process.env.NODE_ENV !== 'production')) {
@@ -6445,12 +6469,17 @@ function applyOptions(instance, options, deferredData = [], deferredWatch = [],
});
}
if (provideOptions) {
- const provides = isFunction(provideOptions)
- ? provideOptions.call(publicThis)
- : provideOptions;
- for (const key in provides) {
- provide(key, provides[key]);
- }
+ deferredProvide.push(provideOptions);
+ }
+ if (!asMixin && deferredProvide.length) {
+ deferredProvide.forEach(provideOptions => {
+ const provides = isFunction(provideOptions)
+ ? provideOptions.call(publicThis)
+ : provideOptions;
+ for (const key in provides) {
+ provide(key, provides[key]);
+ }
+ });
}
// asset options.
// To reduce memory usage, only components with mixins or extends will have
@@ -6467,7 +6496,7 @@ function applyOptions(instance, options, deferredData = [], deferredWatch = [],
}
// lifecycle options
if (!asMixin) {
- callSyncHook('created', options, publicThis, globalMixins);
+ callSyncHook('created', "c" /* CREATED */, options, instance, globalMixins);
}
if (beforeMount) {
onBeforeMount(beforeMount.bind(publicThis));
@@ -6509,44 +6538,44 @@ function applyOptions(instance, options, deferredData = [], deferredWatch = [],
onUnmounted(unmounted.bind(publicThis));
}
}
-function callSyncHook(name, options, ctx, globalMixins) {
- callHookFromMixins(name, globalMixins, ctx);
+function callSyncHook(name, type, options, instance, globalMixins) {
+ callHookFromMixins(name, type, globalMixins, instance);
const { extends: base, mixins } = options;
if (base) {
- callHookFromExtends(name, base, ctx);
+ callHookFromExtends(name, type, base, instance);
}
if (mixins) {
- callHookFromMixins(name, mixins, ctx);
+ callHookFromMixins(name, type, mixins, instance);
}
const selfHook = options[name];
if (selfHook) {
- selfHook.call(ctx);
+ callWithAsyncErrorHandling(selfHook.bind(instance.proxy), instance, type);
}
}
-function callHookFromExtends(name, base, ctx) {
+function callHookFromExtends(name, type, base, instance) {
if (base.extends) {
- callHookFromExtends(name, base.extends, ctx);
+ callHookFromExtends(name, type, base.extends, instance);
}
const baseHook = base[name];
if (baseHook) {
- baseHook.call(ctx);
+ callWithAsyncErrorHandling(baseHook.bind(instance.proxy), instance, type);
}
}
-function callHookFromMixins(name, mixins, ctx) {
+function callHookFromMixins(name, type, mixins, instance) {
for (let i = 0; i < mixins.length; i++) {
const chainedMixins = mixins[i].mixins;
if (chainedMixins) {
- callHookFromMixins(name, chainedMixins, ctx);
+ callHookFromMixins(name, type, chainedMixins, instance);
}
const fn = mixins[i][name];
if (fn) {
- fn.call(ctx);
+ callWithAsyncErrorHandling(fn.bind(instance.proxy), instance, type);
}
}
}
-function applyMixins(instance, mixins, deferredData, deferredWatch) {
+function applyMixins(instance, mixins, deferredData, deferredWatch, deferredProvide) {
for (let i = 0; i < mixins.length; i++) {
- applyOptions(instance, mixins[i], deferredData, deferredWatch, true);
+ applyOptions(instance, mixins[i], deferredData, deferredWatch, deferredProvide, true);
}
}
function resolveData(instance, dataFn, publicThis) {
@@ -6659,7 +6688,7 @@ const publicPropertiesMap = extend(Object.create(null), {
$emit: i => i.emit,
$options: i => (__VUE_OPTIONS_API__ ? resolveMergedOptions(i) : i.type),
$forceUpdate: i => () => queueJob(i.update),
- $nextTick: () => nextTick,
+ $nextTick: i => nextTick.bind(i.proxy),
$watch: i => (__VUE_OPTIONS_API__ ? instanceWatch.bind(i) : NOOP)
});
const PublicInstanceProxyHandlers = {
@@ -6669,6 +6698,10 @@ const PublicInstanceProxyHandlers = {
if (key === "__v_skip" /* SKIP */) {
return true;
}
+ // for internal formatters to know that this is a Vue instance
+ if ((process.env.NODE_ENV !== 'production') && key === '__isVue') {
+ return true;
+ }
// data / props / ctx
// This getter gets called for every property access on the render context
// during render and is a major hotspot. The most expensive part of this
@@ -7016,7 +7049,7 @@ function setupStatefulComponent(instance, isSSR) {
}
}
// 0. create render proxy property access cache
- instance.accessCache = {};
+ instance.accessCache = Object.create(null);
// 1. create public instance / render proxy
// also mark it raw so it's never observed
instance.proxy = new Proxy(instance.ctx, PublicInstanceProxyHandlers);
@@ -7387,6 +7420,195 @@ const useSSRContext = () => {
}
};
+function initCustomFormatter() {
+ if (!(process.env.NODE_ENV !== 'production') || !true) {
+ return;
+ }
+ const vueStyle = { style: 'color:#3ba776' };
+ const numberStyle = { style: 'color:#0b1bc9' };
+ const stringStyle = { style: 'color:#b62e24' };
+ const keywordStyle = { style: 'color:#9d288c' };
+ // custom formatter for Chrome
+ // https://www.mattzeunert.com/2016/02/19/custom-chrome-devtools-object-formatters.html
+ const formatter = {
+ header(obj) {
+ // TODO also format ComponentPublicInstance & ctx.slots/attrs in setup
+ if (!isObject(obj)) {
+ return null;
+ }
+ if (obj.__isVue) {
+ return ['div', vueStyle, `VueInstance`];
+ }
+ else if (isRef(obj)) {
+ return [
+ 'div',
+ {},
+ ['span', vueStyle, genRefFlag(obj)],
+ '<',
+ formatValue(obj.value),
+ `>`
+ ];
+ }
+ else if (isReactive(obj)) {
+ return [
+ 'div',
+ {},
+ ['span', vueStyle, 'Reactive'],
+ '<',
+ formatValue(obj),
+ `>${isReadonly(obj) ? ` (readonly)` : ``}`
+ ];
+ }
+ else if (isReadonly(obj)) {
+ return [
+ 'div',
+ {},
+ ['span', vueStyle, 'Readonly'],
+ '<',
+ formatValue(obj),
+ '>'
+ ];
+ }
+ return null;
+ },
+ hasBody(obj) {
+ return obj && obj.__isVue;
+ },
+ body(obj) {
+ if (obj && obj.__isVue) {
+ return [
+ 'div',
+ {},
+ ...formatInstance(obj.$)
+ ];
+ }
+ }
+ };
+ function formatInstance(instance) {
+ const blocks = [];
+ if (instance.type.props && instance.props) {
+ blocks.push(createInstanceBlock('props', toRaw(instance.props)));
+ }
+ if (instance.setupState !== EMPTY_OBJ) {
+ blocks.push(createInstanceBlock('setup', instance.setupState));
+ }
+ if (instance.data !== EMPTY_OBJ) {
+ blocks.push(createInstanceBlock('data', toRaw(instance.data)));
+ }
+ const computed = extractKeys(instance, 'computed');
+ if (computed) {
+ blocks.push(createInstanceBlock('computed', computed));
+ }
+ const injected = extractKeys(instance, 'inject');
+ if (injected) {
+ blocks.push(createInstanceBlock('injected', injected));
+ }
+ blocks.push([
+ 'div',
+ {},
+ [
+ 'span',
+ {
+ style: keywordStyle.style + ';opacity:0.66'
+ },
+ '$ (internal): '
+ ],
+ ['object', { object: instance }]
+ ]);
+ return blocks;
+ }
+ function createInstanceBlock(type, target) {
+ target = extend({}, target);
+ if (!Object.keys(target).length) {
+ return ['span', {}];
+ }
+ return [
+ 'div',
+ { style: 'line-height:1.25em;margin-bottom:0.6em' },
+ [
+ 'div',
+ {
+ style: 'color:#476582'
+ },
+ type
+ ],
+ [
+ 'div',
+ {
+ style: 'padding-left:1.25em'
+ },
+ ...Object.keys(target).map(key => {
+ return [
+ 'div',
+ {},
+ ['span', keywordStyle, key + ': '],
+ formatValue(target[key], false)
+ ];
+ })
+ ]
+ ];
+ }
+ function formatValue(v, asRaw = true) {
+ if (typeof v === 'number') {
+ return ['span', numberStyle, v];
+ }
+ else if (typeof v === 'string') {
+ return ['span', stringStyle, JSON.stringify(v)];
+ }
+ else if (typeof v === 'boolean') {
+ return ['span', keywordStyle, v];
+ }
+ else if (isObject(v)) {
+ return ['object', { object: asRaw ? toRaw(v) : v }];
+ }
+ else {
+ return ['span', stringStyle, String(v)];
+ }
+ }
+ function extractKeys(instance, type) {
+ const Comp = instance.type;
+ if (isFunction(Comp)) {
+ return;
+ }
+ const extracted = {};
+ for (const key in instance.ctx) {
+ if (isKeyOfType(Comp, key, type)) {
+ extracted[key] = instance.ctx[key];
+ }
+ }
+ return extracted;
+ }
+ function isKeyOfType(Comp, key, type) {
+ const opts = Comp[type];
+ if ((isArray(opts) && opts.includes(key)) ||
+ (isObject(opts) && key in opts)) {
+ return true;
+ }
+ if (Comp.extends && isKeyOfType(Comp.extends, key, type)) {
+ return true;
+ }
+ if (Comp.mixins && Comp.mixins.some(m => isKeyOfType(m, key, type))) {
+ return true;
+ }
+ }
+ function genRefFlag(v) {
+ if (v._shallow) {
+ return `ShallowRef`;
+ }
+ if (v.effect) {
+ return `ComputedRef`;
+ }
+ return `Ref`;
+ }
+ /* eslint-disable no-restricted-globals */
+ if (window.devtoolsFormatters) {
+ window.devtoolsFormatters.push(formatter);
+ }
+ else {
+ window.devtoolsFormatters = [formatter];
+ }
+}
+
/**
* Actual implementation
*/
@@ -7399,6 +7621,10 @@ function renderList(source, renderItem) {
}
}
else if (typeof source === 'number') {
+ if ((process.env.NODE_ENV !== 'production') && !Number.isInteger(source)) {
+ warn(`The v-for range expect an integer value but got ${source}.`);
+ return [];
+ }
ret = new Array(source);
for (let i = 0; i < source; i++) {
ret[i] = renderItem(i + 1, i);
@@ -7434,7 +7660,7 @@ function toHandlers(obj) {
return ret;
}
for (const key in obj) {
- ret[`on${capitalize(key)}`] = obj[key];
+ ret[toHandlerKey(key)] = obj[key];
}
return ret;
}
@@ -7461,7 +7687,7 @@ function createSlots(slots, dynamicSlots) {
}
// Core API ------------------------------------------------------------------
-const version = "3.0.0";
+const version = "3.0.2";
/**
* SSR utils for \@vue/server-renderer. Only exposed in cjs builds.
* @internal
@@ -7885,11 +8111,9 @@ function useCssVars(getter, scoped = false) {
const prefix = scoped && instance.type.__scopeId
? `${instance.type.__scopeId.replace(/^data-v-/, '')}-`
: ``;
- onMounted(() => {
- watchEffect(() => {
- setVarsOnVNode(instance.subTree, getter(instance.proxy), prefix);
- });
- });
+ const setVars = () => setVarsOnVNode(instance.subTree, getter(instance.proxy), prefix);
+ onMounted(() => watchEffect(setVars));
+ onUpdated(setVars);
}
function setVarsOnVNode(vnode, vars, prefix) {
if ( vnode.shapeFlag & 128 /* SUSPENSE */) {
@@ -8315,8 +8539,7 @@ function trigger$1(el, type) {
// We are exporting the v-model runtime directly as vnode hooks so that it can
// be tree-shaken in case v-model is never used.
const vModelText = {
- created(el, { value, modifiers: { lazy, trim, number } }, vnode) {
- el.value = value == null ? '' : value;
+ created(el, { modifiers: { lazy, trim, number } }, vnode) {
el._assign = getModelAssigner(vnode);
const castToNumber = number || el.type === 'number';
addEventListener(el, lazy ? 'change' : 'input', e => {
@@ -8346,8 +8569,15 @@ const vModelText = {
addEventListener(el, 'change', onCompositionEnd);
}
},
+ // set value on mounted so it's after min/max for type="range"
+ mounted(el, { value }) {
+ el.value = value == null ? '' : value;
+ },
beforeUpdate(el, { value, modifiers: { trim, number } }, vnode) {
el._assign = getModelAssigner(vnode);
+ // avoid clearing unresolved text. #2302
+ if (el.composing)
+ return;
if (document.activeElement === el) {
if (trim && el.value.trim() === value) {
return;
@@ -8384,13 +8614,11 @@ const vModelCheckbox = {
}
}
else if (isSet(modelValue)) {
- const found = modelValue.has(elementValue);
- if (checked && !found) {
- assign(modelValue.add(elementValue));
+ if (checked) {
+ modelValue.add(elementValue);
}
- else if (!checked && found) {
+ else {
modelValue.delete(elementValue);
- assign(modelValue);
}
}
else {
@@ -8409,7 +8637,7 @@ function setChecked(el, { value, oldValue }, vnode) {
el.checked = looseIndexOf(value, vnode.props.value) > -1;
}
else if (isSet(value)) {
- el.checked = looseHas(value, vnode.props.value);
+ el.checked = value.has(vnode.props.value);
}
else if (value !== oldValue) {
el.checked = looseEqual(value, getCheckboxValue(el, true));
@@ -8431,11 +8659,11 @@ const vModelRadio = {
}
};
const vModelSelect = {
- created(el, binding, vnode) {
+ created(el, { modifiers: { number } }, vnode) {
addEventListener(el, 'change', () => {
const selectedVal = Array.prototype.filter
.call(el.options, (o) => o.selected)
- .map(getValue);
+ .map((o) => number ? toNumber(getValue(o)) : getValue(o));
el._assign(el.multiple ? selectedVal : selectedVal[0]);
});
el._assign = getModelAssigner(vnode);
@@ -8468,7 +8696,7 @@ function setSelected(el, value) {
option.selected = looseIndexOf(value, optionValue) > -1;
}
else {
- option.selected = looseHas(value, optionValue);
+ option.selected = value.has(optionValue);
}
}
else {
@@ -8712,6 +8940,7 @@ function initDev() {
{
console.info(`You are running a development build of Vue.\n` +
`Make sure to use the production build (*.prod.js) when deploying for production.`);
+ initCustomFormatter();
}
}
@@ -8754,4 +8983,4 @@ const onNavigationBarSearchInputClicked = /*#__PURE__*/ createHook$1("onNavigati
const onNavigationBarSearchInputConfirmed = /*#__PURE__*/ createHook$1("onNavigationBarSearchInputConfirmed" /* ON_NAVIGATION_BAR_SEARCH_INPUT_CONFIRMED */);
const onNavigationBarSearchInputFocusChanged = /*#__PURE__*/ createHook$1("onNavigationBarSearchInputFocusChanged" /* ON_NAVIGATION_BAR_SEARCH_INPUT_FOCUS_CHANGED */);
-export { BaseTransition, Comment, Fragment, KeepAlive, Static, Suspense, Teleport, Text, Transition, TransitionGroup, callWithAsyncErrorHandling, callWithErrorHandling, cloneVNode, compile$1 as compile, computed$1 as computed, createApp, createBlock, createCommentVNode, createHook$1 as createHook, createHydrationRenderer, createRenderer, createSSRApp, createSlots, createStaticVNode, createTextVNode, createVNode, customRef, defineAsyncComponent, defineComponent, devtools, getCurrentInstance, getTransitionRawChildren, h, handleError, hydrate, inject, injectHook, isInSSRComponentSetup, isProxy, isReactive, isReadonly, isRef, isVNode, markRaw, mergeProps, nextTick, onActivated, onAddToFavorites, onBackPress, onBeforeMount, onBeforeUnmount, onBeforeUpdate, onDeactivated, onError, onErrorCaptured, onHide, onLaunch, onLoad, onMounted, onNavigationBarButtonTap, onNavigationBarSearchInputChanged, onNavigationBarSearchInputClicked, onNavigationBarSearchInputConfirmed, onNavigationBarSearchInputFocusChanged, onPageNotFound, onPageScroll, onPullDownRefresh, onReachBottom, onReady, onRenderTracked, onRenderTriggered, onResize, onShareAppMessage, onShareTimeline, onShow, onTabItemTap, onThemeChange, onUnhandledRejection, onUnload, onUnmounted, onUpdated, openBlock, popScopeId, provide, proxyRefs, pushScopeId, queuePostFlushCb, reactive, readonly, ref, registerRuntimeCompiler, render, renderList, renderSlot, resolveComponent, resolveDirective, resolveDynamicComponent, resolveTransitionHooks, setBlockTracking, setDevtoolsHook, setTransitionHooks, shallowReactive, shallowReadonly, shallowRef, ssrContextKey, ssrUtils, toHandlers, toRaw, toRef, toRefs, transformVNodeArgs, triggerRef, unref, useCssModule, useCssVars, useSSRContext, useTransitionState, vModelCheckbox, vModelDynamic, vModelRadio, vModelSelect, vModelText, vShow, version, warn, watch, watchEffect, withCtx, withDirectives, withKeys, withModifiers, withScopeId };
+export { BaseTransition, Comment, Fragment, KeepAlive, Static, Suspense, Teleport, Text, Transition, TransitionGroup, callWithAsyncErrorHandling, callWithErrorHandling, cloneVNode, compile$1 as compile, computed$1 as computed, createApp, createBlock, createCommentVNode, createHook$1 as createHook, createHydrationRenderer, createRenderer, createSSRApp, createSlots, createStaticVNode, createTextVNode, createVNode, customRef, defineAsyncComponent, defineComponent, devtools, getCurrentInstance, getTransitionRawChildren, h, handleError, hydrate, initCustomFormatter, inject, injectHook, isInSSRComponentSetup, isProxy, isReactive, isReadonly, isRef, isVNode, markRaw, mergeProps, nextTick, onActivated, onAddToFavorites, onBackPress, onBeforeMount, onBeforeUnmount, onBeforeUpdate, onDeactivated, onError, onErrorCaptured, onHide, onLaunch, onLoad, onMounted, onNavigationBarButtonTap, onNavigationBarSearchInputChanged, onNavigationBarSearchInputClicked, onNavigationBarSearchInputConfirmed, onNavigationBarSearchInputFocusChanged, onPageNotFound, onPageScroll, onPullDownRefresh, onReachBottom, onReady, onRenderTracked, onRenderTriggered, onResize, onShareAppMessage, onShareTimeline, onShow, onTabItemTap, onThemeChange, onUnhandledRejection, onUnload, onUnmounted, onUpdated, openBlock, popScopeId, provide, proxyRefs, pushScopeId, queuePostFlushCb, reactive, readonly, ref, registerRuntimeCompiler, render, renderList, renderSlot, resolveComponent, resolveDirective, resolveDynamicComponent, resolveTransitionHooks, setBlockTracking, setDevtoolsHook, setTransitionHooks, shallowReactive, shallowReadonly, shallowRef, ssrContextKey, ssrUtils, toHandlers, toRaw, toRef, toRefs, transformVNodeArgs, triggerRef, unref, useCssModule, useCssVars, useSSRContext, useTransitionState, vModelCheckbox, vModelDynamic, vModelRadio, vModelSelect, vModelText, vShow, version, warn, watch, watchEffect, withCtx, withDirectives, withKeys, withModifiers, withScopeId };
diff --git a/packages/uni-h5-vue/lib/vue.runtime.esm.js b/packages/uni-h5-vue/lib/vue.runtime.esm.js
index 0b5994187c9b079f0a9fdcdd9547a0c09bcf9389..3c12353a517f55f9b902b80bf5c4d438a71b740e 100644
--- a/packages/uni-h5-vue/lib/vue.runtime.esm.js
+++ b/packages/uni-h5-vue/lib/vue.runtime.esm.js
@@ -1,5 +1,5 @@
-import { EMPTY_OBJ, isArray, isMap, isIntegerKey, isSymbol, extend, hasOwn, isObject, hasChanged, capitalize, toRawType, def, isFunction, NOOP, isString, isPromise, hyphenate, isOn, isModelListener, toNumber, camelize, EMPTY_ARR, normalizeClass, normalizeStyle, isReservedProp, makeMap, remove, invokeArrayFns, NO, getGlobalThis, isSet, isGloballyWhitelisted, isSpecialBooleanAttr, looseIndexOf, looseHas, looseEqual, isHTMLTag, isSVGTag } from '@vue/shared';
-export { camelize, capitalize, toDisplayString } from '@vue/shared';
+import { EMPTY_OBJ, isArray, isMap, isIntegerKey, isSymbol, extend, hasOwn, isObject, hasChanged, capitalize, toRawType, def, isFunction, NOOP, isString, isPromise, toHandlerKey, toNumber, hyphenate, camelize, isOn, isModelListener, isReservedProp, EMPTY_ARR, makeMap, remove, isSet, invokeArrayFns, NO, getGlobalThis, normalizeClass, normalizeStyle, isGloballyWhitelisted, isSpecialBooleanAttr, looseIndexOf, looseEqual, isHTMLTag, isSVGTag } from '@vue/shared';
+export { camelize, capitalize, toDisplayString, toHandlerKey } from '@vue/shared';
const targetMap = new WeakMap();
const effectStack = [];
@@ -50,6 +50,7 @@ function createReactiveEffect(fn, options) {
}
};
effect.id = uid++;
+ effect.allowRecurse = !!options.allowRecurse;
effect._isEffect = true;
effect.active = true;
effect.raw = fn;
@@ -115,7 +116,7 @@ function trigger(target, type, key, newValue, oldValue, oldTarget) {
const add = (effectsToAdd) => {
if (effectsToAdd) {
effectsToAdd.forEach(effect => {
- if (effect !== activeEffect || effect.options.allowRecurse) {
+ if (effect !== activeEffect || effect.allowRecurse) {
effects.add(effect);
}
});
@@ -220,7 +221,7 @@ const arrayInstrumentations = {};
arrayInstrumentations[key] = function (...args) {
pauseTracking();
const res = method.apply(this, args);
- enableTracking();
+ resetTracking();
return res;
};
});
@@ -241,8 +242,7 @@ function createGetter(isReadonly = false, shallow = false) {
return Reflect.get(arrayInstrumentations, key, receiver);
}
const res = Reflect.get(target, key, receiver);
- const keyIsSymbol = isSymbol(key);
- if (keyIsSymbol
+ if (isSymbol(key)
? builtInSymbols.has(key)
: key === `__proto__` || key === `__v_isRef`) {
return res;
@@ -312,7 +312,7 @@ function has(target, key) {
return result;
}
function ownKeys(target) {
- track(target, "iterate" /* ITERATE */, ITERATE_KEY);
+ track(target, "iterate" /* ITERATE */, isArray(target) ? 'length' : ITERATE_KEY);
return Reflect.ownKeys(target);
}
const mutableHandlers = {
@@ -595,7 +595,7 @@ function checkIdentityKeys(target, has, key) {
if (rawKey !== key && has.call(target, rawKey)) {
const type = toRawType(target);
console.warn(`Reactive ${type} contains both the raw and reactive ` +
- `versions of the same object${type === `Map` ? `as keys` : ``}, ` +
+ `versions of the same object${type === `Map` ? ` as keys` : ``}, ` +
`which can lead to inconsistencies. ` +
`Avoid differentiating between the raw and reactive versions ` +
`of an object and only use the reactive version if possible.`);
@@ -730,7 +730,7 @@ function createRef(rawValue, shallow = false) {
return new RefImpl(rawValue, shallow);
}
function triggerRef(ref) {
- trigger(ref, "set" /* SET */, 'value', (process.env.NODE_ENV !== 'production') ? ref.value : void 0);
+ trigger(toRaw(ref), "set" /* SET */, 'value', (process.env.NODE_ENV !== 'production') ? ref.value : void 0);
}
function unref(ref) {
return isRef(ref) ? ref.value : ref;
@@ -1028,7 +1028,7 @@ function handleError(err, instance, type, throwInDev = true) {
const errorCapturedHooks = cur.ec;
if (errorCapturedHooks) {
for (let i = 0; i < errorCapturedHooks.length; i++) {
- if (errorCapturedHooks[i](err, exposedInstance, errorInfo)) {
+ if (errorCapturedHooks[i](err, exposedInstance, errorInfo) === false) {
return;
}
}
@@ -1084,7 +1084,7 @@ let currentPreFlushParentJob = null;
const RECURSION_LIMIT = 100;
function nextTick(fn) {
const p = currentFlushPromise || resolvedPromise;
- return fn ? p.then(fn) : p;
+ return fn ? p.then(this ? fn.bind(this) : fn) : p;
}
function queueJob(job) {
// the dedupe search uses the startIndex argument of Array.includes()
@@ -1247,7 +1247,7 @@ const hmrDirtyComponents = new Set();
// it easier to be used in toolings like vue-loader
// Note: for a component to be eligible for HMR it also needs the __hmrId option
// to be set so that its instances can be registered / removed.
-if ((process.env.NODE_ENV !== 'production')) {
+if ((process.env.NODE_ENV !== 'production') && (true )) {
const globalObject = typeof global !== 'undefined'
? global
: typeof self !== 'undefined'
@@ -1391,21 +1391,21 @@ function devtoolsComponentEmit(component, event, params) {
devtools.emit("component:emit" /* COMPONENT_EMIT */, component.appContext.app, component, event, params);
}
-function emit(instance, event, ...args) {
+function emit(instance, event, ...rawArgs) {
const props = instance.vnode.props || EMPTY_OBJ;
if ((process.env.NODE_ENV !== 'production')) {
const { emitsOptions, propsOptions: [propsOptions] } = instance;
if (emitsOptions) {
if (!(event in emitsOptions)) {
- if (!propsOptions || !(`on` + capitalize(event) in propsOptions)) {
+ if (!propsOptions || !(toHandlerKey(event) in propsOptions)) {
warn(`Component emitted event "${event}" but it is neither declared in ` +
- `the emits option nor as an "on${capitalize(event)}" prop.`);
+ `the emits option nor as an "${toHandlerKey(event)}" prop.`);
}
}
else {
const validator = emitsOptions[event];
if (isFunction(validator)) {
- const isValid = validator(...args);
+ const isValid = validator(...rawArgs);
if (!isValid) {
warn(`Invalid event arguments: event validation failed for event "${event}".`);
}
@@ -1413,36 +1413,59 @@ function emit(instance, event, ...args) {
}
}
}
+ let args = rawArgs;
+ const isModelListener = event.startsWith('update:');
+ // for v-model update:xxx events, apply modifiers on args
+ const modelArg = isModelListener && event.slice(7);
+ if (modelArg && modelArg in props) {
+ const modifiersKey = `${modelArg === 'modelValue' ? 'model' : modelArg}Modifiers`;
+ const { number, trim } = props[modifiersKey] || EMPTY_OBJ;
+ if (trim) {
+ args = rawArgs.map(a => a.trim());
+ }
+ else if (number) {
+ args = rawArgs.map(toNumber);
+ }
+ }
if ((process.env.NODE_ENV !== 'production') || __VUE_PROD_DEVTOOLS__) {
devtoolsComponentEmit(instance, event, args);
}
- let handlerName = `on${capitalize(event)}`;
+ if ((process.env.NODE_ENV !== 'production')) {
+ const lowerCaseEvent = event.toLowerCase();
+ if (lowerCaseEvent !== event && props[toHandlerKey(lowerCaseEvent)]) {
+ warn(`Event "${lowerCaseEvent}" is emitted in component ` +
+ `${formatComponentName(instance, instance.type)} but the handler is registered for "${event}". ` +
+ `Note that HTML attributes are case-insensitive and you cannot use ` +
+ `v-on to listen to camelCase events when using in-DOM templates. ` +
+ `You should probably use "${hyphenate(event)}" instead of "${event}".`);
+ }
+ }
+ // convert handler name to camelCase. See issue #2249
+ let handlerName = toHandlerKey(camelize(event));
let handler = props[handlerName];
// for v-model update:xxx events, also trigger kebab-case equivalent
// for props passed via kebab-case
- if (!handler && event.startsWith('update:')) {
- handlerName = `on${capitalize(hyphenate(event))}`;
+ if (!handler && isModelListener) {
+ handlerName = toHandlerKey(hyphenate(event));
handler = props[handlerName];
}
- if (!handler) {
- handler = props[handlerName + `Once`];
+ if (handler) {
+ callWithAsyncErrorHandling(handler, instance, 6 /* COMPONENT_EVENT_HANDLER */, args);
+ }
+ const onceHandler = props[handlerName + `Once`];
+ if (onceHandler) {
if (!instance.emitted) {
(instance.emitted = {})[handlerName] = true;
}
else if (instance.emitted[handlerName]) {
return;
}
- }
- if (handler) {
- callWithAsyncErrorHandling(handler, instance, 6 /* COMPONENT_EVENT_HANDLER */, args);
+ callWithAsyncErrorHandling(onceHandler, instance, 6 /* COMPONENT_EVENT_HANDLER */, args);
}
}
function normalizeEmitsOptions(comp, appContext, asMixin = false) {
- const appId = appContext.app ? appContext.app._uid : -1;
- const cache = comp.__emits || (comp.__emits = {});
- const cached = cache[appId];
- if (cached !== undefined) {
- return cached;
+ if (!appContext.deopt && comp.__emits !== undefined) {
+ return comp.__emits;
}
const raw = comp.emits;
let normalized = {};
@@ -1464,7 +1487,7 @@ function normalizeEmitsOptions(comp, appContext, asMixin = false) {
}
}
if (!raw && !hasExtends) {
- return (cache[appId] = null);
+ return (comp.__emits = null);
}
if (isArray(raw)) {
raw.forEach(key => (normalized[key] = null));
@@ -1472,7 +1495,7 @@ function normalizeEmitsOptions(comp, appContext, asMixin = false) {
else {
extend(normalized, raw);
}
- return (cache[appId] = normalized);
+ return (comp.__emits = normalized);
}
// Check if an incoming prop key is a declared emit event listener.
// e.g. With `emits: { click: null }`, props named `onClick` and `onclick` are
@@ -1603,7 +1626,7 @@ function renderComponentRoot(instance) {
warn(`Runtime directive used on component with non-element root node. ` +
`The directives will not function as intended.`);
}
- root.dirs = vnode.dirs;
+ root.dirs = root.dirs ? root.dirs.concat(vnode.dirs) : vnode.dirs;
}
// inherit transition data
if (vnode.transition) {
@@ -1647,11 +1670,13 @@ const getChildRoot = (vnode) => {
const dynamicIndex = dynamicChildren ? dynamicChildren.indexOf(childRoot) : -1;
const setRoot = (updatedRoot) => {
rawChildren[index] = updatedRoot;
- if (dynamicIndex > -1) {
- dynamicChildren[dynamicIndex] = updatedRoot;
- }
- else if (dynamicChildren && updatedRoot.patchFlag > 0) {
- dynamicChildren.push(updatedRoot);
+ if (dynamicChildren) {
+ if (dynamicIndex > -1) {
+ dynamicChildren[dynamicIndex] = updatedRoot;
+ }
+ else if (updatedRoot.patchFlag > 0) {
+ vnode.dynamicChildren = [...dynamicChildren, updatedRoot];
+ }
}
};
return [normalizeVNode(childRoot), setRoot];
@@ -1789,7 +1814,7 @@ const SuspenseImpl = {
mountSuspense(n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized, rendererInternals);
}
else {
- patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, optimized, rendererInternals);
+ patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, rendererInternals);
}
},
hydrate: hydrateSuspense,
@@ -1803,13 +1828,13 @@ function mountSuspense(vnode, container, anchor, parentComponent, parentSuspense
const hiddenContainer = createElement('div');
const suspense = (vnode.suspense = createSuspenseBoundary(vnode, parentSuspense, parentComponent, container, hiddenContainer, anchor, isSVG, optimized, rendererInternals));
// start mounting the content subtree in an off-dom container
- patch(null, (suspense.pendingBranch = vnode.ssContent), hiddenContainer, null, parentComponent, suspense, isSVG, optimized);
+ patch(null, (suspense.pendingBranch = vnode.ssContent), hiddenContainer, null, parentComponent, suspense, isSVG);
// now check if we have encountered any async deps
if (suspense.deps > 0) {
// has async
// mount the fallback tree
patch(null, vnode.ssFallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context
- isSVG, optimized);
+ isSVG);
setActiveBranch(suspense, vnode.ssFallback);
}
else {
@@ -1817,7 +1842,7 @@ function mountSuspense(vnode, container, anchor, parentComponent, parentSuspense
suspense.resolve();
}
}
-function patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, optimized, { p: patch, um: unmount, o: { createElement } }) {
+function patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, { p: patch, um: unmount, o: { createElement } }) {
const suspense = (n2.suspense = n1.suspense);
suspense.vnode = n2;
n2.el = n1.el;
@@ -1828,13 +1853,13 @@ function patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, optimi
suspense.pendingBranch = newBranch;
if (isSameVNodeType(newBranch, pendingBranch)) {
// same root type but content may have changed.
- patch(pendingBranch, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, optimized);
+ patch(pendingBranch, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG);
if (suspense.deps <= 0) {
suspense.resolve();
}
else if (isInFallback) {
patch(activeBranch, newFallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context
- isSVG, optimized);
+ isSVG);
setActiveBranch(suspense, newFallback);
}
}
@@ -1860,25 +1885,25 @@ function patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, optimi
suspense.hiddenContainer = createElement('div');
if (isInFallback) {
// already in fallback state
- patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, optimized);
+ patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG);
if (suspense.deps <= 0) {
suspense.resolve();
}
else {
patch(activeBranch, newFallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context
- isSVG, optimized);
+ isSVG);
setActiveBranch(suspense, newFallback);
}
}
else if (activeBranch && isSameVNodeType(newBranch, activeBranch)) {
// toggled "back" to current active branch
- patch(activeBranch, newBranch, container, anchor, parentComponent, suspense, isSVG, optimized);
+ patch(activeBranch, newBranch, container, anchor, parentComponent, suspense, isSVG);
// force resolve
suspense.resolve(true);
}
else {
// switched to a 3rd branch
- patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, optimized);
+ patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG);
if (suspense.deps <= 0) {
suspense.resolve();
}
@@ -1888,7 +1913,7 @@ function patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, optimi
else {
if (activeBranch && isSameVNodeType(newBranch, activeBranch)) {
// root did not change, just normal patch
- patch(activeBranch, newBranch, container, anchor, parentComponent, suspense, isSVG, optimized);
+ patch(activeBranch, newBranch, container, anchor, parentComponent, suspense, isSVG);
setActiveBranch(suspense, newBranch);
}
else {
@@ -1901,7 +1926,7 @@ function patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, optimi
// mount pending branch in off-dom container
suspense.pendingBranch = newBranch;
suspense.pendingId++;
- patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, optimized);
+ patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG);
if (suspense.deps <= 0) {
// incoming branch has no async deps, resolve now.
suspense.resolve();
@@ -1937,7 +1962,6 @@ function createSuspenseBoundary(vnode, parent, parentComponent, container, hidde
parent,
parentComponent,
isSVG,
- optimized,
container,
hiddenContainer,
anchor,
@@ -2020,7 +2044,7 @@ function createSuspenseBoundary(vnode, parent, parentComponent, container, hidde
if (!suspense.pendingBranch) {
return;
}
- const { vnode, activeBranch, parentComponent, container, isSVG, optimized } = suspense;
+ const { vnode, activeBranch, parentComponent, container, isSVG } = suspense;
// invoke @fallback event
const onFallback = vnode.props && vnode.props.onFallback;
if (isFunction(onFallback)) {
@@ -2033,7 +2057,7 @@ function createSuspenseBoundary(vnode, parent, parentComponent, container, hidde
}
// mount the fallback tree
patch(null, fallbackVNode, container, anchor, parentComponent, null, // fallback tree will not have suspense context
- isSVG, optimized);
+ isSVG);
setActiveBranch(suspense, fallbackVNode);
};
const delayEnter = fallbackVNode.transition && fallbackVNode.transition.mode === 'out-in';
@@ -2277,1128 +2301,655 @@ function withScopeId(id) {
}));
}
-const isTeleport = (type) => type.__isTeleport;
-const isTeleportDisabled = (props) => props && (props.disabled || props.disabled === '');
-const resolveTarget = (props, select) => {
- const targetSelector = props && props.to;
- if (isString(targetSelector)) {
- if (!select) {
- (process.env.NODE_ENV !== 'production') &&
- warn(`Current renderer does not support string target for Teleports. ` +
- `(missing querySelector renderer option)`);
- return null;
- }
- else {
- const target = select(targetSelector);
- if (!target) {
- (process.env.NODE_ENV !== 'production') &&
- warn(`Failed to locate Teleport target with selector "${targetSelector}". ` +
- `Note the target element must exist before the component is mounted - ` +
- `i.e. the target cannot be rendered by the component itself, and ` +
- `ideally should be outside of the entire Vue component tree.`);
- }
- return target;
- }
+function initProps(instance, rawProps, isStateful, // result of bitwise flag comparison
+isSSR = false) {
+ const props = {};
+ const attrs = {};
+ def(attrs, InternalObjectKey, 1);
+ setFullProps(instance, rawProps, props, attrs);
+ // validation
+ if ((process.env.NODE_ENV !== 'production')) {
+ validateProps(props, instance);
}
- else {
- if ((process.env.NODE_ENV !== 'production') && !targetSelector && !isTeleportDisabled(props)) {
- warn(`Invalid Teleport target: ${targetSelector}`);
- }
- return targetSelector;
+ if (isStateful) {
+ // stateful
+ instance.props = isSSR ? props : shallowReactive(props);
}
-};
-const TeleportImpl = {
- __isTeleport: true,
- process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized, internals) {
- const { mc: mountChildren, pc: patchChildren, pbc: patchBlockChildren, o: { insert, querySelector, createText, createComment } } = internals;
- const disabled = isTeleportDisabled(n2.props);
- const { shapeFlag, children } = n2;
- if (n1 == null) {
- // insert anchors in the main view
- const placeholder = (n2.el = (process.env.NODE_ENV !== 'production')
- ? createComment('teleport start')
- : createText(''));
- const mainAnchor = (n2.anchor = (process.env.NODE_ENV !== 'production')
- ? createComment('teleport end')
- : createText(''));
- insert(placeholder, container, anchor);
- insert(mainAnchor, container, anchor);
- const target = (n2.target = resolveTarget(n2.props, querySelector));
- const targetAnchor = (n2.targetAnchor = createText(''));
- if (target) {
- insert(targetAnchor, target);
- }
- else if ((process.env.NODE_ENV !== 'production') && !disabled) {
- warn('Invalid Teleport target on mount:', target, `(${typeof target})`);
- }
- const mount = (container, anchor) => {
- // Teleport *always* has Array children. This is enforced in both the
- // compiler and vnode children normalization.
- if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
- mountChildren(children, container, anchor, parentComponent, parentSuspense, isSVG, optimized);
- }
- };
- if (disabled) {
- mount(container, mainAnchor);
- }
- else if (target) {
- mount(target, targetAnchor);
- }
+ else {
+ if (!instance.type.props) {
+ // functional w/ optional props, props === attrs
+ instance.props = attrs;
}
else {
- // update content
- n2.el = n1.el;
- const mainAnchor = (n2.anchor = n1.anchor);
- const target = (n2.target = n1.target);
- const targetAnchor = (n2.targetAnchor = n1.targetAnchor);
- const wasDisabled = isTeleportDisabled(n1.props);
- const currentContainer = wasDisabled ? container : target;
- const currentAnchor = wasDisabled ? mainAnchor : targetAnchor;
- if (n2.dynamicChildren) {
- // fast path when the teleport happens to be a block root
- patchBlockChildren(n1.dynamicChildren, n2.dynamicChildren, currentContainer, parentComponent, parentSuspense, isSVG);
- // even in block tree mode we need to make sure all root-level nodes
- // in the teleport inherit previous DOM references so that they can
- // be moved in future patches.
- if (n2.shapeFlag & 16 /* ARRAY_CHILDREN */) {
- const oldChildren = n1.children;
- const children = n2.children;
- for (let i = 0; i < children.length; i++) {
- // only inherit for non-patched nodes (i.e. static ones)
- if (!children[i].el) {
- children[i].el = oldChildren[i].el;
- }
+ // functional w/ declared props
+ instance.props = props;
+ }
+ }
+ instance.attrs = attrs;
+}
+function updateProps(instance, rawProps, rawPrevProps, optimized) {
+ const { props, attrs, vnode: { patchFlag } } = instance;
+ const rawCurrentProps = toRaw(props);
+ const [options] = instance.propsOptions;
+ if (
+ // always force full diff in dev
+ // - #1942 if hmr is enabled with sfc component
+ // - vite#872 non-sfc component used by sfc component
+ !((process.env.NODE_ENV !== 'production') &&
+ (instance.type.__hmrId ||
+ (instance.parent && instance.parent.type.__hmrId))) &&
+ (optimized || patchFlag > 0) &&
+ !(patchFlag & 16 /* FULL_PROPS */)) {
+ if (patchFlag & 8 /* PROPS */) {
+ // Compiler-generated props & no keys change, just set the updated
+ // the props.
+ const propsToUpdate = instance.vnode.dynamicProps;
+ for (let i = 0; i < propsToUpdate.length; i++) {
+ const key = propsToUpdate[i];
+ // PROPS flag guarantees rawProps to be non-null
+ const value = rawProps[key];
+ if (options) {
+ // attr / props separation was done on init and will be consistent
+ // in this code path, so just check if attrs have it.
+ if (hasOwn(attrs, key)) {
+ attrs[key] = value;
+ }
+ else {
+ const camelizedKey = camelize(key);
+ props[camelizedKey] = resolvePropValue(options, rawCurrentProps, camelizedKey, value, instance);
}
}
- }
- else if (!optimized) {
- patchChildren(n1, n2, currentContainer, currentAnchor, parentComponent, parentSuspense, isSVG);
- }
- if (disabled) {
- if (!wasDisabled) {
- // enabled -> disabled
- // move into main container
- moveTeleport(n2, container, mainAnchor, internals, 1 /* TOGGLE */);
+ else {
+ attrs[key] = value;
}
}
- else {
- // target changed
- if ((n2.props && n2.props.to) !== (n1.props && n1.props.to)) {
- const nextTarget = (n2.target = resolveTarget(n2.props, querySelector));
- if (nextTarget) {
- moveTeleport(n2, nextTarget, null, internals, 0 /* TARGET_CHANGE */);
- }
- else if ((process.env.NODE_ENV !== 'production')) {
- warn('Invalid Teleport target on update:', target, `(${typeof target})`);
+ }
+ }
+ else {
+ // full props update.
+ setFullProps(instance, rawProps, props, attrs);
+ // in case of dynamic props, check if we need to delete keys from
+ // the props object
+ let kebabKey;
+ for (const key in rawCurrentProps) {
+ if (!rawProps ||
+ // for camelCase
+ (!hasOwn(rawProps, key) &&
+ // it's possible the original props was passed in as kebab-case
+ // and converted to camelCase (#955)
+ ((kebabKey = hyphenate(key)) === key || !hasOwn(rawProps, kebabKey)))) {
+ if (options) {
+ if (rawPrevProps &&
+ // for camelCase
+ (rawPrevProps[key] !== undefined ||
+ // for kebab-case
+ rawPrevProps[kebabKey] !== undefined)) {
+ props[key] = resolvePropValue(options, rawProps || EMPTY_OBJ, key, undefined, instance);
}
}
- else if (wasDisabled) {
- // disabled -> enabled
- // move into teleport target
- moveTeleport(n2, target, targetAnchor, internals, 1 /* TOGGLE */);
+ else {
+ delete props[key];
}
}
}
- },
- remove(vnode, { r: remove, o: { remove: hostRemove } }) {
- const { shapeFlag, children, anchor } = vnode;
- hostRemove(anchor);
- if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
- for (let i = 0; i < children.length; i++) {
- remove(children[i]);
+ // in the case of functional component w/o props declaration, props and
+ // attrs point to the same object so it should already have been updated.
+ if (attrs !== rawCurrentProps) {
+ for (const key in attrs) {
+ if (!rawProps || !hasOwn(rawProps, key)) {
+ delete attrs[key];
+ }
}
}
- },
- move: moveTeleport,
- hydrate: hydrateTeleport
-};
-function moveTeleport(vnode, container, parentAnchor, { o: { insert }, m: move }, moveType = 2 /* REORDER */) {
- // move target anchor if this is a target change.
- if (moveType === 0 /* TARGET_CHANGE */) {
- insert(vnode.targetAnchor, container, parentAnchor);
}
- const { el, anchor, shapeFlag, children, props } = vnode;
- const isReorder = moveType === 2 /* REORDER */;
- // move main view anchor if this is a re-order.
- if (isReorder) {
- insert(el, container, parentAnchor);
+ // trigger updates for $attrs in case it's used in component slots
+ trigger(instance, "set" /* SET */, '$attrs');
+ if ((process.env.NODE_ENV !== 'production') && rawProps) {
+ validateProps(props, instance);
}
- // if this is a re-order and teleport is enabled (content is in target)
- // do not move children. So the opposite is: only move children if this
- // is not a reorder, or the teleport is disabled
- if (!isReorder || isTeleportDisabled(props)) {
- // Teleport has either Array children or no children.
- if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
- for (let i = 0; i < children.length; i++) {
- move(children[i], container, parentAnchor, 2 /* REORDER */);
+}
+function setFullProps(instance, rawProps, props, attrs) {
+ const [options, needCastKeys] = instance.propsOptions;
+ if (rawProps) {
+ for (const key in rawProps) {
+ const value = rawProps[key];
+ // key, ref are reserved and never passed down
+ if (isReservedProp(key)) {
+ continue;
+ }
+ // prop option names are camelized during normalization, so to support
+ // kebab -> camel conversion here we need to camelize the key.
+ let camelKey;
+ if (options && hasOwn(options, (camelKey = camelize(key)))) {
+ props[camelKey] = value;
+ }
+ else if (!isEmitListener(instance.emitsOptions, key)) {
+ // Any non-declared (either as a prop or an emitted event) props are put
+ // into a separate `attrs` object for spreading. Make sure to preserve
+ // original key casing
+ attrs[key] = value;
}
}
}
- // move main view anchor if this is a re-order.
- if (isReorder) {
- insert(anchor, container, parentAnchor);
+ if (needCastKeys) {
+ const rawCurrentProps = toRaw(props);
+ for (let i = 0; i < needCastKeys.length; i++) {
+ const key = needCastKeys[i];
+ props[key] = resolvePropValue(options, rawCurrentProps, key, rawCurrentProps[key], instance);
+ }
}
}
-function hydrateTeleport(node, vnode, parentComponent, parentSuspense, optimized, { o: { nextSibling, parentNode, querySelector } }, hydrateChildren) {
- const target = (vnode.target = resolveTarget(vnode.props, querySelector));
- if (target) {
- // if multiple teleports rendered to the same target element, we need to
- // pick up from where the last teleport finished instead of the first node
- const targetNode = target._lpa || target.firstChild;
- if (vnode.shapeFlag & 16 /* ARRAY_CHILDREN */) {
- if (isTeleportDisabled(vnode.props)) {
- vnode.anchor = hydrateChildren(nextSibling(node), vnode, parentNode(node), parentComponent, parentSuspense, optimized);
- vnode.targetAnchor = targetNode;
+function resolvePropValue(options, props, key, value, instance) {
+ const opt = options[key];
+ if (opt != null) {
+ const hasDefault = hasOwn(opt, 'default');
+ // default values
+ if (hasDefault && value === undefined) {
+ const defaultValue = opt.default;
+ if (opt.type !== Function && isFunction(defaultValue)) {
+ setCurrentInstance(instance);
+ value = defaultValue(props);
+ setCurrentInstance(null);
}
else {
- vnode.anchor = nextSibling(node);
- vnode.targetAnchor = hydrateChildren(targetNode, vnode, target, parentComponent, parentSuspense, optimized);
+ value = defaultValue;
+ }
+ }
+ // boolean casting
+ if (opt[0 /* shouldCast */]) {
+ if (!hasOwn(props, key) && !hasDefault) {
+ value = false;
+ }
+ else if (opt[1 /* shouldCastTrue */] &&
+ (value === '' || value === hyphenate(key))) {
+ value = true;
}
- target._lpa =
- vnode.targetAnchor && nextSibling(vnode.targetAnchor);
}
}
- return vnode.anchor && nextSibling(vnode.anchor);
-}
-// Force-casted public typing for h and TSX props inference
-const Teleport = TeleportImpl;
-
-const COMPONENTS = 'components';
-const DIRECTIVES = 'directives';
-/**
- * @private
- */
-function resolveComponent(name) {
- return resolveAsset(COMPONENTS, name) || name;
+ return value;
}
-const NULL_DYNAMIC_COMPONENT = Symbol();
-/**
- * @private
- */
-function resolveDynamicComponent(component) {
- if (isString(component)) {
- return resolveAsset(COMPONENTS, component, false) || component;
+function normalizePropsOptions(comp, appContext, asMixin = false) {
+ if (!appContext.deopt && comp.__props) {
+ return comp.__props;
}
- else {
- // invalid types will fallthrough to createVNode and raise warning
- return (component || NULL_DYNAMIC_COMPONENT);
+ const raw = comp.props;
+ const normalized = {};
+ const needCastKeys = [];
+ // apply mixin/extends props
+ let hasExtends = false;
+ if (__VUE_OPTIONS_API__ && !isFunction(comp)) {
+ const extendProps = (raw) => {
+ hasExtends = true;
+ const [props, keys] = normalizePropsOptions(raw, appContext, true);
+ extend(normalized, props);
+ if (keys)
+ needCastKeys.push(...keys);
+ };
+ if (!asMixin && appContext.mixins.length) {
+ appContext.mixins.forEach(extendProps);
+ }
+ if (comp.extends) {
+ extendProps(comp.extends);
+ }
+ if (comp.mixins) {
+ comp.mixins.forEach(extendProps);
+ }
}
-}
-/**
- * @private
- */
-function resolveDirective(name) {
- return resolveAsset(DIRECTIVES, name);
-}
-// implementation
-function resolveAsset(type, name, warnMissing = true) {
- const instance = currentRenderingInstance || currentInstance;
- if (instance) {
- const Component = instance.type;
- // self name has highest priority
- if (type === COMPONENTS) {
- const selfName = Component.displayName || Component.name;
- if (selfName &&
- (selfName === name ||
- selfName === camelize(name) ||
- selfName === capitalize(camelize(name)))) {
- return Component;
+ if (!raw && !hasExtends) {
+ return (comp.__props = EMPTY_ARR);
+ }
+ if (isArray(raw)) {
+ for (let i = 0; i < raw.length; i++) {
+ if ((process.env.NODE_ENV !== 'production') && !isString(raw[i])) {
+ warn(`props must be strings when using array syntax.`, raw[i]);
+ }
+ const normalizedKey = camelize(raw[i]);
+ if (validatePropName(normalizedKey)) {
+ normalized[normalizedKey] = EMPTY_OBJ;
}
}
- const res =
- // local registration
- // check instance[type] first for components with mixin or extends.
- resolve(instance[type] || Component[type], name) ||
- // global registration
- resolve(instance.appContext[type], name);
- if ((process.env.NODE_ENV !== 'production') && warnMissing && !res) {
- warn(`Failed to resolve ${type.slice(0, -1)}: ${name}`);
+ }
+ else if (raw) {
+ if ((process.env.NODE_ENV !== 'production') && !isObject(raw)) {
+ warn(`invalid props options`, raw);
}
- return res;
+ for (const key in raw) {
+ const normalizedKey = camelize(key);
+ if (validatePropName(normalizedKey)) {
+ const opt = raw[key];
+ const prop = (normalized[normalizedKey] =
+ isArray(opt) || isFunction(opt) ? { type: opt } : opt);
+ if (prop) {
+ const booleanIndex = getTypeIndex(Boolean, prop.type);
+ const stringIndex = getTypeIndex(String, prop.type);
+ prop[0 /* shouldCast */] = booleanIndex > -1;
+ prop[1 /* shouldCastTrue */] =
+ stringIndex < 0 || booleanIndex < stringIndex;
+ // if the prop needs boolean casting or default value
+ if (booleanIndex > -1 || hasOwn(prop, 'default')) {
+ needCastKeys.push(normalizedKey);
+ }
+ }
+ }
+ }
+ }
+ return (comp.__props = [normalized, needCastKeys]);
+}
+function validatePropName(key) {
+ if (key[0] !== '$') {
+ return true;
}
else if ((process.env.NODE_ENV !== 'production')) {
- warn(`resolve${capitalize(type.slice(0, -1))} ` +
- `can only be used in render() or setup().`);
+ warn(`Invalid prop name: "${key}" is a reserved property.`);
}
+ return false;
}
-function resolve(registry, name) {
- return (registry &&
- (registry[name] ||
- registry[camelize(name)] ||
- registry[capitalize(camelize(name))]));
-}
-
-const Fragment = Symbol((process.env.NODE_ENV !== 'production') ? 'Fragment' : undefined);
-const Text = Symbol((process.env.NODE_ENV !== 'production') ? 'Text' : undefined);
-const Comment = Symbol((process.env.NODE_ENV !== 'production') ? 'Comment' : undefined);
-const Static = Symbol((process.env.NODE_ENV !== 'production') ? 'Static' : undefined);
-// Since v-if and v-for are the two possible ways node structure can dynamically
-// change, once we consider v-if branches and each v-for fragment a block, we
-// can divide a template into nested blocks, and within each block the node
-// structure would be stable. This allows us to skip most children diffing
-// and only worry about the dynamic nodes (indicated by patch flags).
-const blockStack = [];
-let currentBlock = null;
-/**
- * Open a block.
- * This must be called before `createBlock`. It cannot be part of `createBlock`
- * because the children of the block are evaluated before `createBlock` itself
- * is called. The generated code typically looks like this:
- *
- * ```js
- * function render() {
- * return (openBlock(),createBlock('div', null, [...]))
- * }
- * ```
- * disableTracking is true when creating a v-for fragment block, since a v-for
- * fragment always diffs its children.
- *
- * @private
- */
-function openBlock(disableTracking = false) {
- blockStack.push((currentBlock = disableTracking ? null : []));
+// use function string name to check type constructors
+// so that it works across vms / iframes.
+function getType(ctor) {
+ const match = ctor && ctor.toString().match(/^\s*function (\w+)/);
+ return match ? match[1] : '';
}
-function closeBlock() {
- blockStack.pop();
- currentBlock = blockStack[blockStack.length - 1] || null;
+function isSameType(a, b) {
+ return getType(a) === getType(b);
+}
+function getTypeIndex(type, expectedTypes) {
+ if (isArray(expectedTypes)) {
+ for (let i = 0, len = expectedTypes.length; i < len; i++) {
+ if (isSameType(expectedTypes[i], type)) {
+ return i;
+ }
+ }
+ }
+ else if (isFunction(expectedTypes)) {
+ return isSameType(expectedTypes, type) ? 0 : -1;
+ }
+ return -1;
}
-// Whether we should be tracking dynamic child nodes inside a block.
-// Only tracks when this value is > 0
-// We are not using a simple boolean because this value may need to be
-// incremented/decremented by nested usage of v-once (see below)
-let shouldTrack$1 = 1;
/**
- * Block tracking sometimes needs to be disabled, for example during the
- * creation of a tree that needs to be cached by v-once. The compiler generates
- * code like this:
- *
- * ``` js
- * _cache[1] || (
- * setBlockTracking(-1),
- * _cache[1] = createVNode(...),
- * setBlockTracking(1),
- * _cache[1]
- * )
- * ```
- *
- * @private
+ * dev only
*/
-function setBlockTracking(value) {
- shouldTrack$1 += value;
+function validateProps(props, instance) {
+ const rawValues = toRaw(props);
+ const options = instance.propsOptions[0];
+ for (const key in options) {
+ let opt = options[key];
+ if (opt == null)
+ continue;
+ validateProp(key, rawValues[key], opt, !hasOwn(rawValues, key));
+ }
}
/**
- * Create a block root vnode. Takes the same exact arguments as `createVNode`.
- * A block root keeps track of dynamic nodes within the block in the
- * `dynamicChildren` array.
- *
- * @private
+ * dev only
*/
-function createBlock(type, props, children, patchFlag, dynamicProps) {
- const vnode = createVNode(type, props, children, patchFlag, dynamicProps, true /* isBlock: prevent a block from tracking itself */);
- // save current block children on the block vnode
- vnode.dynamicChildren = currentBlock || EMPTY_ARR;
- // close block
- closeBlock();
- // a block is always going to be patched, so track it as a child of its
- // parent block
- if (shouldTrack$1 > 0 && currentBlock) {
- currentBlock.push(vnode);
+function validateProp(name, value, prop, isAbsent) {
+ const { type, required, validator } = prop;
+ // required!
+ if (required && isAbsent) {
+ warn('Missing required prop: "' + name + '"');
+ return;
}
- return vnode;
-}
-function isVNode(value) {
- return value ? value.__v_isVNode === true : false;
-}
-function isSameVNodeType(n1, n2) {
- if ((process.env.NODE_ENV !== 'production') &&
- n2.shapeFlag & 6 /* COMPONENT */ &&
- hmrDirtyComponents.has(n2.type)) {
- // HMR only: if the component has been hot-updated, force a reload.
- return false;
+ // missing but optional
+ if (value == null && !prop.required) {
+ return;
}
- return n1.type === n2.type && n1.key === n2.key;
-}
-let vnodeArgsTransformer;
-/**
- * Internal API for registering an arguments transform for createVNode
- * used for creating stubs in the test-utils
- * It is *internal* but needs to be exposed for test-utils to pick up proper
- * typings
- */
-function transformVNodeArgs(transformer) {
- vnodeArgsTransformer = transformer;
-}
-const createVNodeWithArgsTransform = (...args) => {
- return _createVNode(...(vnodeArgsTransformer
- ? vnodeArgsTransformer(args, currentRenderingInstance)
- : args));
-};
-const InternalObjectKey = `__vInternal`;
-const normalizeKey = ({ key }) => key != null ? key : null;
-const normalizeRef = ({ ref }) => {
- return (ref != null
- ? isArray(ref)
- ? ref
- : { i: currentRenderingInstance, r: ref }
- : null);
-};
-const createVNode = ((process.env.NODE_ENV !== 'production')
- ? createVNodeWithArgsTransform
- : _createVNode);
-function _createVNode(type, props = null, children = null, patchFlag = 0, dynamicProps = null, isBlockNode = false) {
- if (!type || type === NULL_DYNAMIC_COMPONENT) {
- if ((process.env.NODE_ENV !== 'production') && !type) {
- warn(`Invalid vnode type when creating vnode: ${type}.`);
+ // type check
+ if (type != null && type !== true) {
+ let isValid = false;
+ const types = isArray(type) ? type : [type];
+ const expectedTypes = [];
+ // value is valid as long as one of the specified types match
+ for (let i = 0; i < types.length && !isValid; i++) {
+ const { valid, expectedType } = assertType(value, types[i]);
+ expectedTypes.push(expectedType || '');
+ isValid = valid;
}
- type = Comment;
- }
- if (isVNode(type)) {
- // createVNode receiving an existing vnode. This happens in cases like
- //
- // #2078 make sure to merge refs during the clone instead of overwriting it
- const cloned = cloneVNode(type, props, true /* mergeRef: true */);
- if (children) {
- normalizeChildren(cloned, children);
+ if (!isValid) {
+ warn(getInvalidTypeMessage(name, value, expectedTypes));
+ return;
}
- return cloned;
}
- // class component normalization.
- if (isClassComponent(type)) {
- type = type.__vccOpts;
+ // custom validator
+ if (validator && !validator(value)) {
+ warn('Invalid prop: custom validator check failed for prop "' + name + '".');
}
- // class & style normalization.
- if (props) {
- // for reactive or proxy objects, we need to clone it to enable mutation.
- if (isProxy(props) || InternalObjectKey in props) {
- props = extend({}, props);
- }
- let { class: klass, style } = props;
- if (klass && !isString(klass)) {
- props.class = normalizeClass(klass);
- }
- if (isObject(style)) {
- // reactive state objects need to be cloned since they are likely to be
- // mutated
- if (isProxy(style) && !isArray(style)) {
- style = extend({}, style);
- }
- props.style = normalizeStyle(style);
+}
+const isSimpleType = /*#__PURE__*/ makeMap('String,Number,Boolean,Function,Symbol');
+/**
+ * dev only
+ */
+function assertType(value, type) {
+ let valid;
+ const expectedType = getType(type);
+ if (isSimpleType(expectedType)) {
+ const t = typeof value;
+ valid = t === expectedType.toLowerCase();
+ // for primitive wrapper objects
+ if (!valid && t === 'object') {
+ valid = value instanceof type;
}
}
- // encode the vnode type information into a bitmap
- const shapeFlag = isString(type)
- ? 1 /* ELEMENT */
- : isSuspense(type)
- ? 128 /* SUSPENSE */
- : isTeleport(type)
- ? 64 /* TELEPORT */
- : isObject(type)
- ? 4 /* STATEFUL_COMPONENT */
- : isFunction(type)
- ? 2 /* FUNCTIONAL_COMPONENT */
- : 0;
- if ((process.env.NODE_ENV !== 'production') && shapeFlag & 4 /* STATEFUL_COMPONENT */ && isProxy(type)) {
- type = toRaw(type);
- warn(`Vue received a Component which was made a reactive object. This can ` +
- `lead to unnecessary performance overhead, and should be avoided by ` +
- `marking the component with \`markRaw\` or using \`shallowRef\` ` +
- `instead of \`ref\`.`, `\nComponent that was made reactive: `, type);
- }
- const vnode = {
- __v_isVNode: true,
- ["__v_skip" /* SKIP */]: true,
- type,
- props,
- key: props && normalizeKey(props),
- ref: props && normalizeRef(props),
- scopeId: currentScopeId,
- children: null,
- component: null,
- suspense: null,
- ssContent: null,
- ssFallback: null,
- dirs: null,
- transition: null,
- el: null,
- anchor: null,
- target: null,
- targetAnchor: null,
- staticCount: 0,
- shapeFlag,
- patchFlag,
- dynamicProps,
- dynamicChildren: null,
- appContext: null
- };
- // validate key
- if ((process.env.NODE_ENV !== 'production') && vnode.key !== vnode.key) {
- warn(`VNode created with invalid key (NaN). VNode type:`, vnode.type);
+ else if (expectedType === 'Object') {
+ valid = isObject(value);
}
- normalizeChildren(vnode, children);
- // normalize suspense children
- if ( shapeFlag & 128 /* SUSPENSE */) {
- const { content, fallback } = normalizeSuspenseChildren(vnode);
- vnode.ssContent = content;
- vnode.ssFallback = fallback;
+ else if (expectedType === 'Array') {
+ valid = isArray(value);
}
- if (shouldTrack$1 > 0 &&
- // avoid a block node from tracking itself
- !isBlockNode &&
- // has current parent block
- currentBlock &&
- // presence of a patch flag indicates this node needs patching on updates.
- // component nodes also should always be patched, because even if the
- // component doesn't need to update, it needs to persist the instance on to
- // the next vnode so that it can be properly unmounted later.
- (patchFlag > 0 || shapeFlag & 6 /* COMPONENT */) &&
- // the EVENTS flag is only for hydration and if it is the only flag, the
- // vnode should not be considered dynamic due to handler caching.
- patchFlag !== 32 /* HYDRATE_EVENTS */) {
- currentBlock.push(vnode);
+ else {
+ valid = value instanceof type;
}
- return vnode;
-}
-function cloneVNode(vnode, extraProps, mergeRef = false) {
- // This is intentionally NOT using spread or extend to avoid the runtime
- // key enumeration cost.
- const { props, ref, patchFlag } = vnode;
- const mergedProps = extraProps ? mergeProps(props || {}, extraProps) : props;
return {
- __v_isVNode: true,
- ["__v_skip" /* SKIP */]: true,
- type: vnode.type,
- props: mergedProps,
- key: mergedProps && normalizeKey(mergedProps),
- ref: extraProps && extraProps.ref
- ? // #2078 in the case of
- // if the vnode itself already has a ref, cloneVNode will need to merge
- // the refs so the single vnode can be set on multiple refs
- mergeRef && ref
- ? isArray(ref)
- ? ref.concat(normalizeRef(extraProps))
- : [ref, normalizeRef(extraProps)]
- : normalizeRef(extraProps)
- : ref,
- scopeId: vnode.scopeId,
- children: vnode.children,
- target: vnode.target,
- targetAnchor: vnode.targetAnchor,
- staticCount: vnode.staticCount,
- shapeFlag: vnode.shapeFlag,
- // if the vnode is cloned with extra props, we can no longer assume its
- // existing patch flag to be reliable and need to add the FULL_PROPS flag.
- // note: perserve flag for fragments since they use the flag for children
- // fast paths only.
- patchFlag: extraProps && vnode.type !== Fragment
- ? patchFlag === -1 // hoisted node
- ? 16 /* FULL_PROPS */
- : patchFlag | 16 /* FULL_PROPS */
- : patchFlag,
- dynamicProps: vnode.dynamicProps,
- dynamicChildren: vnode.dynamicChildren,
- appContext: vnode.appContext,
- dirs: vnode.dirs,
- transition: vnode.transition,
- // These should technically only be non-null on mounted VNodes. However,
- // they *should* be copied for kept-alive vnodes. So we just always copy
- // them since them being non-null during a mount doesn't affect the logic as
- // they will simply be overwritten.
- component: vnode.component,
- suspense: vnode.suspense,
- ssContent: vnode.ssContent && cloneVNode(vnode.ssContent),
- ssFallback: vnode.ssFallback && cloneVNode(vnode.ssFallback),
- el: vnode.el,
- anchor: vnode.anchor
+ valid,
+ expectedType
};
}
/**
- * @private
+ * dev only
*/
-function createTextVNode(text = ' ', flag = 0) {
- return createVNode(Text, null, text, flag);
-}
-/**
- * @private
- */
-function createStaticVNode(content, numberOfNodes) {
- // A static vnode can contain multiple stringified elements, and the number
- // of elements is necessary for hydration.
- const vnode = createVNode(Static, null, content);
- vnode.staticCount = numberOfNodes;
- return vnode;
+function getInvalidTypeMessage(name, value, expectedTypes) {
+ let message = `Invalid prop: type check failed for prop "${name}".` +
+ ` Expected ${expectedTypes.map(capitalize).join(', ')}`;
+ const expectedType = expectedTypes[0];
+ const receivedType = toRawType(value);
+ const expectedValue = styleValue(value, expectedType);
+ const receivedValue = styleValue(value, receivedType);
+ // check if we need to specify expected value
+ if (expectedTypes.length === 1 &&
+ isExplicable(expectedType) &&
+ !isBoolean(expectedType, receivedType)) {
+ message += ` with value ${expectedValue}`;
+ }
+ message += `, got ${receivedType} `;
+ // check if we need to specify received value
+ if (isExplicable(receivedType)) {
+ message += `with value ${receivedValue}.`;
+ }
+ return message;
}
/**
- * @private
+ * dev only
*/
-function createCommentVNode(text = '',
-// when used as the v-else branch, the comment node must be created as a
-// block to ensure correct updates.
-asBlock = false) {
- return asBlock
- ? (openBlock(), createBlock(Comment, null, text))
- : createVNode(Comment, null, text);
-}
-function normalizeVNode(child) {
- if (child == null || typeof child === 'boolean') {
- // empty placeholder
- return createVNode(Comment);
- }
- else if (isArray(child)) {
- // fragment
- return createVNode(Fragment, null, child);
+function styleValue(value, type) {
+ if (type === 'String') {
+ return `"${value}"`;
}
- else if (typeof child === 'object') {
- // already vnode, this should be the most common since compiled templates
- // always produce all-vnode children arrays
- return child.el === null ? child : cloneVNode(child);
+ else if (type === 'Number') {
+ return `${Number(value)}`;
}
else {
- // strings and numbers
- return createVNode(Text, null, String(child));
+ return `${value}`;
}
}
-// optimized normalization for template-compiled render fns
-function cloneIfMounted(child) {
- return child.el === null ? child : cloneVNode(child);
+/**
+ * dev only
+ */
+function isExplicable(type) {
+ const explicitTypes = ['string', 'number', 'boolean'];
+ return explicitTypes.some(elem => type.toLowerCase() === elem);
}
-function normalizeChildren(vnode, children) {
- let type = 0;
- const { shapeFlag } = vnode;
- if (children == null) {
- children = null;
- }
- else if (isArray(children)) {
- type = 16 /* ARRAY_CHILDREN */;
- }
- else if (typeof children === 'object') {
- if (shapeFlag & 1 /* ELEMENT */ || shapeFlag & 64 /* TELEPORT */) {
- // Normalize slot to plain children for plain element and Teleport
- const slot = children.default;
- if (slot) {
- // _c marker is added by withCtx() indicating this is a compiled slot
- slot._c && setCompiledSlotRendering(1);
- normalizeChildren(vnode, slot());
- slot._c && setCompiledSlotRendering(-1);
- }
- return;
+/**
+ * dev only
+ */
+function isBoolean(...args) {
+ return args.some(elem => elem.toLowerCase() === 'boolean');
+}
+
+function injectHook(type, hook, target = currentInstance, prepend = false) {
+ if (target) {
+ const hooks = target[type] || (target[type] = []);
+ // cache the error handling wrapper for injected hooks so the same hook
+ // can be properly deduped by the scheduler. "__weh" stands for "with error
+ // handling".
+ const wrappedHook = hook.__weh ||
+ (hook.__weh = (...args) => {
+ if (target.isUnmounted) {
+ return;
+ }
+ // disable tracking inside all lifecycle hooks
+ // since they can potentially be called inside effects.
+ pauseTracking();
+ // Set currentInstance during hook invocation.
+ // This assumes the hook does not synchronously trigger other hooks, which
+ // can only be false when the user does something really funky.
+ setCurrentInstance(target);
+ const res = callWithAsyncErrorHandling(hook, target, type, args);
+ setCurrentInstance(null);
+ resetTracking();
+ return res;
+ });
+ if (prepend) {
+ hooks.unshift(wrappedHook);
}
else {
- type = 32 /* SLOTS_CHILDREN */;
- const slotFlag = children._;
- if (!slotFlag && !(InternalObjectKey in children)) {
- children._ctx = currentRenderingInstance;
- }
- else if (slotFlag === 3 /* FORWARDED */ && currentRenderingInstance) {
- // a child component receives forwarded slots from the parent.
- // its slot type is determined by its parent's slot type.
- if (currentRenderingInstance.vnode.patchFlag & 1024 /* DYNAMIC_SLOTS */) {
- children._ = 2 /* DYNAMIC */;
- vnode.patchFlag |= 1024 /* DYNAMIC_SLOTS */;
- }
- else {
- children._ = 1 /* STABLE */;
- }
- }
+ hooks.push(wrappedHook);
}
+ return wrappedHook;
}
- else if (isFunction(children)) {
- children = { default: children, _ctx: currentRenderingInstance };
- type = 32 /* SLOTS_CHILDREN */;
+ else if ((process.env.NODE_ENV !== 'production')) {
+ const apiName = toHandlerKey(ErrorTypeStrings[type].replace(/ hook$/, ''));
+ warn(`${apiName} is called when there is no active component instance to be ` +
+ `associated with. ` +
+ `Lifecycle injection APIs can only be used during execution of setup().` +
+ ( ` If you are using async setup(), make sure to register lifecycle ` +
+ `hooks before the first await statement.`
+ ));
}
- else {
- children = String(children);
- // force teleport children to array so it can be moved around
- if (shapeFlag & 64 /* TELEPORT */) {
- type = 16 /* ARRAY_CHILDREN */;
- children = [createTextVNode(children)];
+}
+const createHook = (lifecycle) => (hook, target = currentInstance) =>
+// post-create lifecycle registrations are noops during SSR
+!isInSSRComponentSetup && injectHook(lifecycle, hook, target);
+const onBeforeMount = createHook("bm" /* BEFORE_MOUNT */);
+const onMounted = createHook("m" /* MOUNTED */);
+const onBeforeUpdate = createHook("bu" /* BEFORE_UPDATE */);
+const onUpdated = createHook("u" /* UPDATED */);
+const onBeforeUnmount = createHook("bum" /* BEFORE_UNMOUNT */);
+const onUnmounted = createHook("um" /* UNMOUNTED */);
+const onRenderTriggered = createHook("rtg" /* RENDER_TRIGGERED */);
+const onRenderTracked = createHook("rtc" /* RENDER_TRACKED */);
+const onErrorCaptured = (hook, target = currentInstance) => {
+ injectHook("ec" /* ERROR_CAPTURED */, hook, target);
+};
+
+// Simple effect.
+function watchEffect(effect, options) {
+ return doWatch(effect, null, options);
+}
+// initial value for watchers to trigger on undefined initial values
+const INITIAL_WATCHER_VALUE = {};
+// implementation
+function watch(source, cb, options) {
+ if ((process.env.NODE_ENV !== 'production') && !isFunction(cb)) {
+ warn(`\`watch(fn, options?)\` signature has been moved to a separate API. ` +
+ `Use \`watchEffect(fn, options?)\` instead. \`watch\` now only ` +
+ `supports \`watch(source, cb, options?) signature.`);
+ }
+ return doWatch(source, cb, options);
+}
+function doWatch(source, cb, { immediate, deep, flush, onTrack, onTrigger } = EMPTY_OBJ, instance = currentInstance) {
+ if ((process.env.NODE_ENV !== 'production') && !cb) {
+ if (immediate !== undefined) {
+ warn(`watch() "immediate" option is only respected when using the ` +
+ `watch(source, callback, options?) signature.`);
}
- else {
- type = 8 /* TEXT_CHILDREN */;
+ if (deep !== undefined) {
+ warn(`watch() "deep" option is only respected when using the ` +
+ `watch(source, callback, options?) signature.`);
}
}
- vnode.children = children;
- vnode.shapeFlag |= type;
-}
-function mergeProps(...args) {
- const ret = extend({}, args[0]);
- for (let i = 1; i < args.length; i++) {
- const toMerge = args[i];
- for (const key in toMerge) {
- if (key === 'class') {
- if (ret.class !== toMerge.class) {
- ret.class = normalizeClass([ret.class, toMerge.class]);
- }
+ const warnInvalidSource = (s) => {
+ warn(`Invalid watch source: `, s, `A watch source can only be a getter/effect function, a ref, ` +
+ `a reactive object, or an array of these types.`);
+ };
+ let getter;
+ let forceTrigger = false;
+ if (isRef(source)) {
+ getter = () => source.value;
+ forceTrigger = !!source._shallow;
+ }
+ else if (isReactive(source)) {
+ getter = () => source;
+ deep = true;
+ }
+ else if (isArray(source)) {
+ getter = () => source.map(s => {
+ if (isRef(s)) {
+ return s.value;
}
- else if (key === 'style') {
- ret.style = normalizeStyle([ret.style, toMerge.style]);
+ else if (isReactive(s)) {
+ return traverse(s);
}
- else if (isOn(key)) {
- const existing = ret[key];
- const incoming = toMerge[key];
- if (existing !== incoming) {
- ret[key] = existing
- ? [].concat(existing, toMerge[key])
- : incoming;
- }
+ else if (isFunction(s)) {
+ return callWithErrorHandling(s, instance, 2 /* WATCH_GETTER */);
}
else {
- ret[key] = toMerge[key];
+ (process.env.NODE_ENV !== 'production') && warnInvalidSource(s);
}
+ });
+ }
+ else if (isFunction(source)) {
+ if (cb) {
+ // getter with cb
+ getter = () => callWithErrorHandling(source, instance, 2 /* WATCH_GETTER */);
+ }
+ else {
+ // no cb -> simple effect
+ getter = () => {
+ if (instance && instance.isUnmounted) {
+ return;
+ }
+ if (cleanup) {
+ cleanup();
+ }
+ return callWithErrorHandling(source, instance, 3 /* WATCH_CALLBACK */, [onInvalidate]);
+ };
}
}
- return ret;
-}
-
-function initProps(instance, rawProps, isStateful, // result of bitwise flag comparison
-isSSR = false) {
- const props = {};
- const attrs = {};
- def(attrs, InternalObjectKey, 1);
- setFullProps(instance, rawProps, props, attrs);
- // validation
- if ((process.env.NODE_ENV !== 'production')) {
- validateProps(props, instance);
- }
- if (isStateful) {
- // stateful
- instance.props = isSSR ? props : shallowReactive(props);
- }
else {
- if (!instance.type.props) {
- // functional w/ optional props, props === attrs
- instance.props = attrs;
- }
- else {
- // functional w/ declared props
- instance.props = props;
- }
+ getter = NOOP;
+ (process.env.NODE_ENV !== 'production') && warnInvalidSource(source);
}
- instance.attrs = attrs;
-}
-function updateProps(instance, rawProps, rawPrevProps, optimized) {
- const { props, attrs, vnode: { patchFlag } } = instance;
- const rawCurrentProps = toRaw(props);
- const [options] = instance.propsOptions;
- if (
- // always force full diff if hmr is enabled
- !((process.env.NODE_ENV !== 'production') && instance.type.__hmrId) &&
- (optimized || patchFlag > 0) &&
- !(patchFlag & 16 /* FULL_PROPS */)) {
- if (patchFlag & 8 /* PROPS */) {
- // Compiler-generated props & no keys change, just set the updated
- // the props.
- const propsToUpdate = instance.vnode.dynamicProps;
- for (let i = 0; i < propsToUpdate.length; i++) {
- const key = propsToUpdate[i];
- // PROPS flag guarantees rawProps to be non-null
- const value = rawProps[key];
- if (options) {
- // attr / props separation was done on init and will be consistent
- // in this code path, so just check if attrs have it.
- if (hasOwn(attrs, key)) {
- attrs[key] = value;
- }
- else {
- const camelizedKey = camelize(key);
- props[camelizedKey] = resolvePropValue(options, rawCurrentProps, camelizedKey, value, instance);
- }
- }
- else {
- attrs[key] = value;
- }
- }
- }
+ if (cb && deep) {
+ const baseGetter = getter;
+ getter = () => traverse(baseGetter());
}
- else {
- // full props update.
- setFullProps(instance, rawProps, props, attrs);
- // in case of dynamic props, check if we need to delete keys from
- // the props object
- let kebabKey;
- for (const key in rawCurrentProps) {
- if (!rawProps ||
- // for camelCase
- (!hasOwn(rawProps, key) &&
- // it's possible the original props was passed in as kebab-case
- // and converted to camelCase (#955)
- ((kebabKey = hyphenate(key)) === key || !hasOwn(rawProps, kebabKey)))) {
- if (options) {
- if (rawPrevProps &&
- // for camelCase
- (rawPrevProps[key] !== undefined ||
- // for kebab-case
- rawPrevProps[kebabKey] !== undefined)) {
- props[key] = resolvePropValue(options, rawProps || EMPTY_OBJ, key, undefined, instance);
- }
- }
- else {
- delete props[key];
- }
- }
+ let cleanup;
+ const onInvalidate = (fn) => {
+ cleanup = runner.options.onStop = () => {
+ callWithErrorHandling(fn, instance, 4 /* WATCH_CLEANUP */);
+ };
+ };
+ let oldValue = isArray(source) ? [] : INITIAL_WATCHER_VALUE;
+ const job = () => {
+ if (!runner.active) {
+ return;
}
- // in the case of functional component w/o props declaration, props and
- // attrs point to the same object so it should already have been updated.
- if (attrs !== rawCurrentProps) {
- for (const key in attrs) {
- if (!rawProps || !hasOwn(rawProps, key)) {
- delete attrs[key];
+ if (cb) {
+ // watch(source, cb)
+ const newValue = runner();
+ if (deep || forceTrigger || hasChanged(newValue, oldValue)) {
+ // cleanup before running cb again
+ if (cleanup) {
+ cleanup();
}
+ callWithAsyncErrorHandling(cb, instance, 3 /* WATCH_CALLBACK */, [
+ newValue,
+ // pass undefined as the old value when it's changed for the first time
+ oldValue === INITIAL_WATCHER_VALUE ? undefined : oldValue,
+ onInvalidate
+ ]);
+ oldValue = newValue;
}
}
- }
- // trigger updates for $attrs in case it's used in component slots
- trigger(instance, "set" /* SET */, '$attrs');
- if ((process.env.NODE_ENV !== 'production') && rawProps) {
- validateProps(props, instance);
- }
-}
-function setFullProps(instance, rawProps, props, attrs) {
- const [options, needCastKeys] = instance.propsOptions;
- if (rawProps) {
- for (const key in rawProps) {
- const value = rawProps[key];
- // key, ref are reserved and never passed down
- if (isReservedProp(key)) {
- continue;
- }
- // prop option names are camelized during normalization, so to support
- // kebab -> camel conversion here we need to camelize the key.
- let camelKey;
- if (options && hasOwn(options, (camelKey = camelize(key)))) {
- props[camelKey] = value;
- }
- else if (!isEmitListener(instance.emitsOptions, key)) {
- // Any non-declared (either as a prop or an emitted event) props are put
- // into a separate `attrs` object for spreading. Make sure to preserve
- // original key casing
- attrs[key] = value;
- }
+ else {
+ // watchEffect
+ runner();
}
+ };
+ // important: mark the job as a watcher callback so that scheduler knows
+ // it is allowed to self-trigger (#1727)
+ job.allowRecurse = !!cb;
+ let scheduler;
+ if (flush === 'sync') {
+ scheduler = job;
}
- if (needCastKeys) {
- const rawCurrentProps = toRaw(props);
- for (let i = 0; i < needCastKeys.length; i++) {
- const key = needCastKeys[i];
- props[key] = resolvePropValue(options, rawCurrentProps, key, rawCurrentProps[key], instance);
- }
+ else if (flush === 'post') {
+ scheduler = () => queuePostRenderEffect(job, instance && instance.suspense);
}
-}
-function resolvePropValue(options, props, key, value, instance) {
- const opt = options[key];
- if (opt != null) {
- const hasDefault = hasOwn(opt, 'default');
- // default values
- if (hasDefault && value === undefined) {
- const defaultValue = opt.default;
- if (opt.type !== Function && isFunction(defaultValue)) {
- setCurrentInstance(instance);
- value = defaultValue(props);
- setCurrentInstance(null);
+ else {
+ // default: 'pre'
+ scheduler = () => {
+ if (!instance || instance.isMounted) {
+ queuePreFlushCb(job);
}
else {
- value = defaultValue;
- }
- }
- // boolean casting
- if (opt[0 /* shouldCast */]) {
- if (!hasOwn(props, key) && !hasDefault) {
- value = false;
- }
- else if (opt[1 /* shouldCastTrue */] &&
- (value === '' || value === hyphenate(key))) {
- value = true;
+ // with 'pre' option, the first call must happen before
+ // the component is mounted so it is called synchronously.
+ job();
}
- }
- }
- return value;
-}
-function normalizePropsOptions(comp, appContext, asMixin = false) {
- const appId = appContext.app ? appContext.app._uid : -1;
- const cache = comp.__props || (comp.__props = {});
- const cached = cache[appId];
- if (cached) {
- return cached;
- }
- const raw = comp.props;
- const normalized = {};
- const needCastKeys = [];
- // apply mixin/extends props
- let hasExtends = false;
- if (__VUE_OPTIONS_API__ && !isFunction(comp)) {
- const extendProps = (raw) => {
- hasExtends = true;
- const [props, keys] = normalizePropsOptions(raw, appContext, true);
- extend(normalized, props);
- if (keys)
- needCastKeys.push(...keys);
};
- if (!asMixin && appContext.mixins.length) {
- appContext.mixins.forEach(extendProps);
- }
- if (comp.extends) {
- extendProps(comp.extends);
+ }
+ const runner = effect(getter, {
+ lazy: true,
+ onTrack,
+ onTrigger,
+ scheduler
+ });
+ recordInstanceBoundEffect(runner);
+ // initial run
+ if (cb) {
+ if (immediate) {
+ job();
}
- if (comp.mixins) {
- comp.mixins.forEach(extendProps);
+ else {
+ oldValue = runner();
}
}
- if (!raw && !hasExtends) {
- return (cache[appId] = EMPTY_ARR);
+ else if (flush === 'post') {
+ queuePostRenderEffect(runner, instance && instance.suspense);
}
- if (isArray(raw)) {
- for (let i = 0; i < raw.length; i++) {
- if ((process.env.NODE_ENV !== 'production') && !isString(raw[i])) {
- warn(`props must be strings when using array syntax.`, raw[i]);
- }
- const normalizedKey = camelize(raw[i]);
- if (validatePropName(normalizedKey)) {
- normalized[normalizedKey] = EMPTY_OBJ;
- }
- }
+ else {
+ runner();
}
- else if (raw) {
- if ((process.env.NODE_ENV !== 'production') && !isObject(raw)) {
- warn(`invalid props options`, raw);
+ return () => {
+ stop(runner);
+ if (instance) {
+ remove(instance.effects, runner);
}
- for (const key in raw) {
- const normalizedKey = camelize(key);
- if (validatePropName(normalizedKey)) {
- const opt = raw[key];
- const prop = (normalized[normalizedKey] =
- isArray(opt) || isFunction(opt) ? { type: opt } : opt);
- if (prop) {
- const booleanIndex = getTypeIndex(Boolean, prop.type);
- const stringIndex = getTypeIndex(String, prop.type);
- prop[0 /* shouldCast */] = booleanIndex > -1;
- prop[1 /* shouldCastTrue */] =
- stringIndex < 0 || booleanIndex < stringIndex;
- // if the prop needs boolean casting or default value
- if (booleanIndex > -1 || hasOwn(prop, 'default')) {
- needCastKeys.push(normalizedKey);
- }
- }
- }
- }
- }
- return (cache[appId] = [normalized, needCastKeys]);
-}
-// use function string name to check type constructors
-// so that it works across vms / iframes.
-function getType(ctor) {
- const match = ctor && ctor.toString().match(/^\s*function (\w+)/);
- return match ? match[1] : '';
-}
-function isSameType(a, b) {
- return getType(a) === getType(b);
-}
-function getTypeIndex(type, expectedTypes) {
- if (isArray(expectedTypes)) {
- for (let i = 0, len = expectedTypes.length; i < len; i++) {
- if (isSameType(expectedTypes[i], type)) {
- return i;
- }
- }
- }
- else if (isFunction(expectedTypes)) {
- return isSameType(expectedTypes, type) ? 0 : -1;
- }
- return -1;
-}
-/**
- * dev only
- */
-function validateProps(props, instance) {
- const rawValues = toRaw(props);
- const options = instance.propsOptions[0];
- for (const key in options) {
- let opt = options[key];
- if (opt == null)
- continue;
- validateProp(key, rawValues[key], opt, !hasOwn(rawValues, key));
- }
+ };
}
-/**
- * dev only
- */
-function validatePropName(key) {
- if (key[0] !== '$') {
- return true;
- }
- else if ((process.env.NODE_ENV !== 'production')) {
- warn(`Invalid prop name: "${key}" is a reserved property.`);
- }
- return false;
+// this.$watch
+function instanceWatch(source, cb, options) {
+ const publicThis = this.proxy;
+ const getter = isString(source)
+ ? () => publicThis[source]
+ : source.bind(publicThis);
+ return doWatch(getter, cb.bind(publicThis), options, this);
}
-/**
- * dev only
- */
-function validateProp(name, value, prop, isAbsent) {
- const { type, required, validator } = prop;
- // required!
- if (required && isAbsent) {
- warn('Missing required prop: "' + name + '"');
- return;
- }
- // missing but optional
- if (value == null && !prop.required) {
- return;
- }
- // type check
- if (type != null && type !== true) {
- let isValid = false;
- const types = isArray(type) ? type : [type];
- const expectedTypes = [];
- // value is valid as long as one of the specified types match
- for (let i = 0; i < types.length && !isValid; i++) {
- const { valid, expectedType } = assertType(value, types[i]);
- expectedTypes.push(expectedType || '');
- isValid = valid;
- }
- if (!isValid) {
- warn(getInvalidTypeMessage(name, value, expectedTypes));
- return;
- }
+function traverse(value, seen = new Set()) {
+ if (!isObject(value) || seen.has(value)) {
+ return value;
}
- // custom validator
- if (validator && !validator(value)) {
- warn('Invalid prop: custom validator check failed for prop "' + name + '".');
+ seen.add(value);
+ if (isRef(value)) {
+ traverse(value.value, seen);
}
-}
-const isSimpleType = /*#__PURE__*/ makeMap('String,Number,Boolean,Function,Symbol');
-/**
- * dev only
- */
-function assertType(value, type) {
- let valid;
- const expectedType = getType(type);
- if (isSimpleType(expectedType)) {
- const t = typeof value;
- valid = t === expectedType.toLowerCase();
- // for primitive wrapper objects
- if (!valid && t === 'object') {
- valid = value instanceof type;
+ else if (isArray(value)) {
+ for (let i = 0; i < value.length; i++) {
+ traverse(value[i], seen);
}
}
- else if (expectedType === 'Object') {
- valid = isObject(value);
- }
- else if (expectedType === 'Array') {
- valid = isArray(value);
- }
- else {
- valid = value instanceof type;
- }
- return {
- valid,
- expectedType
- };
-}
-/**
- * dev only
- */
-function getInvalidTypeMessage(name, value, expectedTypes) {
- let message = `Invalid prop: type check failed for prop "${name}".` +
- ` Expected ${expectedTypes.map(capitalize).join(', ')}`;
- const expectedType = expectedTypes[0];
- const receivedType = toRawType(value);
- const expectedValue = styleValue(value, expectedType);
- const receivedValue = styleValue(value, receivedType);
- // check if we need to specify expected value
- if (expectedTypes.length === 1 &&
- isExplicable(expectedType) &&
- !isBoolean(expectedType, receivedType)) {
- message += ` with value ${expectedValue}`;
- }
- message += `, got ${receivedType} `;
- // check if we need to specify received value
- if (isExplicable(receivedType)) {
- message += `with value ${receivedValue}.`;
- }
- return message;
-}
-/**
- * dev only
- */
-function styleValue(value, type) {
- if (type === 'String') {
- return `"${value}"`;
- }
- else if (type === 'Number') {
- return `${Number(value)}`;
+ else if (isSet(value) || isMap(value)) {
+ value.forEach((v) => {
+ traverse(v, seen);
+ });
}
else {
- return `${value}`;
- }
-}
-/**
- * dev only
- */
-function isExplicable(type) {
- const explicitTypes = ['string', 'number', 'boolean'];
- return explicitTypes.some(elem => type.toLowerCase() === elem);
-}
-/**
- * dev only
- */
-function isBoolean(...args) {
- return args.some(elem => elem.toLowerCase() === 'boolean');
-}
-
-function injectHook(type, hook, target = currentInstance, prepend = false) {
- if (target) {
- const hooks = target[type] || (target[type] = []);
- // cache the error handling wrapper for injected hooks so the same hook
- // can be properly deduped by the scheduler. "__weh" stands for "with error
- // handling".
- const wrappedHook = hook.__weh ||
- (hook.__weh = (...args) => {
- if (target.isUnmounted) {
- return;
- }
- // disable tracking inside all lifecycle hooks
- // since they can potentially be called inside effects.
- pauseTracking();
- // Set currentInstance during hook invocation.
- // This assumes the hook does not synchronously trigger other hooks, which
- // can only be false when the user does something really funky.
- setCurrentInstance(target);
- const res = callWithAsyncErrorHandling(hook, target, type, args);
- setCurrentInstance(null);
- resetTracking();
- return res;
- });
- if (prepend) {
- hooks.unshift(wrappedHook);
- }
- else {
- hooks.push(wrappedHook);
+ for (const key in value) {
+ traverse(value[key], seen);
}
- return wrappedHook;
}
- else if ((process.env.NODE_ENV !== 'production')) {
- const apiName = `on${capitalize(ErrorTypeStrings[type].replace(/ hook$/, ''))}`;
- warn(`${apiName} is called when there is no active component instance to be ` +
- `associated with. ` +
- `Lifecycle injection APIs can only be used during execution of setup().` +
- ( ` If you are using async setup(), make sure to register lifecycle ` +
- `hooks before the first await statement.`
- ));
- }
-}
-const createHook = (lifecycle) => (hook, target = currentInstance) =>
-// post-create lifecycle registrations are noops during SSR
-!isInSSRComponentSetup && injectHook(lifecycle, hook, target);
-const onBeforeMount = createHook("bm" /* BEFORE_MOUNT */);
-const onMounted = createHook("m" /* MOUNTED */);
-const onBeforeUpdate = createHook("bu" /* BEFORE_UPDATE */);
-const onUpdated = createHook("u" /* UPDATED */);
-const onBeforeUnmount = createHook("bum" /* BEFORE_UNMOUNT */);
-const onUnmounted = createHook("um" /* UNMOUNTED */);
-const onRenderTriggered = createHook("rtg" /* RENDER_TRIGGERED */);
-const onRenderTracked = createHook("rtc" /* RENDER_TRACKED */);
-const onErrorCaptured = (hook, target = currentInstance) => {
- injectHook("ec" /* ERROR_CAPTURED */, hook, target);
-};
+ return value;
+}
function useTransitionState() {
const state = {
@@ -4215,6 +3766,11 @@ function createAppAPI(render, hydrate) {
if (__VUE_OPTIONS_API__) {
if (!context.mixins.includes(mixin)) {
context.mixins.push(mixin);
+ // global mixin with props/emits de-optimizes props/emits
+ // normalization caching.
+ if (mixin.props || mixin.emits) {
+ context.deopt = true;
+ }
}
else if ((process.env.NODE_ENV !== 'production')) {
warn('Mixin has already been applied to target app' +
@@ -5037,7 +4593,7 @@ function baseCreateRenderer(options, createHydrationFns) {
if (dirs) {
invokeDirectiveHook(n2, n1, parentComponent, 'beforeUpdate');
}
- if ((process.env.NODE_ENV !== 'production') && isHmrUpdating) {
+ if ((process.env.NODE_ENV !== 'production') && (true ) && isHmrUpdating) {
// HMR updated, force full diff
patchFlag = 0;
optimized = false;
@@ -5100,7 +4656,10 @@ function baseCreateRenderer(options, createHydrationFns) {
const areChildrenSVG = isSVG && n2.type !== 'foreignObject';
if (dynamicChildren) {
patchBlockChildren(n1.dynamicChildren, dynamicChildren, el, parentComponent, parentSuspense, areChildrenSVG);
- if ((process.env.NODE_ENV !== 'production') && parentComponent && parentComponent.type.__hmrId) {
+ if ((process.env.NODE_ENV !== 'production') &&
+ (true ) &&
+ parentComponent &&
+ parentComponent.type.__hmrId) {
traverseStaticChildren(n1, n2);
}
}
@@ -5141,6 +4700,7 @@ function baseCreateRenderer(options, createHydrationFns) {
const patchProps = (el, vnode, oldProps, newProps, parentComponent, parentSuspense, isSVG) => {
if (oldProps !== newProps) {
for (const key in newProps) {
+ // empty string is not valid prop
if (isReservedProp(key))
continue;
const next = newProps[key];
@@ -5224,7 +4784,7 @@ function baseCreateRenderer(options, createHydrationFns) {
};
const mountComponent = (initialVNode, container, anchor, parentComponent, parentSuspense, isSVG, optimized) => {
const instance = (initialVNode.component = createComponentInstance(initialVNode, parentComponent, parentSuspense));
- if ((process.env.NODE_ENV !== 'production') && instance.type.__hmrId) {
+ if ((process.env.NODE_ENV !== 'production') && (true ) && instance.type.__hmrId) {
registerHMR(instance);
}
if ((process.env.NODE_ENV !== 'production')) {
@@ -5369,12 +4929,12 @@ function baseCreateRenderer(options, createHydrationFns) {
pushWarningContext(next || instance.vnode);
}
if (next) {
+ next.el = vnode.el;
updateComponentPreRender(instance, next, optimized);
}
else {
next = vnode;
}
- next.el = vnode.el;
// beforeUpdate hook
if (bu) {
invokeArrayFns(bu);
@@ -5393,11 +4953,6 @@ function baseCreateRenderer(options, createHydrationFns) {
}
const prevTree = instance.subTree;
instance.subTree = nextTree;
- // reset refs
- // only needed if previous patch had refs
- if (instance.refs !== EMPTY_OBJ) {
- instance.refs = {};
- }
if ((process.env.NODE_ENV !== 'production')) {
startMeasure(instance, `patch`);
}
@@ -5515,7 +5070,7 @@ function baseCreateRenderer(options, createHydrationFns) {
}
if (oldLength > newLength) {
// remove old
- unmountChildren(c1, parentComponent, parentSuspense, true, commonLength);
+ unmountChildren(c1, parentComponent, parentSuspense, true, false, commonLength);
}
else {
// mount new
@@ -5752,7 +5307,7 @@ function baseCreateRenderer(options, createHydrationFns) {
hostInsert(el, container, anchor);
}
};
- const unmount = (vnode, parentComponent, parentSuspense, doRemove = false) => {
+ const unmount = (vnode, parentComponent, parentSuspense, doRemove = false, optimized = false) => {
const { type, props, ref, children, dynamicChildren, shapeFlag, patchFlag, dirs } = vnode;
// unset ref
if (ref != null && parentComponent) {
@@ -5783,13 +5338,17 @@ function baseCreateRenderer(options, createHydrationFns) {
(type !== Fragment ||
(patchFlag > 0 && patchFlag & 64 /* STABLE_FRAGMENT */))) {
// fast path for block nodes: only need to unmount dynamic children.
- unmountChildren(dynamicChildren, parentComponent, parentSuspense);
+ unmountChildren(dynamicChildren, parentComponent, parentSuspense, false, true);
}
- else if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
+ else if ((type === Fragment &&
+ (patchFlag & 128 /* KEYED_FRAGMENT */ ||
+ patchFlag & 256 /* UNKEYED_FRAGMENT */)) ||
+ (!optimized && shapeFlag & 16 /* ARRAY_CHILDREN */)) {
unmountChildren(children, parentComponent, parentSuspense);
}
- // an unmounted teleport should always remove its children
- if (shapeFlag & 64 /* TELEPORT */) {
+ // an unmounted teleport should always remove its children if not disabled
+ if (shapeFlag & 64 /* TELEPORT */ &&
+ (doRemove || !isTeleportDisabled(vnode.props))) {
vnode.type.remove(vnode, internals);
}
if (doRemove) {
@@ -5848,7 +5407,7 @@ function baseCreateRenderer(options, createHydrationFns) {
hostRemove(end);
};
const unmountComponent = (instance, parentSuspense, doRemove) => {
- if ((process.env.NODE_ENV !== 'production') && instance.type.__hmrId) {
+ if ((process.env.NODE_ENV !== 'production') && (true ) && instance.type.__hmrId) {
unregisterHMR(instance);
}
const { bum, effects, update, subTree, um } = instance;
@@ -5893,9 +5452,9 @@ function baseCreateRenderer(options, createHydrationFns) {
devtoolsComponentRemoved(instance);
}
};
- const unmountChildren = (children, parentComponent, parentSuspense, doRemove = false, start = 0) => {
+ const unmountChildren = (children, parentComponent, parentSuspense, doRemove = false, optimized = false, start = 0) => {
for (let i = start; i < children.length; i++) {
- unmount(children[i], parentComponent, parentSuspense, doRemove);
+ unmount(children[i], parentComponent, parentSuspense, doRemove, optimized);
}
};
const getNextHostNode = vnode => {
@@ -5907,39 +5466,6 @@ function baseCreateRenderer(options, createHydrationFns) {
}
return hostNextSibling((vnode.anchor || vnode.el));
};
- /**
- * #1156
- * When a component is HMR-enabled, we need to make sure that all static nodes
- * inside a block also inherit the DOM element from the previous tree so that
- * HMR updates (which are full updates) can retrieve the element for patching.
- *
- * #2080
- * Inside keyed `template` fragment static children, if a fragment is moved,
- * the children will always moved so that need inherit el form previous nodes
- * to ensure correct moved position.
- */
- const traverseStaticChildren = (n1, n2, shallow = false) => {
- const ch1 = n1.children;
- const ch2 = n2.children;
- if (isArray(ch1) && isArray(ch2)) {
- for (let i = 0; i < ch1.length; i++) {
- // this is only called in the optimized path so array children are
- // guaranteed to be vnodes
- const c1 = ch1[i];
- const c2 = (ch2[i] = cloneIfMounted(ch2[i]));
- if (c2.shapeFlag & 1 /* ELEMENT */ && !c2.dynamicChildren) {
- if (c2.patchFlag <= 0 || c2.patchFlag === 32 /* HYDRATE_EVENTS */) {
- c2.el = c1.el;
- }
- if (!shallow)
- traverseStaticChildren(c1, c2);
- }
- if ((process.env.NODE_ENV !== 'production') && c2.type === Comment) {
- c2.el = c1.el;
- }
- }
- }
- };
const render = (vnode, container) => {
if (vnode == null) {
if (container._vnode) {
@@ -5981,6 +5507,42 @@ function invokeVNodeHook(hook, instance, vnode, prevVNode = null) {
prevVNode
]);
}
+/**
+ * #1156
+ * When a component is HMR-enabled, we need to make sure that all static nodes
+ * inside a block also inherit the DOM element from the previous tree so that
+ * HMR updates (which are full updates) can retrieve the element for patching.
+ *
+ * #2080
+ * Inside keyed `template` fragment static children, if a fragment is moved,
+ * the children will always moved so that need inherit el form previous nodes
+ * to ensure correct moved position.
+ */
+function traverseStaticChildren(n1, n2, shallow = false) {
+ const ch1 = n1.children;
+ const ch2 = n2.children;
+ if (isArray(ch1) && isArray(ch2)) {
+ for (let i = 0; i < ch1.length; i++) {
+ // this is only called in the optimized path so array children are
+ // guaranteed to be vnodes
+ const c1 = ch1[i];
+ let c2 = ch2[i];
+ if (c2.shapeFlag & 1 /* ELEMENT */ && !c2.dynamicChildren) {
+ if (c2.patchFlag <= 0 || c2.patchFlag === 32 /* HYDRATE_EVENTS */) {
+ c2 = ch2[i] = cloneIfMounted(ch2[i]);
+ c2.el = c1.el;
+ }
+ if (!shallow)
+ traverseStaticChildren(c1, c2);
+ }
+ // also inherit for comment nodes, but not placeholders (e.g. v-if which
+ // would have received .el during block patch)
+ if ((process.env.NODE_ENV !== 'production') && c2.type === Comment && !c2.el) {
+ c2.el = c1.el;
+ }
+ }
+ }
+}
// https://en.wikipedia.org/wiki/Longest_increasing_subsequence
function getSequence(arr) {
const p = arr.slice();
@@ -6024,210 +5586,667 @@ function getSequence(arr) {
return result;
}
-// Simple effect.
-function watchEffect(effect, options) {
- return doWatch(effect, null, options);
-}
-// initial value for watchers to trigger on undefined initial values
-const INITIAL_WATCHER_VALUE = {};
-// implementation
-function watch(source, cb, options) {
- if ((process.env.NODE_ENV !== 'production') && !isFunction(cb)) {
- warn(`\`watch(fn, options?)\` signature has been moved to a separate API. ` +
- `Use \`watchEffect(fn, options?)\` instead. \`watch\` now only ` +
- `supports \`watch(source, cb, options?) signature.`);
- }
- return doWatch(source, cb, options);
-}
-function doWatch(source, cb, { immediate, deep, flush, onTrack, onTrigger } = EMPTY_OBJ, instance = currentInstance) {
- if ((process.env.NODE_ENV !== 'production') && !cb) {
- if (immediate !== undefined) {
- warn(`watch() "immediate" option is only respected when using the ` +
- `watch(source, callback, options?) signature.`);
+const isTeleport = (type) => type.__isTeleport;
+const isTeleportDisabled = (props) => props && (props.disabled || props.disabled === '');
+const resolveTarget = (props, select) => {
+ const targetSelector = props && props.to;
+ if (isString(targetSelector)) {
+ if (!select) {
+ (process.env.NODE_ENV !== 'production') &&
+ warn(`Current renderer does not support string target for Teleports. ` +
+ `(missing querySelector renderer option)`);
+ return null;
}
- if (deep !== undefined) {
- warn(`watch() "deep" option is only respected when using the ` +
- `watch(source, callback, options?) signature.`);
+ else {
+ const target = select(targetSelector);
+ if (!target) {
+ (process.env.NODE_ENV !== 'production') &&
+ warn(`Failed to locate Teleport target with selector "${targetSelector}". ` +
+ `Note the target element must exist before the component is mounted - ` +
+ `i.e. the target cannot be rendered by the component itself, and ` +
+ `ideally should be outside of the entire Vue component tree.`);
+ }
+ return target;
}
}
- const warnInvalidSource = (s) => {
- warn(`Invalid watch source: `, s, `A watch source can only be a getter/effect function, a ref, ` +
- `a reactive object, or an array of these types.`);
- };
- let getter;
- const isRefSource = isRef(source);
- if (isRefSource) {
- getter = () => source.value;
- }
- else if (isReactive(source)) {
- getter = () => source;
- deep = true;
+ else {
+ if ((process.env.NODE_ENV !== 'production') && !targetSelector && !isTeleportDisabled(props)) {
+ warn(`Invalid Teleport target: ${targetSelector}`);
+ }
+ return targetSelector;
}
- else if (isArray(source)) {
- getter = () => source.map(s => {
- if (isRef(s)) {
- return s.value;
+};
+const TeleportImpl = {
+ __isTeleport: true,
+ process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized, internals) {
+ const { mc: mountChildren, pc: patchChildren, pbc: patchBlockChildren, o: { insert, querySelector, createText, createComment } } = internals;
+ const disabled = isTeleportDisabled(n2.props);
+ const { shapeFlag, children } = n2;
+ if (n1 == null) {
+ // insert anchors in the main view
+ const placeholder = (n2.el = (process.env.NODE_ENV !== 'production')
+ ? createComment('teleport start')
+ : createText(''));
+ const mainAnchor = (n2.anchor = (process.env.NODE_ENV !== 'production')
+ ? createComment('teleport end')
+ : createText(''));
+ insert(placeholder, container, anchor);
+ insert(mainAnchor, container, anchor);
+ const target = (n2.target = resolveTarget(n2.props, querySelector));
+ const targetAnchor = (n2.targetAnchor = createText(''));
+ if (target) {
+ insert(targetAnchor, target);
}
- else if (isReactive(s)) {
- return traverse(s);
+ else if ((process.env.NODE_ENV !== 'production') && !disabled) {
+ warn('Invalid Teleport target on mount:', target, `(${typeof target})`);
}
- else if (isFunction(s)) {
- return callWithErrorHandling(s, instance, 2 /* WATCH_GETTER */);
+ const mount = (container, anchor) => {
+ // Teleport *always* has Array children. This is enforced in both the
+ // compiler and vnode children normalization.
+ if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
+ mountChildren(children, container, anchor, parentComponent, parentSuspense, isSVG, optimized);
+ }
+ };
+ if (disabled) {
+ mount(container, mainAnchor);
}
- else {
- (process.env.NODE_ENV !== 'production') && warnInvalidSource(s);
+ else if (target) {
+ mount(target, targetAnchor);
}
- });
- }
- else if (isFunction(source)) {
- if (cb) {
- // getter with cb
- getter = () => callWithErrorHandling(source, instance, 2 /* WATCH_GETTER */);
}
else {
- // no cb -> simple effect
- getter = () => {
- if (instance && instance.isUnmounted) {
- return;
+ // update content
+ n2.el = n1.el;
+ const mainAnchor = (n2.anchor = n1.anchor);
+ const target = (n2.target = n1.target);
+ const targetAnchor = (n2.targetAnchor = n1.targetAnchor);
+ const wasDisabled = isTeleportDisabled(n1.props);
+ const currentContainer = wasDisabled ? container : target;
+ const currentAnchor = wasDisabled ? mainAnchor : targetAnchor;
+ if (n2.dynamicChildren) {
+ // fast path when the teleport happens to be a block root
+ patchBlockChildren(n1.dynamicChildren, n2.dynamicChildren, currentContainer, parentComponent, parentSuspense, isSVG);
+ // even in block tree mode we need to make sure all root-level nodes
+ // in the teleport inherit previous DOM references so that they can
+ // be moved in future patches.
+ traverseStaticChildren(n1, n2, true);
+ }
+ else if (!optimized) {
+ patchChildren(n1, n2, currentContainer, currentAnchor, parentComponent, parentSuspense, isSVG);
+ }
+ if (disabled) {
+ if (!wasDisabled) {
+ // enabled -> disabled
+ // move into main container
+ moveTeleport(n2, container, mainAnchor, internals, 1 /* TOGGLE */);
}
- if (cleanup) {
- cleanup();
+ }
+ else {
+ // target changed
+ if ((n2.props && n2.props.to) !== (n1.props && n1.props.to)) {
+ const nextTarget = (n2.target = resolveTarget(n2.props, querySelector));
+ if (nextTarget) {
+ moveTeleport(n2, nextTarget, null, internals, 0 /* TARGET_CHANGE */);
+ }
+ else if ((process.env.NODE_ENV !== 'production')) {
+ warn('Invalid Teleport target on update:', target, `(${typeof target})`);
+ }
}
- return callWithErrorHandling(source, instance, 3 /* WATCH_CALLBACK */, [onInvalidate]);
- };
+ else if (wasDisabled) {
+ // disabled -> enabled
+ // move into teleport target
+ moveTeleport(n2, target, targetAnchor, internals, 1 /* TOGGLE */);
+ }
+ }
+ }
+ },
+ remove(vnode, { r: remove, o: { remove: hostRemove } }) {
+ const { shapeFlag, children, anchor } = vnode;
+ hostRemove(anchor);
+ if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
+ for (let i = 0; i < children.length; i++) {
+ remove(children[i]);
+ }
+ }
+ },
+ move: moveTeleport,
+ hydrate: hydrateTeleport
+};
+function moveTeleport(vnode, container, parentAnchor, { o: { insert }, m: move }, moveType = 2 /* REORDER */) {
+ // move target anchor if this is a target change.
+ if (moveType === 0 /* TARGET_CHANGE */) {
+ insert(vnode.targetAnchor, container, parentAnchor);
+ }
+ const { el, anchor, shapeFlag, children, props } = vnode;
+ const isReorder = moveType === 2 /* REORDER */;
+ // move main view anchor if this is a re-order.
+ if (isReorder) {
+ insert(el, container, parentAnchor);
+ }
+ // if this is a re-order and teleport is enabled (content is in target)
+ // do not move children. So the opposite is: only move children if this
+ // is not a reorder, or the teleport is disabled
+ if (!isReorder || isTeleportDisabled(props)) {
+ // Teleport has either Array children or no children.
+ if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
+ for (let i = 0; i < children.length; i++) {
+ move(children[i], container, parentAnchor, 2 /* REORDER */);
+ }
+ }
+ }
+ // move main view anchor if this is a re-order.
+ if (isReorder) {
+ insert(anchor, container, parentAnchor);
+ }
+}
+function hydrateTeleport(node, vnode, parentComponent, parentSuspense, optimized, { o: { nextSibling, parentNode, querySelector } }, hydrateChildren) {
+ const target = (vnode.target = resolveTarget(vnode.props, querySelector));
+ if (target) {
+ // if multiple teleports rendered to the same target element, we need to
+ // pick up from where the last teleport finished instead of the first node
+ const targetNode = target._lpa || target.firstChild;
+ if (vnode.shapeFlag & 16 /* ARRAY_CHILDREN */) {
+ if (isTeleportDisabled(vnode.props)) {
+ vnode.anchor = hydrateChildren(nextSibling(node), vnode, parentNode(node), parentComponent, parentSuspense, optimized);
+ vnode.targetAnchor = targetNode;
+ }
+ else {
+ vnode.anchor = nextSibling(node);
+ vnode.targetAnchor = hydrateChildren(targetNode, vnode, target, parentComponent, parentSuspense, optimized);
+ }
+ target._lpa =
+ vnode.targetAnchor && nextSibling(vnode.targetAnchor);
}
}
+ return vnode.anchor && nextSibling(vnode.anchor);
+}
+// Force-casted public typing for h and TSX props inference
+const Teleport = TeleportImpl;
+
+const COMPONENTS = 'components';
+const DIRECTIVES = 'directives';
+/**
+ * @private
+ */
+function resolveComponent(name) {
+ return resolveAsset(COMPONENTS, name) || name;
+}
+const NULL_DYNAMIC_COMPONENT = Symbol();
+/**
+ * @private
+ */
+function resolveDynamicComponent(component) {
+ if (isString(component)) {
+ return resolveAsset(COMPONENTS, component, false) || component;
+ }
+ else {
+ // invalid types will fallthrough to createVNode and raise warning
+ return (component || NULL_DYNAMIC_COMPONENT);
+ }
+}
+/**
+ * @private
+ */
+function resolveDirective(name) {
+ return resolveAsset(DIRECTIVES, name);
+}
+// implementation
+function resolveAsset(type, name, warnMissing = true) {
+ const instance = currentRenderingInstance || currentInstance;
+ if (instance) {
+ const Component = instance.type;
+ // self name has highest priority
+ if (type === COMPONENTS) {
+ const selfName = Component.displayName || Component.name;
+ if (selfName &&
+ (selfName === name ||
+ selfName === camelize(name) ||
+ selfName === capitalize(camelize(name)))) {
+ return Component;
+ }
+ }
+ const res =
+ // local registration
+ // check instance[type] first for components with mixin or extends.
+ resolve(instance[type] || Component[type], name) ||
+ // global registration
+ resolve(instance.appContext[type], name);
+ if ((process.env.NODE_ENV !== 'production') && warnMissing && !res) {
+ warn(`Failed to resolve ${type.slice(0, -1)}: ${name}`);
+ }
+ return res;
+ }
+ else if ((process.env.NODE_ENV !== 'production')) {
+ warn(`resolve${capitalize(type.slice(0, -1))} ` +
+ `can only be used in render() or setup().`);
+ }
+}
+function resolve(registry, name) {
+ return (registry &&
+ (registry[name] ||
+ registry[camelize(name)] ||
+ registry[capitalize(camelize(name))]));
+}
+
+const Fragment = Symbol((process.env.NODE_ENV !== 'production') ? 'Fragment' : undefined);
+const Text = Symbol((process.env.NODE_ENV !== 'production') ? 'Text' : undefined);
+const Comment = Symbol((process.env.NODE_ENV !== 'production') ? 'Comment' : undefined);
+const Static = Symbol((process.env.NODE_ENV !== 'production') ? 'Static' : undefined);
+// Since v-if and v-for are the two possible ways node structure can dynamically
+// change, once we consider v-if branches and each v-for fragment a block, we
+// can divide a template into nested blocks, and within each block the node
+// structure would be stable. This allows us to skip most children diffing
+// and only worry about the dynamic nodes (indicated by patch flags).
+const blockStack = [];
+let currentBlock = null;
+/**
+ * Open a block.
+ * This must be called before `createBlock`. It cannot be part of `createBlock`
+ * because the children of the block are evaluated before `createBlock` itself
+ * is called. The generated code typically looks like this:
+ *
+ * ```js
+ * function render() {
+ * return (openBlock(),createBlock('div', null, [...]))
+ * }
+ * ```
+ * disableTracking is true when creating a v-for fragment block, since a v-for
+ * fragment always diffs its children.
+ *
+ * @private
+ */
+function openBlock(disableTracking = false) {
+ blockStack.push((currentBlock = disableTracking ? null : []));
+}
+function closeBlock() {
+ blockStack.pop();
+ currentBlock = blockStack[blockStack.length - 1] || null;
+}
+// Whether we should be tracking dynamic child nodes inside a block.
+// Only tracks when this value is > 0
+// We are not using a simple boolean because this value may need to be
+// incremented/decremented by nested usage of v-once (see below)
+let shouldTrack$1 = 1;
+/**
+ * Block tracking sometimes needs to be disabled, for example during the
+ * creation of a tree that needs to be cached by v-once. The compiler generates
+ * code like this:
+ *
+ * ``` js
+ * _cache[1] || (
+ * setBlockTracking(-1),
+ * _cache[1] = createVNode(...),
+ * setBlockTracking(1),
+ * _cache[1]
+ * )
+ * ```
+ *
+ * @private
+ */
+function setBlockTracking(value) {
+ shouldTrack$1 += value;
+}
+/**
+ * Create a block root vnode. Takes the same exact arguments as `createVNode`.
+ * A block root keeps track of dynamic nodes within the block in the
+ * `dynamicChildren` array.
+ *
+ * @private
+ */
+function createBlock(type, props, children, patchFlag, dynamicProps) {
+ const vnode = createVNode(type, props, children, patchFlag, dynamicProps, true /* isBlock: prevent a block from tracking itself */);
+ // save current block children on the block vnode
+ vnode.dynamicChildren = currentBlock || EMPTY_ARR;
+ // close block
+ closeBlock();
+ // a block is always going to be patched, so track it as a child of its
+ // parent block
+ if (shouldTrack$1 > 0 && currentBlock) {
+ currentBlock.push(vnode);
+ }
+ return vnode;
+}
+function isVNode(value) {
+ return value ? value.__v_isVNode === true : false;
+}
+function isSameVNodeType(n1, n2) {
+ if ((process.env.NODE_ENV !== 'production') &&
+ n2.shapeFlag & 6 /* COMPONENT */ &&
+ hmrDirtyComponents.has(n2.type)) {
+ // HMR only: if the component has been hot-updated, force a reload.
+ return false;
+ }
+ return n1.type === n2.type && n1.key === n2.key;
+}
+let vnodeArgsTransformer;
+/**
+ * Internal API for registering an arguments transform for createVNode
+ * used for creating stubs in the test-utils
+ * It is *internal* but needs to be exposed for test-utils to pick up proper
+ * typings
+ */
+function transformVNodeArgs(transformer) {
+ vnodeArgsTransformer = transformer;
+}
+const createVNodeWithArgsTransform = (...args) => {
+ return _createVNode(...(vnodeArgsTransformer
+ ? vnodeArgsTransformer(args, currentRenderingInstance)
+ : args));
+};
+const InternalObjectKey = `__vInternal`;
+const normalizeKey = ({ key }) => key != null ? key : null;
+const normalizeRef = ({ ref }) => {
+ return (ref != null
+ ? isArray(ref)
+ ? ref
+ : { i: currentRenderingInstance, r: ref }
+ : null);
+};
+const createVNode = ((process.env.NODE_ENV !== 'production')
+ ? createVNodeWithArgsTransform
+ : _createVNode);
+function _createVNode(type, props = null, children = null, patchFlag = 0, dynamicProps = null, isBlockNode = false) {
+ if (!type || type === NULL_DYNAMIC_COMPONENT) {
+ if ((process.env.NODE_ENV !== 'production') && !type) {
+ warn(`Invalid vnode type when creating vnode: ${type}.`);
+ }
+ type = Comment;
+ }
+ if (isVNode(type)) {
+ // createVNode receiving an existing vnode. This happens in cases like
+ //
+ // #2078 make sure to merge refs during the clone instead of overwriting it
+ const cloned = cloneVNode(type, props, true /* mergeRef: true */);
+ if (children) {
+ normalizeChildren(cloned, children);
+ }
+ return cloned;
+ }
+ // class component normalization.
+ if (isClassComponent(type)) {
+ type = type.__vccOpts;
+ }
+ // class & style normalization.
+ if (props) {
+ // for reactive or proxy objects, we need to clone it to enable mutation.
+ if (isProxy(props) || InternalObjectKey in props) {
+ props = extend({}, props);
+ }
+ let { class: klass, style } = props;
+ if (klass && !isString(klass)) {
+ props.class = normalizeClass(klass);
+ }
+ if (isObject(style)) {
+ // reactive state objects need to be cloned since they are likely to be
+ // mutated
+ if (isProxy(style) && !isArray(style)) {
+ style = extend({}, style);
+ }
+ props.style = normalizeStyle(style);
+ }
+ }
+ // encode the vnode type information into a bitmap
+ const shapeFlag = isString(type)
+ ? 1 /* ELEMENT */
+ : isSuspense(type)
+ ? 128 /* SUSPENSE */
+ : isTeleport(type)
+ ? 64 /* TELEPORT */
+ : isObject(type)
+ ? 4 /* STATEFUL_COMPONENT */
+ : isFunction(type)
+ ? 2 /* FUNCTIONAL_COMPONENT */
+ : 0;
+ if ((process.env.NODE_ENV !== 'production') && shapeFlag & 4 /* STATEFUL_COMPONENT */ && isProxy(type)) {
+ type = toRaw(type);
+ warn(`Vue received a Component which was made a reactive object. This can ` +
+ `lead to unnecessary performance overhead, and should be avoided by ` +
+ `marking the component with \`markRaw\` or using \`shallowRef\` ` +
+ `instead of \`ref\`.`, `\nComponent that was made reactive: `, type);
+ }
+ const vnode = {
+ __v_isVNode: true,
+ ["__v_skip" /* SKIP */]: true,
+ type,
+ props,
+ key: props && normalizeKey(props),
+ ref: props && normalizeRef(props),
+ scopeId: currentScopeId,
+ children: null,
+ component: null,
+ suspense: null,
+ ssContent: null,
+ ssFallback: null,
+ dirs: null,
+ transition: null,
+ el: null,
+ anchor: null,
+ target: null,
+ targetAnchor: null,
+ staticCount: 0,
+ shapeFlag,
+ patchFlag,
+ dynamicProps,
+ dynamicChildren: null,
+ appContext: null
+ };
+ // validate key
+ if ((process.env.NODE_ENV !== 'production') && vnode.key !== vnode.key) {
+ warn(`VNode created with invalid key (NaN). VNode type:`, vnode.type);
+ }
+ normalizeChildren(vnode, children);
+ // normalize suspense children
+ if ( shapeFlag & 128 /* SUSPENSE */) {
+ const { content, fallback } = normalizeSuspenseChildren(vnode);
+ vnode.ssContent = content;
+ vnode.ssFallback = fallback;
+ }
+ if (shouldTrack$1 > 0 &&
+ // avoid a block node from tracking itself
+ !isBlockNode &&
+ // has current parent block
+ currentBlock &&
+ // presence of a patch flag indicates this node needs patching on updates.
+ // component nodes also should always be patched, because even if the
+ // component doesn't need to update, it needs to persist the instance on to
+ // the next vnode so that it can be properly unmounted later.
+ (patchFlag > 0 || shapeFlag & 6 /* COMPONENT */) &&
+ // the EVENTS flag is only for hydration and if it is the only flag, the
+ // vnode should not be considered dynamic due to handler caching.
+ patchFlag !== 32 /* HYDRATE_EVENTS */) {
+ currentBlock.push(vnode);
+ }
+ return vnode;
+}
+function cloneVNode(vnode, extraProps, mergeRef = false) {
+ // This is intentionally NOT using spread or extend to avoid the runtime
+ // key enumeration cost.
+ const { props, ref, patchFlag } = vnode;
+ const mergedProps = extraProps ? mergeProps(props || {}, extraProps) : props;
+ return {
+ __v_isVNode: true,
+ ["__v_skip" /* SKIP */]: true,
+ type: vnode.type,
+ props: mergedProps,
+ key: mergedProps && normalizeKey(mergedProps),
+ ref: extraProps && extraProps.ref
+ ? // #2078 in the case of
+ // if the vnode itself already has a ref, cloneVNode will need to merge
+ // the refs so the single vnode can be set on multiple refs
+ mergeRef && ref
+ ? isArray(ref)
+ ? ref.concat(normalizeRef(extraProps))
+ : [ref, normalizeRef(extraProps)]
+ : normalizeRef(extraProps)
+ : ref,
+ scopeId: vnode.scopeId,
+ children: vnode.children,
+ target: vnode.target,
+ targetAnchor: vnode.targetAnchor,
+ staticCount: vnode.staticCount,
+ shapeFlag: vnode.shapeFlag,
+ // if the vnode is cloned with extra props, we can no longer assume its
+ // existing patch flag to be reliable and need to add the FULL_PROPS flag.
+ // note: perserve flag for fragments since they use the flag for children
+ // fast paths only.
+ patchFlag: extraProps && vnode.type !== Fragment
+ ? patchFlag === -1 // hoisted node
+ ? 16 /* FULL_PROPS */
+ : patchFlag | 16 /* FULL_PROPS */
+ : patchFlag,
+ dynamicProps: vnode.dynamicProps,
+ dynamicChildren: vnode.dynamicChildren,
+ appContext: vnode.appContext,
+ dirs: vnode.dirs,
+ transition: vnode.transition,
+ // These should technically only be non-null on mounted VNodes. However,
+ // they *should* be copied for kept-alive vnodes. So we just always copy
+ // them since them being non-null during a mount doesn't affect the logic as
+ // they will simply be overwritten.
+ component: vnode.component,
+ suspense: vnode.suspense,
+ ssContent: vnode.ssContent && cloneVNode(vnode.ssContent),
+ ssFallback: vnode.ssFallback && cloneVNode(vnode.ssFallback),
+ el: vnode.el,
+ anchor: vnode.anchor
+ };
+}
+/**
+ * @private
+ */
+function createTextVNode(text = ' ', flag = 0) {
+ return createVNode(Text, null, text, flag);
+}
+/**
+ * @private
+ */
+function createStaticVNode(content, numberOfNodes) {
+ // A static vnode can contain multiple stringified elements, and the number
+ // of elements is necessary for hydration.
+ const vnode = createVNode(Static, null, content);
+ vnode.staticCount = numberOfNodes;
+ return vnode;
+}
+/**
+ * @private
+ */
+function createCommentVNode(text = '',
+// when used as the v-else branch, the comment node must be created as a
+// block to ensure correct updates.
+asBlock = false) {
+ return asBlock
+ ? (openBlock(), createBlock(Comment, null, text))
+ : createVNode(Comment, null, text);
+}
+function normalizeVNode(child) {
+ if (child == null || typeof child === 'boolean') {
+ // empty placeholder
+ return createVNode(Comment);
+ }
+ else if (isArray(child)) {
+ // fragment
+ return createVNode(Fragment, null, child);
+ }
+ else if (typeof child === 'object') {
+ // already vnode, this should be the most common since compiled templates
+ // always produce all-vnode children arrays
+ return child.el === null ? child : cloneVNode(child);
+ }
else {
- getter = NOOP;
- (process.env.NODE_ENV !== 'production') && warnInvalidSource(source);
+ // strings and numbers
+ return createVNode(Text, null, String(child));
}
- if (cb && deep) {
- const baseGetter = getter;
- getter = () => traverse(baseGetter());
+}
+// optimized normalization for template-compiled render fns
+function cloneIfMounted(child) {
+ return child.el === null ? child : cloneVNode(child);
+}
+function normalizeChildren(vnode, children) {
+ let type = 0;
+ const { shapeFlag } = vnode;
+ if (children == null) {
+ children = null;
}
- let cleanup;
- const onInvalidate = (fn) => {
- cleanup = runner.options.onStop = () => {
- callWithErrorHandling(fn, instance, 4 /* WATCH_CLEANUP */);
- };
- };
- let oldValue = isArray(source) ? [] : INITIAL_WATCHER_VALUE;
- const job = () => {
- if (!runner.active) {
+ else if (isArray(children)) {
+ type = 16 /* ARRAY_CHILDREN */;
+ }
+ else if (typeof children === 'object') {
+ if (shapeFlag & 1 /* ELEMENT */ || shapeFlag & 64 /* TELEPORT */) {
+ // Normalize slot to plain children for plain element and Teleport
+ const slot = children.default;
+ if (slot) {
+ // _c marker is added by withCtx() indicating this is a compiled slot
+ slot._c && setCompiledSlotRendering(1);
+ normalizeChildren(vnode, slot());
+ slot._c && setCompiledSlotRendering(-1);
+ }
return;
}
- if (cb) {
- // watch(source, cb)
- const newValue = runner();
- if (deep || isRefSource || hasChanged(newValue, oldValue)) {
- // cleanup before running cb again
- if (cleanup) {
- cleanup();
+ else {
+ type = 32 /* SLOTS_CHILDREN */;
+ const slotFlag = children._;
+ if (!slotFlag && !(InternalObjectKey in children)) {
+ children._ctx = currentRenderingInstance;
+ }
+ else if (slotFlag === 3 /* FORWARDED */ && currentRenderingInstance) {
+ // a child component receives forwarded slots from the parent.
+ // its slot type is determined by its parent's slot type.
+ if (currentRenderingInstance.vnode.patchFlag & 1024 /* DYNAMIC_SLOTS */) {
+ children._ = 2 /* DYNAMIC */;
+ vnode.patchFlag |= 1024 /* DYNAMIC_SLOTS */;
+ }
+ else {
+ children._ = 1 /* STABLE */;
}
- callWithAsyncErrorHandling(cb, instance, 3 /* WATCH_CALLBACK */, [
- newValue,
- // pass undefined as the old value when it's changed for the first time
- oldValue === INITIAL_WATCHER_VALUE ? undefined : oldValue,
- onInvalidate
- ]);
- oldValue = newValue;
}
}
- else {
- // watchEffect
- runner();
- }
- };
- // important: mark the job as a watcher callback so that scheduler knows it
- // it is allowed to self-trigger (#1727)
- job.allowRecurse = !!cb;
- let scheduler;
- if (flush === 'sync') {
- scheduler = job;
}
- else if (flush === 'post') {
- scheduler = () => queuePostRenderEffect(job, instance && instance.suspense);
+ else if (isFunction(children)) {
+ children = { default: children, _ctx: currentRenderingInstance };
+ type = 32 /* SLOTS_CHILDREN */;
}
else {
- // default: 'pre'
- scheduler = () => {
- if (!instance || instance.isMounted) {
- queuePreFlushCb(job);
- }
- else {
- // with 'pre' option, the first call must happen before
- // the component is mounted so it is called synchronously.
- job();
- }
- };
- }
- const runner = effect(getter, {
- lazy: true,
- onTrack,
- onTrigger,
- scheduler
- });
- recordInstanceBoundEffect(runner);
- // initial run
- if (cb) {
- if (immediate) {
- job();
+ children = String(children);
+ // force teleport children to array so it can be moved around
+ if (shapeFlag & 64 /* TELEPORT */) {
+ type = 16 /* ARRAY_CHILDREN */;
+ children = [createTextVNode(children)];
}
else {
- oldValue = runner();
+ type = 8 /* TEXT_CHILDREN */;
}
}
- else if (flush === 'post') {
- queuePostRenderEffect(runner, instance && instance.suspense);
- }
- else {
- runner();
- }
- return () => {
- stop(runner);
- if (instance) {
- remove(instance.effects, runner);
- }
- };
-}
-// this.$watch
-function instanceWatch(source, cb, options) {
- const publicThis = this.proxy;
- const getter = isString(source)
- ? () => publicThis[source]
- : source.bind(publicThis);
- return doWatch(getter, cb.bind(publicThis), options, this);
+ vnode.children = children;
+ vnode.shapeFlag |= type;
}
-function traverse(value, seen = new Set()) {
- if (!isObject(value) || seen.has(value)) {
- return value;
- }
- seen.add(value);
- if (isRef(value)) {
- traverse(value.value, seen);
- }
- else if (isArray(value)) {
- for (let i = 0; i < value.length; i++) {
- traverse(value[i], seen);
- }
- }
- else if (isMap(value)) {
- value.forEach((_, key) => {
- // to register mutation dep for existing keys
- traverse(value.get(key), seen);
- });
- }
- else if (isSet(value)) {
- value.forEach(v => {
- traverse(v, seen);
- });
- }
- else {
- for (const key in value) {
- traverse(value[key], seen);
+function mergeProps(...args) {
+ const ret = extend({}, args[0]);
+ for (let i = 1; i < args.length; i++) {
+ const toMerge = args[i];
+ for (const key in toMerge) {
+ if (key === 'class') {
+ if (ret.class !== toMerge.class) {
+ ret.class = normalizeClass([ret.class, toMerge.class]);
+ }
+ }
+ else if (key === 'style') {
+ ret.style = normalizeStyle([ret.style, toMerge.style]);
+ }
+ else if (isOn(key)) {
+ const existing = ret[key];
+ const incoming = toMerge[key];
+ if (existing !== incoming) {
+ ret[key] = existing
+ ? [].concat(existing, toMerge[key])
+ : incoming;
+ }
+ }
+ else if (key !== '') {
+ ret[key] = toMerge[key];
+ }
}
}
- return value;
+ return ret;
}
function provide(key, value) {
@@ -6256,8 +6275,13 @@ function inject(key, defaultValue, treatDefaultAsFactory = false) {
// a functional component
const instance = currentInstance || currentRenderingInstance;
if (instance) {
- const provides = instance.provides;
- if (key in provides) {
+ // #2400
+ // to support `app.use` plugins,
+ // fallback to appContext's `provides` if the intance is at root
+ const provides = instance.parent == null
+ ? instance.vnode.appContext && instance.vnode.appContext.provides
+ : instance.parent.provides;
+ if (provides && key in provides) {
// TS doesn't allow symbol as index type
return provides[key];
}
@@ -6287,7 +6311,7 @@ function createDuplicateChecker() {
};
}
let isInBeforeCreate = false;
-function applyOptions(instance, options, deferredData = [], deferredWatch = [], asMixin = false) {
+function applyOptions(instance, options, deferredData = [], deferredWatch = [], deferredProvide = [], asMixin = false) {
const {
// composition
mixins, extends: extendsOptions,
@@ -6306,18 +6330,18 @@ function applyOptions(instance, options, deferredData = [], deferredWatch = [],
// applyOptions is called non-as-mixin once per instance
if (!asMixin) {
isInBeforeCreate = true;
- callSyncHook('beforeCreate', options, publicThis, globalMixins);
+ callSyncHook('beforeCreate', "bc" /* BEFORE_CREATE */, options, instance, globalMixins);
isInBeforeCreate = false;
// global mixins are applied first
- applyMixins(instance, globalMixins, deferredData, deferredWatch);
+ applyMixins(instance, globalMixins, deferredData, deferredWatch, deferredProvide);
}
// extending a base component...
if (extendsOptions) {
- applyOptions(instance, extendsOptions, deferredData, deferredWatch, true);
+ applyOptions(instance, extendsOptions, deferredData, deferredWatch, deferredProvide, true);
}
// local mixins
if (mixins) {
- applyMixins(instance, mixins, deferredData, deferredWatch);
+ applyMixins(instance, mixins, deferredData, deferredWatch, deferredProvide);
}
const checkDuplicateProperties = (process.env.NODE_ENV !== 'production') ? createDuplicateChecker() : null;
if ((process.env.NODE_ENV !== 'production')) {
@@ -6445,12 +6469,17 @@ function applyOptions(instance, options, deferredData = [], deferredWatch = [],
});
}
if (provideOptions) {
- const provides = isFunction(provideOptions)
- ? provideOptions.call(publicThis)
- : provideOptions;
- for (const key in provides) {
- provide(key, provides[key]);
- }
+ deferredProvide.push(provideOptions);
+ }
+ if (!asMixin && deferredProvide.length) {
+ deferredProvide.forEach(provideOptions => {
+ const provides = isFunction(provideOptions)
+ ? provideOptions.call(publicThis)
+ : provideOptions;
+ for (const key in provides) {
+ provide(key, provides[key]);
+ }
+ });
}
// asset options.
// To reduce memory usage, only components with mixins or extends will have
@@ -6467,7 +6496,7 @@ function applyOptions(instance, options, deferredData = [], deferredWatch = [],
}
// lifecycle options
if (!asMixin) {
- callSyncHook('created', options, publicThis, globalMixins);
+ callSyncHook('created', "c" /* CREATED */, options, instance, globalMixins);
}
if (beforeMount) {
onBeforeMount(beforeMount.bind(publicThis));
@@ -6509,44 +6538,44 @@ function applyOptions(instance, options, deferredData = [], deferredWatch = [],
onUnmounted(unmounted.bind(publicThis));
}
}
-function callSyncHook(name, options, ctx, globalMixins) {
- callHookFromMixins(name, globalMixins, ctx);
+function callSyncHook(name, type, options, instance, globalMixins) {
+ callHookFromMixins(name, type, globalMixins, instance);
const { extends: base, mixins } = options;
if (base) {
- callHookFromExtends(name, base, ctx);
+ callHookFromExtends(name, type, base, instance);
}
if (mixins) {
- callHookFromMixins(name, mixins, ctx);
+ callHookFromMixins(name, type, mixins, instance);
}
const selfHook = options[name];
if (selfHook) {
- selfHook.call(ctx);
+ callWithAsyncErrorHandling(selfHook.bind(instance.proxy), instance, type);
}
}
-function callHookFromExtends(name, base, ctx) {
+function callHookFromExtends(name, type, base, instance) {
if (base.extends) {
- callHookFromExtends(name, base.extends, ctx);
+ callHookFromExtends(name, type, base.extends, instance);
}
const baseHook = base[name];
if (baseHook) {
- baseHook.call(ctx);
+ callWithAsyncErrorHandling(baseHook.bind(instance.proxy), instance, type);
}
}
-function callHookFromMixins(name, mixins, ctx) {
+function callHookFromMixins(name, type, mixins, instance) {
for (let i = 0; i < mixins.length; i++) {
const chainedMixins = mixins[i].mixins;
if (chainedMixins) {
- callHookFromMixins(name, chainedMixins, ctx);
+ callHookFromMixins(name, type, chainedMixins, instance);
}
const fn = mixins[i][name];
if (fn) {
- fn.call(ctx);
+ callWithAsyncErrorHandling(fn.bind(instance.proxy), instance, type);
}
}
}
-function applyMixins(instance, mixins, deferredData, deferredWatch) {
+function applyMixins(instance, mixins, deferredData, deferredWatch, deferredProvide) {
for (let i = 0; i < mixins.length; i++) {
- applyOptions(instance, mixins[i], deferredData, deferredWatch, true);
+ applyOptions(instance, mixins[i], deferredData, deferredWatch, deferredProvide, true);
}
}
function resolveData(instance, dataFn, publicThis) {
@@ -6659,7 +6688,7 @@ const publicPropertiesMap = extend(Object.create(null), {
$emit: i => i.emit,
$options: i => (__VUE_OPTIONS_API__ ? resolveMergedOptions(i) : i.type),
$forceUpdate: i => () => queueJob(i.update),
- $nextTick: () => nextTick,
+ $nextTick: i => nextTick.bind(i.proxy),
$watch: i => (__VUE_OPTIONS_API__ ? instanceWatch.bind(i) : NOOP)
});
const PublicInstanceProxyHandlers = {
@@ -6669,6 +6698,10 @@ const PublicInstanceProxyHandlers = {
if (key === "__v_skip" /* SKIP */) {
return true;
}
+ // for internal formatters to know that this is a Vue instance
+ if ((process.env.NODE_ENV !== 'production') && key === '__isVue') {
+ return true;
+ }
// data / props / ctx
// This getter gets called for every property access on the render context
// during render and is a major hotspot. The most expensive part of this
@@ -7016,7 +7049,7 @@ function setupStatefulComponent(instance, isSSR) {
}
}
// 0. create render proxy property access cache
- instance.accessCache = {};
+ instance.accessCache = Object.create(null);
// 1. create public instance / render proxy
// also mark it raw so it's never observed
instance.proxy = new Proxy(instance.ctx, PublicInstanceProxyHandlers);
@@ -7387,6 +7420,195 @@ const useSSRContext = () => {
}
};
+function initCustomFormatter() {
+ if (!(process.env.NODE_ENV !== 'production') || !true) {
+ return;
+ }
+ const vueStyle = { style: 'color:#3ba776' };
+ const numberStyle = { style: 'color:#0b1bc9' };
+ const stringStyle = { style: 'color:#b62e24' };
+ const keywordStyle = { style: 'color:#9d288c' };
+ // custom formatter for Chrome
+ // https://www.mattzeunert.com/2016/02/19/custom-chrome-devtools-object-formatters.html
+ const formatter = {
+ header(obj) {
+ // TODO also format ComponentPublicInstance & ctx.slots/attrs in setup
+ if (!isObject(obj)) {
+ return null;
+ }
+ if (obj.__isVue) {
+ return ['div', vueStyle, `VueInstance`];
+ }
+ else if (isRef(obj)) {
+ return [
+ 'div',
+ {},
+ ['span', vueStyle, genRefFlag(obj)],
+ '<',
+ formatValue(obj.value),
+ `>`
+ ];
+ }
+ else if (isReactive(obj)) {
+ return [
+ 'div',
+ {},
+ ['span', vueStyle, 'Reactive'],
+ '<',
+ formatValue(obj),
+ `>${isReadonly(obj) ? ` (readonly)` : ``}`
+ ];
+ }
+ else if (isReadonly(obj)) {
+ return [
+ 'div',
+ {},
+ ['span', vueStyle, 'Readonly'],
+ '<',
+ formatValue(obj),
+ '>'
+ ];
+ }
+ return null;
+ },
+ hasBody(obj) {
+ return obj && obj.__isVue;
+ },
+ body(obj) {
+ if (obj && obj.__isVue) {
+ return [
+ 'div',
+ {},
+ ...formatInstance(obj.$)
+ ];
+ }
+ }
+ };
+ function formatInstance(instance) {
+ const blocks = [];
+ if (instance.type.props && instance.props) {
+ blocks.push(createInstanceBlock('props', toRaw(instance.props)));
+ }
+ if (instance.setupState !== EMPTY_OBJ) {
+ blocks.push(createInstanceBlock('setup', instance.setupState));
+ }
+ if (instance.data !== EMPTY_OBJ) {
+ blocks.push(createInstanceBlock('data', toRaw(instance.data)));
+ }
+ const computed = extractKeys(instance, 'computed');
+ if (computed) {
+ blocks.push(createInstanceBlock('computed', computed));
+ }
+ const injected = extractKeys(instance, 'inject');
+ if (injected) {
+ blocks.push(createInstanceBlock('injected', injected));
+ }
+ blocks.push([
+ 'div',
+ {},
+ [
+ 'span',
+ {
+ style: keywordStyle.style + ';opacity:0.66'
+ },
+ '$ (internal): '
+ ],
+ ['object', { object: instance }]
+ ]);
+ return blocks;
+ }
+ function createInstanceBlock(type, target) {
+ target = extend({}, target);
+ if (!Object.keys(target).length) {
+ return ['span', {}];
+ }
+ return [
+ 'div',
+ { style: 'line-height:1.25em;margin-bottom:0.6em' },
+ [
+ 'div',
+ {
+ style: 'color:#476582'
+ },
+ type
+ ],
+ [
+ 'div',
+ {
+ style: 'padding-left:1.25em'
+ },
+ ...Object.keys(target).map(key => {
+ return [
+ 'div',
+ {},
+ ['span', keywordStyle, key + ': '],
+ formatValue(target[key], false)
+ ];
+ })
+ ]
+ ];
+ }
+ function formatValue(v, asRaw = true) {
+ if (typeof v === 'number') {
+ return ['span', numberStyle, v];
+ }
+ else if (typeof v === 'string') {
+ return ['span', stringStyle, JSON.stringify(v)];
+ }
+ else if (typeof v === 'boolean') {
+ return ['span', keywordStyle, v];
+ }
+ else if (isObject(v)) {
+ return ['object', { object: asRaw ? toRaw(v) : v }];
+ }
+ else {
+ return ['span', stringStyle, String(v)];
+ }
+ }
+ function extractKeys(instance, type) {
+ const Comp = instance.type;
+ if (isFunction(Comp)) {
+ return;
+ }
+ const extracted = {};
+ for (const key in instance.ctx) {
+ if (isKeyOfType(Comp, key, type)) {
+ extracted[key] = instance.ctx[key];
+ }
+ }
+ return extracted;
+ }
+ function isKeyOfType(Comp, key, type) {
+ const opts = Comp[type];
+ if ((isArray(opts) && opts.includes(key)) ||
+ (isObject(opts) && key in opts)) {
+ return true;
+ }
+ if (Comp.extends && isKeyOfType(Comp.extends, key, type)) {
+ return true;
+ }
+ if (Comp.mixins && Comp.mixins.some(m => isKeyOfType(m, key, type))) {
+ return true;
+ }
+ }
+ function genRefFlag(v) {
+ if (v._shallow) {
+ return `ShallowRef`;
+ }
+ if (v.effect) {
+ return `ComputedRef`;
+ }
+ return `Ref`;
+ }
+ /* eslint-disable no-restricted-globals */
+ if (window.devtoolsFormatters) {
+ window.devtoolsFormatters.push(formatter);
+ }
+ else {
+ window.devtoolsFormatters = [formatter];
+ }
+}
+
/**
* Actual implementation
*/
@@ -7399,6 +7621,10 @@ function renderList(source, renderItem) {
}
}
else if (typeof source === 'number') {
+ if ((process.env.NODE_ENV !== 'production') && !Number.isInteger(source)) {
+ warn(`The v-for range expect an integer value but got ${source}.`);
+ return [];
+ }
ret = new Array(source);
for (let i = 0; i < source; i++) {
ret[i] = renderItem(i + 1, i);
@@ -7434,7 +7660,7 @@ function toHandlers(obj) {
return ret;
}
for (const key in obj) {
- ret[`on${capitalize(key)}`] = obj[key];
+ ret[toHandlerKey(key)] = obj[key];
}
return ret;
}
@@ -7461,7 +7687,7 @@ function createSlots(slots, dynamicSlots) {
}
// Core API ------------------------------------------------------------------
-const version = "3.0.0";
+const version = "3.0.2";
/**
* SSR utils for \@vue/server-renderer. Only exposed in cjs builds.
* @internal
@@ -7885,11 +8111,9 @@ function useCssVars(getter, scoped = false) {
const prefix = scoped && instance.type.__scopeId
? `${instance.type.__scopeId.replace(/^data-v-/, '')}-`
: ``;
- onMounted(() => {
- watchEffect(() => {
- setVarsOnVNode(instance.subTree, getter(instance.proxy), prefix);
- });
- });
+ const setVars = () => setVarsOnVNode(instance.subTree, getter(instance.proxy), prefix);
+ onMounted(() => watchEffect(setVars));
+ onUpdated(setVars);
}
function setVarsOnVNode(vnode, vars, prefix) {
if ( vnode.shapeFlag & 128 /* SUSPENSE */) {
@@ -8315,8 +8539,7 @@ function trigger$1(el, type) {
// We are exporting the v-model runtime directly as vnode hooks so that it can
// be tree-shaken in case v-model is never used.
const vModelText = {
- created(el, { value, modifiers: { lazy, trim, number } }, vnode) {
- el.value = value == null ? '' : value;
+ created(el, { modifiers: { lazy, trim, number } }, vnode) {
el._assign = getModelAssigner(vnode);
const castToNumber = number || el.type === 'number';
addEventListener(el, lazy ? 'change' : 'input', e => {
@@ -8346,8 +8569,15 @@ const vModelText = {
addEventListener(el, 'change', onCompositionEnd);
}
},
+ // set value on mounted so it's after min/max for type="range"
+ mounted(el, { value }) {
+ el.value = value == null ? '' : value;
+ },
beforeUpdate(el, { value, modifiers: { trim, number } }, vnode) {
el._assign = getModelAssigner(vnode);
+ // avoid clearing unresolved text. #2302
+ if (el.composing)
+ return;
if (document.activeElement === el) {
if (trim && el.value.trim() === value) {
return;
@@ -8384,13 +8614,11 @@ const vModelCheckbox = {
}
}
else if (isSet(modelValue)) {
- const found = modelValue.has(elementValue);
- if (checked && !found) {
- assign(modelValue.add(elementValue));
+ if (checked) {
+ modelValue.add(elementValue);
}
- else if (!checked && found) {
+ else {
modelValue.delete(elementValue);
- assign(modelValue);
}
}
else {
@@ -8409,7 +8637,7 @@ function setChecked(el, { value, oldValue }, vnode) {
el.checked = looseIndexOf(value, vnode.props.value) > -1;
}
else if (isSet(value)) {
- el.checked = looseHas(value, vnode.props.value);
+ el.checked = value.has(vnode.props.value);
}
else if (value !== oldValue) {
el.checked = looseEqual(value, getCheckboxValue(el, true));
@@ -8431,11 +8659,11 @@ const vModelRadio = {
}
};
const vModelSelect = {
- created(el, binding, vnode) {
+ created(el, { modifiers: { number } }, vnode) {
addEventListener(el, 'change', () => {
const selectedVal = Array.prototype.filter
.call(el.options, (o) => o.selected)
- .map(getValue);
+ .map((o) => number ? toNumber(getValue(o)) : getValue(o));
el._assign(el.multiple ? selectedVal : selectedVal[0]);
});
el._assign = getModelAssigner(vnode);
@@ -8468,7 +8696,7 @@ function setSelected(el, value) {
option.selected = looseIndexOf(value, optionValue) > -1;
}
else {
- option.selected = looseHas(value, optionValue);
+ option.selected = value.has(optionValue);
}
}
else {
@@ -8712,6 +8940,7 @@ function initDev() {
{
console.info(`You are running a development build of Vue.\n` +
`Make sure to use the production build (*.prod.js) when deploying for production.`);
+ initCustomFormatter();
}
}
@@ -8725,4 +8954,4 @@ const compile$1 = () => {
}
};
-export { BaseTransition, Comment, Fragment, KeepAlive, Static, Suspense, Teleport, Text, Transition, TransitionGroup, callWithAsyncErrorHandling, callWithErrorHandling, cloneVNode, compile$1 as compile, computed$1 as computed, createApp, createBlock, createCommentVNode, createHydrationRenderer, createRenderer, createSSRApp, createSlots, createStaticVNode, createTextVNode, createVNode, customRef, defineAsyncComponent, defineComponent, devtools, getCurrentInstance, getTransitionRawChildren, h, handleError, hydrate, inject, injectHook, isInSSRComponentSetup, isProxy, isReactive, isReadonly, isRef, isVNode, markRaw, mergeProps, nextTick, onActivated, onBeforeMount, onBeforeUnmount, onBeforeUpdate, onDeactivated, onErrorCaptured, onMounted, onRenderTracked, onRenderTriggered, onUnmounted, onUpdated, openBlock, popScopeId, provide, proxyRefs, pushScopeId, queuePostFlushCb, reactive, readonly, ref, registerRuntimeCompiler, render, renderList, renderSlot, resolveComponent, resolveDirective, resolveDynamicComponent, resolveTransitionHooks, setBlockTracking, setDevtoolsHook, setTransitionHooks, shallowReactive, shallowReadonly, shallowRef, ssrContextKey, ssrUtils, toHandlers, toRaw, toRef, toRefs, transformVNodeArgs, triggerRef, unref, useCssModule, useCssVars, useSSRContext, useTransitionState, vModelCheckbox, vModelDynamic, vModelRadio, vModelSelect, vModelText, vShow, version, warn, watch, watchEffect, withCtx, withDirectives, withKeys, withModifiers, withScopeId };
+export { BaseTransition, Comment, Fragment, KeepAlive, Static, Suspense, Teleport, Text, Transition, TransitionGroup, callWithAsyncErrorHandling, callWithErrorHandling, cloneVNode, compile$1 as compile, computed$1 as computed, createApp, createBlock, createCommentVNode, createHydrationRenderer, createRenderer, createSSRApp, createSlots, createStaticVNode, createTextVNode, createVNode, customRef, defineAsyncComponent, defineComponent, devtools, getCurrentInstance, getTransitionRawChildren, h, handleError, hydrate, initCustomFormatter, inject, injectHook, isInSSRComponentSetup, isProxy, isReactive, isReadonly, isRef, isVNode, markRaw, mergeProps, nextTick, onActivated, onBeforeMount, onBeforeUnmount, onBeforeUpdate, onDeactivated, onErrorCaptured, onMounted, onRenderTracked, onRenderTriggered, onUnmounted, onUpdated, openBlock, popScopeId, provide, proxyRefs, pushScopeId, queuePostFlushCb, reactive, readonly, ref, registerRuntimeCompiler, render, renderList, renderSlot, resolveComponent, resolveDirective, resolveDynamicComponent, resolveTransitionHooks, setBlockTracking, setDevtoolsHook, setTransitionHooks, shallowReactive, shallowReadonly, shallowRef, ssrContextKey, ssrUtils, toHandlers, toRaw, toRef, toRefs, transformVNodeArgs, triggerRef, unref, useCssModule, useCssVars, useSSRContext, useTransitionState, vModelCheckbox, vModelDynamic, vModelRadio, vModelSelect, vModelText, vShow, version, warn, watch, watchEffect, withCtx, withDirectives, withKeys, withModifiers, withScopeId };
diff --git a/packages/uni-h5/dist/uni-h5.esm.js b/packages/uni-h5/dist/uni-h5.esm.js
index 506610fb4f76ae48aefa2f9ffdb394aac3ff2715..cafbfe4717efe2be37b48b46e3619fd906c4f832 100644
--- a/packages/uni-h5/dist/uni-h5.esm.js
+++ b/packages/uni-h5/dist/uni-h5.esm.js
@@ -1544,6 +1544,192 @@ const canIUse = /* @__PURE__ */ createApi({type: API_TYPE_SYNC, name: "canIUse"}
const makePhoneCall = /* @__PURE__ */ createApi({type: API_TYPE_ASYNC, name: "makePhoneCall"}, (option) => {
window.location.href = `tel:${option.phoneNumber}`;
}, MakePhoneCallProtocol);
+var attrs$1 = ["top", "left", "right", "bottom"];
+var inited$1;
+var elementComputedStyle$1 = {};
+var support$1;
+function getSupport$1() {
+ if (!("CSS" in window) || typeof CSS.supports != "function") {
+ support$1 = "";
+ } else if (CSS.supports("top: env(safe-area-inset-top)")) {
+ support$1 = "env";
+ } else if (CSS.supports("top: constant(safe-area-inset-top)")) {
+ support$1 = "constant";
+ } else {
+ support$1 = "";
+ }
+ return support$1;
+}
+function init$1() {
+ support$1 = typeof support$1 === "string" ? support$1 : getSupport$1();
+ if (!support$1) {
+ attrs$1.forEach(function(attr) {
+ elementComputedStyle$1[attr] = 0;
+ });
+ return;
+ }
+ function setStyle(el, style) {
+ var elStyle = el.style;
+ Object.keys(style).forEach(function(key) {
+ var val = style[key];
+ elStyle[key] = val;
+ });
+ }
+ var cbs = [];
+ function parentReady(callback) {
+ if (callback) {
+ cbs.push(callback);
+ } else {
+ cbs.forEach(function(cb) {
+ cb();
+ });
+ }
+ }
+ var passiveEvents = false;
+ try {
+ var opts = Object.defineProperty({}, "passive", {
+ get: function() {
+ passiveEvents = {passive: true};
+ }
+ });
+ window.addEventListener("test", null, opts);
+ } catch (e) {
+ }
+ function addChild(parent, attr) {
+ var a1 = document.createElement("div");
+ var a2 = document.createElement("div");
+ var a1Children = document.createElement("div");
+ var a2Children = document.createElement("div");
+ var W = 100;
+ var MAX = 1e4;
+ var aStyle = {
+ position: "absolute",
+ width: W + "px",
+ height: "200px",
+ boxSizing: "border-box",
+ overflow: "hidden",
+ paddingBottom: support$1 + "(safe-area-inset-" + attr + ")"
+ };
+ setStyle(a1, aStyle);
+ setStyle(a2, aStyle);
+ setStyle(a1Children, {
+ transition: "0s",
+ animation: "none",
+ width: "400px",
+ height: "400px"
+ });
+ setStyle(a2Children, {
+ transition: "0s",
+ animation: "none",
+ width: "250%",
+ height: "250%"
+ });
+ a1.appendChild(a1Children);
+ a2.appendChild(a2Children);
+ parent.appendChild(a1);
+ parent.appendChild(a2);
+ parentReady(function() {
+ a1.scrollTop = a2.scrollTop = MAX;
+ var a1LastScrollTop = a1.scrollTop;
+ var a2LastScrollTop = a2.scrollTop;
+ function onScroll() {
+ if (this.scrollTop === (this === a1 ? a1LastScrollTop : a2LastScrollTop)) {
+ return;
+ }
+ a1.scrollTop = a2.scrollTop = MAX;
+ a1LastScrollTop = a1.scrollTop;
+ a2LastScrollTop = a2.scrollTop;
+ attrChange$1(attr);
+ }
+ a1.addEventListener("scroll", onScroll, passiveEvents);
+ a2.addEventListener("scroll", onScroll, passiveEvents);
+ });
+ var computedStyle = getComputedStyle(a1);
+ Object.defineProperty(elementComputedStyle$1, attr, {
+ configurable: true,
+ get: function() {
+ return parseFloat(computedStyle.paddingBottom);
+ }
+ });
+ }
+ var parentDiv = document.createElement("div");
+ setStyle(parentDiv, {
+ position: "absolute",
+ left: "0",
+ top: "0",
+ width: "0",
+ height: "0",
+ zIndex: "-1",
+ overflow: "hidden",
+ visibility: "hidden"
+ });
+ attrs$1.forEach(function(key) {
+ addChild(parentDiv, key);
+ });
+ document.body.appendChild(parentDiv);
+ parentReady();
+ inited$1 = true;
+}
+function getAttr$1(attr) {
+ if (!inited$1) {
+ init$1();
+ }
+ return elementComputedStyle$1[attr];
+}
+var changeAttrs$1 = [];
+function attrChange$1(attr) {
+ if (!changeAttrs$1.length) {
+ setTimeout(function() {
+ var style = {};
+ changeAttrs$1.forEach(function(attr2) {
+ style[attr2] = elementComputedStyle$1[attr2];
+ });
+ changeAttrs$1.length = 0;
+ callbacks$1.forEach(function(callback) {
+ callback(style);
+ });
+ }, 0);
+ }
+ changeAttrs$1.push(attr);
+}
+var callbacks$1 = [];
+function onChange$1(callback) {
+ if (!getSupport$1()) {
+ return;
+ }
+ if (!inited$1) {
+ init$1();
+ }
+ if (typeof callback === "function") {
+ callbacks$1.push(callback);
+ }
+}
+function offChange$1(callback) {
+ var index2 = callbacks$1.indexOf(callback);
+ if (index2 >= 0) {
+ callbacks$1.splice(index2, 1);
+ }
+}
+var safeAreaInsets$1 = {
+ get support() {
+ return (typeof support$1 === "string" ? support$1 : getSupport$1()).length != 0;
+ },
+ get top() {
+ return getAttr$1("top");
+ },
+ get left() {
+ return getAttr$1("left");
+ },
+ get right() {
+ return getAttr$1("right");
+ },
+ get bottom() {
+ return getAttr$1("bottom");
+ },
+ onChange: onChange$1,
+ offChange: offChange$1
+};
+var out$1 = safeAreaInsets$1;
const ua = navigator.userAgent;
const isAndroid = /android/i.test(ua);
const isIOS$1 = /iphone|ipad|ipod/i.test(ua);
@@ -1557,7 +1743,7 @@ const getSystemInfoSync = /* @__PURE__ */ createApi({type: API_TYPE_SYNC}, () =>
var windowWidth = Math.min(window.innerWidth, document.documentElement.clientWidth, screenWidth) || screenWidth;
var windowHeight = window.innerHeight;
var language = navigator.language;
- var statusBarHeight = out.top;
+ var statusBarHeight = out$1.top;
var osname;
var osversion;
var model;
@@ -1616,12 +1802,12 @@ const getSystemInfoSync = /* @__PURE__ */ createApi({type: API_TYPE_SYNC}, () =>
var system = `${osname} ${osversion}`;
var platform = osname.toLocaleLowerCase();
var safeArea = {
- left: out.left,
- right: windowWidth - out.right,
- top: out.top,
- bottom: windowHeight - out.bottom,
- width: windowWidth - out.left - out.right,
- height: windowHeight - out.top - out.bottom
+ left: out$1.left,
+ right: windowWidth - out$1.right,
+ top: out$1.top,
+ bottom: windowHeight - out$1.bottom,
+ width: windowWidth - out$1.left - out$1.right,
+ height: windowHeight - out$1.top - out$1.bottom
};
const {top: windowTop, bottom: windowBottom} = getWindowOffset();
windowHeight -= windowTop;
@@ -1641,10 +1827,10 @@ const getSystemInfoSync = /* @__PURE__ */ createApi({type: API_TYPE_SYNC}, () =>
model,
safeArea,
safeAreaInsets: {
- top: out.top,
- right: out.right,
- bottom: out.bottom,
- left: out.left
+ top: out$1.top,
+ right: out$1.right,
+ bottom: out$1.bottom,
+ left: out$1.left
}
};
});
@@ -2763,7 +2949,7 @@ var script$8 = {
}, this.pullToRefresh);
let offset = uni.upx2px(refreshOptions.offset);
if (titleNView.type !== "none" && titleNView.type !== "transparent") {
- offset += NAVBAR_HEIGHT + out.top;
+ offset += NAVBAR_HEIGHT + out$1.top;
}
refreshOptions.offset = offset;
refreshOptions.height = uni.upx2px(refreshOptions.height);
diff --git a/packages/uni-mp-alipay/dist/uni.api.esm.js b/packages/uni-mp-alipay/dist/uni.api.esm.js
index 28f3b67135413237bc31344a021c86e3f6af042e..78a3a371577ae825532610bf7a21f3821938842e 100644
--- a/packages/uni-mp-alipay/dist/uni.api.esm.js
+++ b/packages/uni-mp-alipay/dist/uni.api.esm.js
@@ -450,19 +450,7 @@ function addSafeAreaInsets(fromRes, toRes) {
};
}
}
-const redirectTo = {};
-const createCanvasContext = {
- returnValue(fromRes, toRes) {
- const measureText = fromRes.measureText;
- toRes.measureText = function (text, callback) {
- const textMetrics = measureText.call(this, text);
- if (typeof callback === 'function') {
- setTimeout(() => callback(textMetrics), 0);
- }
- return textMetrics;
- };
- }
-};
+const redirectTo = {};
const getProvider = initGetProvider({
oauth: ['alipay'],
@@ -1050,8 +1038,7 @@ var protocols = /*#__PURE__*/Object.freeze({
saveImageToPhotosAlbum: saveImageToPhotosAlbum,
saveVideoToPhotosAlbum: saveVideoToPhotosAlbum,
chooseAddress: chooseAddress,
- redirectTo: redirectTo,
- createCanvasContext: createCanvasContext
+ redirectTo: redirectTo
});
var index = initUni(shims, protocols);
diff --git a/packages/uni-mp-baidu/dist/uni.api.esm.js b/packages/uni-mp-baidu/dist/uni.api.esm.js
index 5801e1d58e8d03a805413cc6d44ce119d4a0ec0e..5b5a1dc57489ebb636349fc714a174c4bb26c010 100644
--- a/packages/uni-mp-baidu/dist/uni.api.esm.js
+++ b/packages/uni-mp-baidu/dist/uni.api.esm.js
@@ -487,19 +487,7 @@ const getSystemInfo = {
returnValue: addSafeAreaInsets
};
const getSystemInfoSync = getSystemInfo;
-const redirectTo = {};
-const createCanvasContext = {
- returnValue(fromRes, toRes) {
- const measureText = fromRes.measureText;
- toRes.measureText = function (text, callback) {
- const textMetrics = measureText.call(this, text);
- if (typeof callback === 'function') {
- setTimeout(() => callback(textMetrics), 0);
- }
- return textMetrics;
- };
- }
-};
+const redirectTo = {};
const getProvider = initGetProvider({
oauth: ['baidu'],
@@ -617,8 +605,7 @@ var protocols = /*#__PURE__*/Object.freeze({
redirectTo: redirectTo,
previewImage: previewImage,
getSystemInfo: getSystemInfo,
- getSystemInfoSync: getSystemInfoSync,
- createCanvasContext: createCanvasContext
+ getSystemInfoSync: getSystemInfoSync
});
var index = initUni(shims, protocols);
diff --git a/packages/uni-mp-qq/dist/uni.api.esm.js b/packages/uni-mp-qq/dist/uni.api.esm.js
index ef851c82502cca509449e7007e1ad60263d616c6..e733ecaf530e597f90dcf972adad4af6d4f708e1 100644
--- a/packages/uni-mp-qq/dist/uni.api.esm.js
+++ b/packages/uni-mp-qq/dist/uni.api.esm.js
@@ -487,19 +487,7 @@ const getSystemInfo = {
returnValue: addSafeAreaInsets
};
const getSystemInfoSync = getSystemInfo;
-const redirectTo = {};
-const createCanvasContext = {
- returnValue(fromRes, toRes) {
- const measureText = fromRes.measureText;
- toRes.measureText = function (text, callback) {
- const textMetrics = measureText.call(this, text);
- if (typeof callback === 'function') {
- setTimeout(() => callback(textMetrics), 0);
- }
- return textMetrics;
- };
- }
-};
+const redirectTo = {};
const getProvider = initGetProvider({
oauth: ['qq'],
@@ -518,8 +506,7 @@ var protocols = /*#__PURE__*/Object.freeze({
redirectTo: redirectTo,
previewImage: previewImage,
getSystemInfo: getSystemInfo,
- getSystemInfoSync: getSystemInfoSync,
- createCanvasContext: createCanvasContext
+ getSystemInfoSync: getSystemInfoSync
});
var index = initUni(shims, protocols);
diff --git a/packages/uni-mp-toutiao/dist/uni.api.esm.js b/packages/uni-mp-toutiao/dist/uni.api.esm.js
index 9d0ce5b125f44531ebb1cfac363ddfa5481437fb..fb3735dd5c4ed3e6c3fee28900c292c2ac2cf277 100644
--- a/packages/uni-mp-toutiao/dist/uni.api.esm.js
+++ b/packages/uni-mp-toutiao/dist/uni.api.esm.js
@@ -472,19 +472,7 @@ const previewImage = {
};
}
};
-const redirectTo = {};
-const createCanvasContext = {
- returnValue(fromRes, toRes) {
- const measureText = fromRes.measureText;
- toRes.measureText = function (text, callback) {
- const textMetrics = measureText.call(this, text);
- if (typeof callback === 'function') {
- setTimeout(() => callback(textMetrics), 0);
- }
- return textMetrics;
- };
- }
-};
+const redirectTo = {};
const getProvider = initGetProvider({
oauth: ['toutiao'],
@@ -586,8 +574,7 @@ var protocols = /*#__PURE__*/Object.freeze({
requestPayment: requestPayment,
getFileInfo: getFileInfo,
redirectTo: redirectTo,
- previewImage: previewImage,
- createCanvasContext: createCanvasContext
+ previewImage: previewImage
});
var index = initUni(shims, protocols);
diff --git a/packages/uni-mp-vue/dist/vue.runtime.esm.js b/packages/uni-mp-vue/dist/vue.runtime.esm.js
index 0846d821befd41ecf467ccb61e264624461f81bb..ea915ea550a92e6dae3da5aa2616bff1665ae242 100644
--- a/packages/uni-mp-vue/dist/vue.runtime.esm.js
+++ b/packages/uni-mp-vue/dist/vue.runtime.esm.js
@@ -1,4 +1,4 @@
-import { isSymbol, extend, isMap, isObject, toRawType, def, isArray, isString, isFunction, isPromise, capitalize, remove, EMPTY_OBJ, NOOP, isGloballyWhitelisted, isIntegerKey, hasOwn, hasChanged, NO, invokeArrayFns, isSet, makeMap, hyphenate, isReservedProp, camelize, EMPTY_ARR, toTypeString, isOn } from '@vue/shared';
+import { isSymbol, extend, isMap, isObject, toRawType, def, isArray, isString, isFunction, isPromise, toHandlerKey, remove, EMPTY_OBJ, NOOP, isGloballyWhitelisted, isIntegerKey, hasOwn, hasChanged, capitalize, NO, invokeArrayFns, isSet, makeMap, toNumber, hyphenate, camelize, isReservedProp, EMPTY_ARR, toTypeString, isOn } from '@vue/shared';
export { camelize } from '@vue/shared';
const targetMap = new WeakMap();
@@ -50,6 +50,7 @@ function createReactiveEffect(fn, options) {
}
};
effect.id = uid++;
+ effect.allowRecurse = !!options.allowRecurse;
effect._isEffect = true;
effect.active = true;
effect.raw = fn;
@@ -115,7 +116,7 @@ function trigger(target, type, key, newValue, oldValue, oldTarget) {
const add = (effectsToAdd) => {
if (effectsToAdd) {
effectsToAdd.forEach(effect => {
- if (effect !== activeEffect || effect.options.allowRecurse) {
+ if (effect !== activeEffect || effect.allowRecurse) {
effects.add(effect);
}
});
@@ -220,7 +221,7 @@ const arrayInstrumentations = {};
arrayInstrumentations[key] = function (...args) {
pauseTracking();
const res = method.apply(this, args);
- enableTracking();
+ resetTracking();
return res;
};
});
@@ -241,8 +242,7 @@ function createGetter(isReadonly = false, shallow = false) {
return Reflect.get(arrayInstrumentations, key, receiver);
}
const res = Reflect.get(target, key, receiver);
- const keyIsSymbol = isSymbol(key);
- if (keyIsSymbol
+ if (isSymbol(key)
? builtInSymbols.has(key)
: key === `__proto__` || key === `__v_isRef`) {
return res;
@@ -312,7 +312,7 @@ function has(target, key) {
return result;
}
function ownKeys(target) {
- track(target, "iterate" /* ITERATE */, ITERATE_KEY);
+ track(target, "iterate" /* ITERATE */, isArray(target) ? 'length' : ITERATE_KEY);
return Reflect.ownKeys(target);
}
const mutableHandlers = {
@@ -595,7 +595,7 @@ function checkIdentityKeys(target, has, key) {
if (rawKey !== key && has.call(target, rawKey)) {
const type = toRawType(target);
console.warn(`Reactive ${type} contains both the raw and reactive ` +
- `versions of the same object${type === `Map` ? `as keys` : ``}, ` +
+ `versions of the same object${type === `Map` ? ` as keys` : ``}, ` +
`which can lead to inconsistencies. ` +
`Avoid differentiating between the raw and reactive versions ` +
`of an object and only use the reactive version if possible.`);
@@ -730,7 +730,7 @@ function createRef(rawValue, shallow = false) {
return new RefImpl(rawValue, shallow);
}
function triggerRef(ref) {
- trigger(ref, "set" /* SET */, 'value', (process.env.NODE_ENV !== 'production') ? ref.value : void 0);
+ trigger(toRaw(ref), "set" /* SET */, 'value', (process.env.NODE_ENV !== 'production') ? ref.value : void 0);
}
function unref(ref) {
return isRef(ref) ? ref.value : ref;
@@ -1028,7 +1028,7 @@ function handleError(err, instance, type, throwInDev = true) {
const errorCapturedHooks = cur.ec;
if (errorCapturedHooks) {
for (let i = 0; i < errorCapturedHooks.length; i++) {
- if (errorCapturedHooks[i](err, exposedInstance, errorInfo)) {
+ if (errorCapturedHooks[i](err, exposedInstance, errorInfo) === false) {
return;
}
}
@@ -1086,7 +1086,7 @@ let currentPreFlushParentJob = null;
const RECURSION_LIMIT = 100;
function nextTick(fn) {
const p = currentFlushPromise || resolvedPromise;
- return fn ? p.then(fn) : p;
+ return fn ? p.then(this ? fn.bind(this) : fn) : p;
}
function queueJob(job) {
// the dedupe search uses the startIndex argument of Array.includes()
@@ -1235,21 +1235,21 @@ function checkRecursiveUpdates(seen, fn) {
}
}
-function emit(instance, event, ...args) {
+function emit(instance, event, ...rawArgs) {
const props = instance.vnode.props || EMPTY_OBJ;
if ((process.env.NODE_ENV !== 'production')) {
const { emitsOptions, propsOptions: [propsOptions] } = instance;
if (emitsOptions) {
if (!(event in emitsOptions)) {
- if (!propsOptions || !(`on` + capitalize(event) in propsOptions)) {
+ if (!propsOptions || !(toHandlerKey(event) in propsOptions)) {
warn(`Component emitted event "${event}" but it is neither declared in ` +
- `the emits option nor as an "on${capitalize(event)}" prop.`);
+ `the emits option nor as an "${toHandlerKey(event)}" prop.`);
}
}
else {
const validator = emitsOptions[event];
if (isFunction(validator)) {
- const isValid = validator(...args);
+ const isValid = validator(...rawArgs);
if (!isValid) {
warn(`Invalid event arguments: event validation failed for event "${event}".`);
}
@@ -1257,34 +1257,57 @@ function emit(instance, event, ...args) {
}
}
}
+ let args = rawArgs;
+ const isModelListener = event.startsWith('update:');
+ // for v-model update:xxx events, apply modifiers on args
+ const modelArg = isModelListener && event.slice(7);
+ if (modelArg && modelArg in props) {
+ const modifiersKey = `${modelArg === 'modelValue' ? 'model' : modelArg}Modifiers`;
+ const { number, trim } = props[modifiersKey] || EMPTY_OBJ;
+ if (trim) {
+ args = rawArgs.map(a => a.trim());
+ }
+ else if (number) {
+ args = rawArgs.map(toNumber);
+ }
+ }
if ((process.env.NODE_ENV !== 'production') || false) ;
- let handlerName = `on${capitalize(event)}`;
+ if ((process.env.NODE_ENV !== 'production')) {
+ const lowerCaseEvent = event.toLowerCase();
+ if (lowerCaseEvent !== event && props[toHandlerKey(lowerCaseEvent)]) {
+ warn(`Event "${lowerCaseEvent}" is emitted in component ` +
+ `${formatComponentName(instance, instance.type)} but the handler is registered for "${event}". ` +
+ `Note that HTML attributes are case-insensitive and you cannot use ` +
+ `v-on to listen to camelCase events when using in-DOM templates. ` +
+ `You should probably use "${hyphenate(event)}" instead of "${event}".`);
+ }
+ }
+ // convert handler name to camelCase. See issue #2249
+ let handlerName = toHandlerKey(camelize(event));
let handler = props[handlerName];
// for v-model update:xxx events, also trigger kebab-case equivalent
// for props passed via kebab-case
- if (!handler && event.startsWith('update:')) {
- handlerName = `on${capitalize(hyphenate(event))}`;
+ if (!handler && isModelListener) {
+ handlerName = toHandlerKey(hyphenate(event));
handler = props[handlerName];
}
- if (!handler) {
- handler = props[handlerName + `Once`];
+ if (handler) {
+ callWithAsyncErrorHandling(handler, instance, 6 /* COMPONENT_EVENT_HANDLER */, args);
+ }
+ const onceHandler = props[handlerName + `Once`];
+ if (onceHandler) {
if (!instance.emitted) {
(instance.emitted = {})[handlerName] = true;
}
else if (instance.emitted[handlerName]) {
return;
}
- }
- if (handler) {
- callWithAsyncErrorHandling(handler, instance, 6 /* COMPONENT_EVENT_HANDLER */, args);
+ callWithAsyncErrorHandling(onceHandler, instance, 6 /* COMPONENT_EVENT_HANDLER */, args);
}
}
function normalizeEmitsOptions(comp, appContext, asMixin = false) {
- const appId = appContext.app ? appContext.app._uid : -1;
- const cache = comp.__emits || (comp.__emits = {});
- const cached = cache[appId];
- if (cached !== undefined) {
- return cached;
+ if (!appContext.deopt && comp.__emits !== undefined) {
+ return comp.__emits;
}
const raw = comp.emits;
let normalized = {};
@@ -1306,7 +1329,7 @@ function normalizeEmitsOptions(comp, appContext, asMixin = false) {
}
}
if (!raw && !hasExtends) {
- return (cache[appId] = null);
+ return (comp.__emits = null);
}
if (isArray(raw)) {
raw.forEach(key => (normalized[key] = null));
@@ -1314,7 +1337,7 @@ function normalizeEmitsOptions(comp, appContext, asMixin = false) {
else {
extend(normalized, raw);
}
- return (cache[appId] = normalized);
+ return (comp.__emits = normalized);
}
// Check if an incoming prop key is a declared emit event listener.
// e.g. With `emits: { click: null }`, props named `onClick` and `onclick` are
@@ -1422,11 +1445,8 @@ function resolvePropValue(options, props, key, value, instance) {
return value;
}
function normalizePropsOptions(comp, appContext, asMixin = false) {
- const appId = appContext.app ? appContext.app._uid : -1;
- const cache = comp.__props || (comp.__props = {});
- const cached = cache[appId];
- if (cached) {
- return cached;
+ if (!appContext.deopt && comp.__props) {
+ return comp.__props;
}
const raw = comp.props;
const normalized = {};
@@ -1452,7 +1472,7 @@ function normalizePropsOptions(comp, appContext, asMixin = false) {
}
}
if (!raw && !hasExtends) {
- return (cache[appId] = EMPTY_ARR);
+ return (comp.__props = EMPTY_ARR);
}
if (isArray(raw)) {
for (let i = 0; i < raw.length; i++) {
@@ -1489,7 +1509,16 @@ function normalizePropsOptions(comp, appContext, asMixin = false) {
}
}
}
- return (cache[appId] = [normalized, needCastKeys]);
+ return (comp.__props = [normalized, needCastKeys]);
+}
+function validatePropName(key) {
+ if (key[0] !== '$') {
+ return true;
+ }
+ else if ((process.env.NODE_ENV !== 'production')) {
+ warn(`Invalid prop name: "${key}" is a reserved property.`);
+ }
+ return false;
}
// use function string name to check type constructors
// so that it works across vms / iframes.
@@ -1526,18 +1555,6 @@ function validateProps(props, instance) {
validateProp(key, rawValues[key], opt, !hasOwn(rawValues, key));
}
}
-/**
- * dev only
- */
-function validatePropName(key) {
- if (key[0] !== '$') {
- return true;
- }
- else if ((process.env.NODE_ENV !== 'production')) {
- warn(`Invalid prop name: "${key}" is a reserved property.`);
- }
- return false;
-}
/**
* dev only
*/
@@ -1685,7 +1702,7 @@ function injectHook(type, hook, target = currentInstance, prepend = false) {
return wrappedHook;
}
else if ((process.env.NODE_ENV !== 'production')) {
- const apiName = `on${capitalize(ErrorTypeStrings[type].replace(/ hook$/, ''))}`;
+ const apiName = toHandlerKey(ErrorTypeStrings[type].replace(/ hook$/, ''));
warn(`${apiName} is called when there is no active component instance to be ` +
`associated with. ` +
`Lifecycle injection APIs can only be used during execution of setup().` +
@@ -1841,6 +1858,11 @@ function createAppAPI() {
if (__VUE_OPTIONS_API__) {
if (!context.mixins.includes(mixin)) {
context.mixins.push(mixin);
+ // global mixin with props/emits de-optimizes props/emits
+ // normalization caching.
+ if (mixin.props || mixin.emits) {
+ context.deopt = true;
+ }
}
else if ((process.env.NODE_ENV !== 'production')) {
warn('Mixin has already been applied to target app' +
@@ -1930,9 +1952,10 @@ function doWatch(source, cb, { immediate, deep, flush, onTrack, onTrigger } = EM
`a reactive object, or an array of these types.`);
};
let getter;
- const isRefSource = isRef(source);
- if (isRefSource) {
+ let forceTrigger = false;
+ if (isRef(source)) {
getter = () => source.value;
+ forceTrigger = !!source._shallow;
}
else if (isReactive(source)) {
getter = () => source;
@@ -1994,7 +2017,7 @@ function doWatch(source, cb, { immediate, deep, flush, onTrack, onTrigger } = EM
if (cb) {
// watch(source, cb)
const newValue = runner();
- if (deep || isRefSource || hasChanged(newValue, oldValue)) {
+ if (deep || forceTrigger || hasChanged(newValue, oldValue)) {
// cleanup before running cb again
if (cleanup) {
cleanup();
@@ -2013,7 +2036,7 @@ function doWatch(source, cb, { immediate, deep, flush, onTrack, onTrigger } = EM
runner();
}
};
- // important: mark the job as a watcher callback so that scheduler knows it
+ // important: mark the job as a watcher callback so that scheduler knows
// it is allowed to self-trigger (#1727)
job.allowRecurse = !!cb;
let scheduler;
@@ -2086,14 +2109,8 @@ function traverse(value, seen = new Set()) {
traverse(value[i], seen);
}
}
- else if (isMap(value)) {
- value.forEach((_, key) => {
- // to register mutation dep for existing keys
- traverse(value.get(key), seen);
- });
- }
- else if (isSet(value)) {
- value.forEach(v => {
+ else if (isSet(value) || isMap(value)) {
+ value.forEach((v) => {
traverse(v, seen);
});
}
@@ -2131,8 +2148,13 @@ function inject(key, defaultValue, treatDefaultAsFactory = false) {
// a functional component
const instance = currentInstance || currentRenderingInstance;
if (instance) {
- const provides = instance.provides;
- if (key in provides) {
+ // #2400
+ // to support `app.use` plugins,
+ // fallback to appContext's `provides` if the intance is at root
+ const provides = instance.parent == null
+ ? instance.vnode.appContext && instance.vnode.appContext.provides
+ : instance.parent.provides;
+ if (provides && key in provides) {
// TS doesn't allow symbol as index type
return provides[key];
}
@@ -2162,7 +2184,7 @@ function createDuplicateChecker() {
};
}
let isInBeforeCreate = false;
-function applyOptions(instance, options, deferredData = [], deferredWatch = [], asMixin = false) {
+function applyOptions(instance, options, deferredData = [], deferredWatch = [], deferredProvide = [], asMixin = false) {
const {
// composition
mixins, extends: extendsOptions,
@@ -2181,18 +2203,18 @@ function applyOptions(instance, options, deferredData = [], deferredWatch = [],
// applyOptions is called non-as-mixin once per instance
if (!asMixin) {
isInBeforeCreate = true;
- callSyncHook('beforeCreate', options, publicThis, globalMixins);
+ callSyncHook('beforeCreate', "bc" /* BEFORE_CREATE */, options, instance, globalMixins);
isInBeforeCreate = false;
// global mixins are applied first
- applyMixins(instance, globalMixins, deferredData, deferredWatch);
+ applyMixins(instance, globalMixins, deferredData, deferredWatch, deferredProvide);
}
// extending a base component...
if (extendsOptions) {
- applyOptions(instance, extendsOptions, deferredData, deferredWatch, true);
+ applyOptions(instance, extendsOptions, deferredData, deferredWatch, deferredProvide, true);
}
// local mixins
if (mixins) {
- applyMixins(instance, mixins, deferredData, deferredWatch);
+ applyMixins(instance, mixins, deferredData, deferredWatch, deferredProvide);
}
const checkDuplicateProperties = (process.env.NODE_ENV !== 'production') ? createDuplicateChecker() : null;
if ((process.env.NODE_ENV !== 'production')) {
@@ -2321,12 +2343,19 @@ function applyOptions(instance, options, deferredData = [], deferredWatch = [],
});
}
// fixed by xxxxxx
- if (!__VUE_CREATED_DEFERRED__ && provideOptions) {
- const provides = isFunction(provideOptions)
- ? provideOptions.call(publicThis)
- : provideOptions;
- for (const key in provides) {
- provide(key, provides[key]);
+ if (!__VUE_CREATED_DEFERRED__) {
+ if (provideOptions) {
+ deferredProvide.push(provideOptions);
+ }
+ if (!asMixin && deferredProvide.length) {
+ deferredProvide.forEach(provideOptions => {
+ const provides = isFunction(provideOptions)
+ ? provideOptions.call(publicThis)
+ : provideOptions;
+ for (const key in provides) {
+ provide(key, provides[key]);
+ }
+ });
}
}
// asset options.
@@ -2346,11 +2375,11 @@ function applyOptions(instance, options, deferredData = [], deferredWatch = [],
// lifecycle options
if (__VUE_CREATED_DEFERRED__) {
ctx.$callSyncHook = function (name) {
- return callSyncHook(name, options, publicThis, globalMixins);
+ return callSyncHook(name, "c" /* CREATED */, options, instance, globalMixins);
};
}
else if (!asMixin) {
- callSyncHook('created', options, publicThis, globalMixins);
+ callSyncHook('created', "c" /* CREATED */, options, instance, globalMixins);
}
if (beforeMount) {
onBeforeMount(beforeMount.bind(publicThis));
@@ -2396,44 +2425,44 @@ function applyOptions(instance, options, deferredData = [], deferredWatch = [],
instance.ctx.$onApplyOptions(options, instance, publicThis);
}
}
-function callSyncHook(name, options, ctx, globalMixins) {
- callHookFromMixins(name, globalMixins, ctx);
+function callSyncHook(name, type, options, instance, globalMixins) {
+ callHookFromMixins(name, type, globalMixins, instance);
const { extends: base, mixins } = options;
if (base) {
- callHookFromExtends(name, base, ctx);
+ callHookFromExtends(name, type, base, instance);
}
if (mixins) {
- callHookFromMixins(name, mixins, ctx);
+ callHookFromMixins(name, type, mixins, instance);
}
const selfHook = options[name];
if (selfHook) {
- selfHook.call(ctx);
+ callWithAsyncErrorHandling(selfHook.bind(instance.proxy), instance, type);
}
}
-function callHookFromExtends(name, base, ctx) {
+function callHookFromExtends(name, type, base, instance) {
if (base.extends) {
- callHookFromExtends(name, base.extends, ctx);
+ callHookFromExtends(name, type, base.extends, instance);
}
const baseHook = base[name];
if (baseHook) {
- baseHook.call(ctx);
+ callWithAsyncErrorHandling(baseHook.bind(instance.proxy), instance, type);
}
}
-function callHookFromMixins(name, mixins, ctx) {
+function callHookFromMixins(name, type, mixins, instance) {
for (let i = 0; i < mixins.length; i++) {
const chainedMixins = mixins[i].mixins;
if (chainedMixins) {
- callHookFromMixins(name, chainedMixins, ctx);
+ callHookFromMixins(name, type, chainedMixins, instance);
}
const fn = mixins[i][name];
if (fn) {
- fn.call(ctx);
+ callWithAsyncErrorHandling(fn.bind(instance.proxy), instance, type);
}
}
}
-function applyMixins(instance, mixins, deferredData, deferredWatch) {
+function applyMixins(instance, mixins, deferredData, deferredWatch, deferredProvide) {
for (let i = 0; i < mixins.length; i++) {
- applyOptions(instance, mixins[i], deferredData, deferredWatch, true);
+ applyOptions(instance, mixins[i], deferredData, deferredWatch, deferredProvide, true);
}
}
function resolveData(instance, dataFn, publicThis) {
@@ -2546,7 +2575,7 @@ const publicPropertiesMap = extend(Object.create(null), {
$emit: i => i.emit,
$options: i => (__VUE_OPTIONS_API__ ? resolveMergedOptions(i) : i.type),
$forceUpdate: i => () => queueJob(i.update),
- // $nextTick: () => nextTick, // fixed by xxxxxx
+ // $nextTick: i => nextTick.bind(i.proxy!), // fixed by xxxxxx
$watch: i => (__VUE_OPTIONS_API__ ? instanceWatch.bind(i) : NOOP)
});
const PublicInstanceProxyHandlers = {
@@ -2556,6 +2585,10 @@ const PublicInstanceProxyHandlers = {
if (key === "__v_skip" /* SKIP */) {
return true;
}
+ // for internal formatters to know that this is a Vue instance
+ if ((process.env.NODE_ENV !== 'production') && key === '__isVue') {
+ return true;
+ }
// data / props / ctx
// This getter gets called for every property access on the render context
// during render and is a major hotspot. The most expensive part of this
@@ -2900,7 +2933,7 @@ function setupStatefulComponent(instance, isSSR) {
}
}
// 0. create render proxy property access cache
- instance.accessCache = {};
+ instance.accessCache = Object.create(null);
// 1. create public instance / render proxy
// also mark it raw so it's never observed
instance.proxy = new Proxy(instance.ctx, PublicInstanceProxyHandlers);
@@ -3077,7 +3110,7 @@ function computed$1(getterOrOptions) {
}
// Core API ------------------------------------------------------------------
-const version = "3.0.0";
+const version = "3.0.2";
// import deepCopy from './deepCopy'
/**
diff --git a/packages/uni-mp-vue/lib/vue.runtime.esm.js b/packages/uni-mp-vue/lib/vue.runtime.esm.js
index c7eeec758c75f249833ed034cdc0090aeb4cc596..39c99a2a671b55988cc47435247c9bf35f68af8a 100644
--- a/packages/uni-mp-vue/lib/vue.runtime.esm.js
+++ b/packages/uni-mp-vue/lib/vue.runtime.esm.js
@@ -1,4 +1,4 @@
-import { EMPTY_OBJ, isArray, isMap, isIntegerKey, isSymbol, extend, hasOwn, isObject, hasChanged, capitalize, toRawType, def, isFunction, NOOP, isString, isPromise, hyphenate, isOn, isReservedProp, camelize, EMPTY_ARR, makeMap, remove, NO, isSet, isGloballyWhitelisted, toTypeString, invokeArrayFns } from '@vue/shared';
+import { EMPTY_OBJ, isArray, isMap, isIntegerKey, isSymbol, extend, hasOwn, isObject, hasChanged, capitalize, toRawType, def, isFunction, NOOP, isString, isPromise, toHandlerKey, toNumber, hyphenate, camelize, isOn, isReservedProp, EMPTY_ARR, makeMap, remove, NO, isSet, isGloballyWhitelisted, toTypeString, invokeArrayFns } from '@vue/shared';
export { camelize } from '@vue/shared';
const targetMap = new WeakMap();
@@ -50,6 +50,7 @@ function createReactiveEffect(fn, options) {
}
};
effect.id = uid++;
+ effect.allowRecurse = !!options.allowRecurse;
effect._isEffect = true;
effect.active = true;
effect.raw = fn;
@@ -115,7 +116,7 @@ function trigger(target, type, key, newValue, oldValue, oldTarget) {
const add = (effectsToAdd) => {
if (effectsToAdd) {
effectsToAdd.forEach(effect => {
- if (effect !== activeEffect || effect.options.allowRecurse) {
+ if (effect !== activeEffect || effect.allowRecurse) {
effects.add(effect);
}
});
@@ -220,7 +221,7 @@ const arrayInstrumentations = {};
arrayInstrumentations[key] = function (...args) {
pauseTracking();
const res = method.apply(this, args);
- enableTracking();
+ resetTracking();
return res;
};
});
@@ -241,8 +242,7 @@ function createGetter(isReadonly = false, shallow = false) {
return Reflect.get(arrayInstrumentations, key, receiver);
}
const res = Reflect.get(target, key, receiver);
- const keyIsSymbol = isSymbol(key);
- if (keyIsSymbol
+ if (isSymbol(key)
? builtInSymbols.has(key)
: key === `__proto__` || key === `__v_isRef`) {
return res;
@@ -312,7 +312,7 @@ function has(target, key) {
return result;
}
function ownKeys(target) {
- track(target, "iterate" /* ITERATE */, ITERATE_KEY);
+ track(target, "iterate" /* ITERATE */, isArray(target) ? 'length' : ITERATE_KEY);
return Reflect.ownKeys(target);
}
const mutableHandlers = {
@@ -595,7 +595,7 @@ function checkIdentityKeys(target, has, key) {
if (rawKey !== key && has.call(target, rawKey)) {
const type = toRawType(target);
console.warn(`Reactive ${type} contains both the raw and reactive ` +
- `versions of the same object${type === `Map` ? `as keys` : ``}, ` +
+ `versions of the same object${type === `Map` ? ` as keys` : ``}, ` +
`which can lead to inconsistencies. ` +
`Avoid differentiating between the raw and reactive versions ` +
`of an object and only use the reactive version if possible.`);
@@ -730,7 +730,7 @@ function createRef(rawValue, shallow = false) {
return new RefImpl(rawValue, shallow);
}
function triggerRef(ref) {
- trigger(ref, "set" /* SET */, 'value', (process.env.NODE_ENV !== 'production') ? ref.value : void 0);
+ trigger(toRaw(ref), "set" /* SET */, 'value', (process.env.NODE_ENV !== 'production') ? ref.value : void 0);
}
function unref(ref) {
return isRef(ref) ? ref.value : ref;
@@ -1028,7 +1028,7 @@ function handleError(err, instance, type, throwInDev = true) {
const errorCapturedHooks = cur.ec;
if (errorCapturedHooks) {
for (let i = 0; i < errorCapturedHooks.length; i++) {
- if (errorCapturedHooks[i](err, exposedInstance, errorInfo)) {
+ if (errorCapturedHooks[i](err, exposedInstance, errorInfo) === false) {
return;
}
}
@@ -1086,7 +1086,7 @@ let currentPreFlushParentJob = null;
const RECURSION_LIMIT = 100;
function nextTick(fn) {
const p = currentFlushPromise || resolvedPromise;
- return fn ? p.then(fn) : p;
+ return fn ? p.then(this ? fn.bind(this) : fn) : p;
}
function queueJob(job) {
// the dedupe search uses the startIndex argument of Array.includes()
@@ -1235,21 +1235,21 @@ function checkRecursiveUpdates(seen, fn) {
}
}
-function emit(instance, event, ...args) {
+function emit(instance, event, ...rawArgs) {
const props = instance.vnode.props || EMPTY_OBJ;
if ((process.env.NODE_ENV !== 'production')) {
const { emitsOptions, propsOptions: [propsOptions] } = instance;
if (emitsOptions) {
if (!(event in emitsOptions)) {
- if (!propsOptions || !(`on` + capitalize(event) in propsOptions)) {
+ if (!propsOptions || !(toHandlerKey(event) in propsOptions)) {
warn(`Component emitted event "${event}" but it is neither declared in ` +
- `the emits option nor as an "on${capitalize(event)}" prop.`);
+ `the emits option nor as an "${toHandlerKey(event)}" prop.`);
}
}
else {
const validator = emitsOptions[event];
if (isFunction(validator)) {
- const isValid = validator(...args);
+ const isValid = validator(...rawArgs);
if (!isValid) {
warn(`Invalid event arguments: event validation failed for event "${event}".`);
}
@@ -1257,34 +1257,57 @@ function emit(instance, event, ...args) {
}
}
}
+ let args = rawArgs;
+ const isModelListener = event.startsWith('update:');
+ // for v-model update:xxx events, apply modifiers on args
+ const modelArg = isModelListener && event.slice(7);
+ if (modelArg && modelArg in props) {
+ const modifiersKey = `${modelArg === 'modelValue' ? 'model' : modelArg}Modifiers`;
+ const { number, trim } = props[modifiersKey] || EMPTY_OBJ;
+ if (trim) {
+ args = rawArgs.map(a => a.trim());
+ }
+ else if (number) {
+ args = rawArgs.map(toNumber);
+ }
+ }
if ((process.env.NODE_ENV !== 'production') || false) ;
- let handlerName = `on${capitalize(event)}`;
+ if ((process.env.NODE_ENV !== 'production')) {
+ const lowerCaseEvent = event.toLowerCase();
+ if (lowerCaseEvent !== event && props[toHandlerKey(lowerCaseEvent)]) {
+ warn(`Event "${lowerCaseEvent}" is emitted in component ` +
+ `${formatComponentName(instance, instance.type)} but the handler is registered for "${event}". ` +
+ `Note that HTML attributes are case-insensitive and you cannot use ` +
+ `v-on to listen to camelCase events when using in-DOM templates. ` +
+ `You should probably use "${hyphenate(event)}" instead of "${event}".`);
+ }
+ }
+ // convert handler name to camelCase. See issue #2249
+ let handlerName = toHandlerKey(camelize(event));
let handler = props[handlerName];
// for v-model update:xxx events, also trigger kebab-case equivalent
// for props passed via kebab-case
- if (!handler && event.startsWith('update:')) {
- handlerName = `on${capitalize(hyphenate(event))}`;
+ if (!handler && isModelListener) {
+ handlerName = toHandlerKey(hyphenate(event));
handler = props[handlerName];
}
- if (!handler) {
- handler = props[handlerName + `Once`];
+ if (handler) {
+ callWithAsyncErrorHandling(handler, instance, 6 /* COMPONENT_EVENT_HANDLER */, args);
+ }
+ const onceHandler = props[handlerName + `Once`];
+ if (onceHandler) {
if (!instance.emitted) {
(instance.emitted = {})[handlerName] = true;
}
else if (instance.emitted[handlerName]) {
return;
}
- }
- if (handler) {
- callWithAsyncErrorHandling(handler, instance, 6 /* COMPONENT_EVENT_HANDLER */, args);
+ callWithAsyncErrorHandling(onceHandler, instance, 6 /* COMPONENT_EVENT_HANDLER */, args);
}
}
function normalizeEmitsOptions(comp, appContext, asMixin = false) {
- const appId = appContext.app ? appContext.app._uid : -1;
- const cache = comp.__emits || (comp.__emits = {});
- const cached = cache[appId];
- if (cached !== undefined) {
- return cached;
+ if (!appContext.deopt && comp.__emits !== undefined) {
+ return comp.__emits;
}
const raw = comp.emits;
let normalized = {};
@@ -1306,7 +1329,7 @@ function normalizeEmitsOptions(comp, appContext, asMixin = false) {
}
}
if (!raw && !hasExtends) {
- return (cache[appId] = null);
+ return (comp.__emits = null);
}
if (isArray(raw)) {
raw.forEach(key => (normalized[key] = null));
@@ -1314,7 +1337,7 @@ function normalizeEmitsOptions(comp, appContext, asMixin = false) {
else {
extend(normalized, raw);
}
- return (cache[appId] = normalized);
+ return (comp.__emits = normalized);
}
// Check if an incoming prop key is a declared emit event listener.
// e.g. With `emits: { click: null }`, props named `onClick` and `onclick` are
@@ -1422,11 +1445,8 @@ function resolvePropValue(options, props, key, value, instance) {
return value;
}
function normalizePropsOptions(comp, appContext, asMixin = false) {
- const appId = appContext.app ? appContext.app._uid : -1;
- const cache = comp.__props || (comp.__props = {});
- const cached = cache[appId];
- if (cached) {
- return cached;
+ if (!appContext.deopt && comp.__props) {
+ return comp.__props;
}
const raw = comp.props;
const normalized = {};
@@ -1452,7 +1472,7 @@ function normalizePropsOptions(comp, appContext, asMixin = false) {
}
}
if (!raw && !hasExtends) {
- return (cache[appId] = EMPTY_ARR);
+ return (comp.__props = EMPTY_ARR);
}
if (isArray(raw)) {
for (let i = 0; i < raw.length; i++) {
@@ -1489,7 +1509,16 @@ function normalizePropsOptions(comp, appContext, asMixin = false) {
}
}
}
- return (cache[appId] = [normalized, needCastKeys]);
+ return (comp.__props = [normalized, needCastKeys]);
+}
+function validatePropName(key) {
+ if (key[0] !== '$') {
+ return true;
+ }
+ else if ((process.env.NODE_ENV !== 'production')) {
+ warn(`Invalid prop name: "${key}" is a reserved property.`);
+ }
+ return false;
}
// use function string name to check type constructors
// so that it works across vms / iframes.
@@ -1526,18 +1555,6 @@ function validateProps(props, instance) {
validateProp(key, rawValues[key], opt, !hasOwn(rawValues, key));
}
}
-/**
- * dev only
- */
-function validatePropName(key) {
- if (key[0] !== '$') {
- return true;
- }
- else if ((process.env.NODE_ENV !== 'production')) {
- warn(`Invalid prop name: "${key}" is a reserved property.`);
- }
- return false;
-}
/**
* dev only
*/
@@ -1685,7 +1702,7 @@ function injectHook(type, hook, target = currentInstance, prepend = false) {
return wrappedHook;
}
else if ((process.env.NODE_ENV !== 'production')) {
- const apiName = `on${capitalize(ErrorTypeStrings[type].replace(/ hook$/, ''))}`;
+ const apiName = toHandlerKey(ErrorTypeStrings[type].replace(/ hook$/, ''));
warn(`${apiName} is called when there is no active component instance to be ` +
`associated with. ` +
`Lifecycle injection APIs can only be used during execution of setup().` +
@@ -1841,6 +1858,11 @@ function createAppAPI() {
if (__VUE_OPTIONS_API__) {
if (!context.mixins.includes(mixin)) {
context.mixins.push(mixin);
+ // global mixin with props/emits de-optimizes props/emits
+ // normalization caching.
+ if (mixin.props || mixin.emits) {
+ context.deopt = true;
+ }
}
else if ((process.env.NODE_ENV !== 'production')) {
warn('Mixin has already been applied to target app' +
@@ -1930,9 +1952,10 @@ function doWatch(source, cb, { immediate, deep, flush, onTrack, onTrigger } = EM
`a reactive object, or an array of these types.`);
};
let getter;
- const isRefSource = isRef(source);
- if (isRefSource) {
+ let forceTrigger = false;
+ if (isRef(source)) {
getter = () => source.value;
+ forceTrigger = !!source._shallow;
}
else if (isReactive(source)) {
getter = () => source;
@@ -1994,7 +2017,7 @@ function doWatch(source, cb, { immediate, deep, flush, onTrack, onTrigger } = EM
if (cb) {
// watch(source, cb)
const newValue = runner();
- if (deep || isRefSource || hasChanged(newValue, oldValue)) {
+ if (deep || forceTrigger || hasChanged(newValue, oldValue)) {
// cleanup before running cb again
if (cleanup) {
cleanup();
@@ -2013,7 +2036,7 @@ function doWatch(source, cb, { immediate, deep, flush, onTrack, onTrigger } = EM
runner();
}
};
- // important: mark the job as a watcher callback so that scheduler knows it
+ // important: mark the job as a watcher callback so that scheduler knows
// it is allowed to self-trigger (#1727)
job.allowRecurse = !!cb;
let scheduler;
@@ -2086,14 +2109,8 @@ function traverse(value, seen = new Set()) {
traverse(value[i], seen);
}
}
- else if (isMap(value)) {
- value.forEach((_, key) => {
- // to register mutation dep for existing keys
- traverse(value.get(key), seen);
- });
- }
- else if (isSet(value)) {
- value.forEach(v => {
+ else if (isSet(value) || isMap(value)) {
+ value.forEach((v) => {
traverse(v, seen);
});
}
@@ -2131,8 +2148,13 @@ function inject(key, defaultValue, treatDefaultAsFactory = false) {
// a functional component
const instance = currentInstance || currentRenderingInstance;
if (instance) {
- const provides = instance.provides;
- if (key in provides) {
+ // #2400
+ // to support `app.use` plugins,
+ // fallback to appContext's `provides` if the intance is at root
+ const provides = instance.parent == null
+ ? instance.vnode.appContext && instance.vnode.appContext.provides
+ : instance.parent.provides;
+ if (provides && key in provides) {
// TS doesn't allow symbol as index type
return provides[key];
}
@@ -2162,7 +2184,7 @@ function createDuplicateChecker() {
};
}
let isInBeforeCreate = false;
-function applyOptions(instance, options, deferredData = [], deferredWatch = [], asMixin = false) {
+function applyOptions(instance, options, deferredData = [], deferredWatch = [], deferredProvide = [], asMixin = false) {
const {
// composition
mixins, extends: extendsOptions,
@@ -2181,18 +2203,18 @@ function applyOptions(instance, options, deferredData = [], deferredWatch = [],
// applyOptions is called non-as-mixin once per instance
if (!asMixin) {
isInBeforeCreate = true;
- callSyncHook('beforeCreate', options, publicThis, globalMixins);
+ callSyncHook('beforeCreate', "bc" /* BEFORE_CREATE */, options, instance, globalMixins);
isInBeforeCreate = false;
// global mixins are applied first
- applyMixins(instance, globalMixins, deferredData, deferredWatch);
+ applyMixins(instance, globalMixins, deferredData, deferredWatch, deferredProvide);
}
// extending a base component...
if (extendsOptions) {
- applyOptions(instance, extendsOptions, deferredData, deferredWatch, true);
+ applyOptions(instance, extendsOptions, deferredData, deferredWatch, deferredProvide, true);
}
// local mixins
if (mixins) {
- applyMixins(instance, mixins, deferredData, deferredWatch);
+ applyMixins(instance, mixins, deferredData, deferredWatch, deferredProvide);
}
const checkDuplicateProperties = (process.env.NODE_ENV !== 'production') ? createDuplicateChecker() : null;
if ((process.env.NODE_ENV !== 'production')) {
@@ -2321,12 +2343,19 @@ function applyOptions(instance, options, deferredData = [], deferredWatch = [],
});
}
// fixed by xxxxxx
- if (!__VUE_CREATED_DEFERRED__ && provideOptions) {
- const provides = isFunction(provideOptions)
- ? provideOptions.call(publicThis)
- : provideOptions;
- for (const key in provides) {
- provide(key, provides[key]);
+ if (!__VUE_CREATED_DEFERRED__) {
+ if (provideOptions) {
+ deferredProvide.push(provideOptions);
+ }
+ if (!asMixin && deferredProvide.length) {
+ deferredProvide.forEach(provideOptions => {
+ const provides = isFunction(provideOptions)
+ ? provideOptions.call(publicThis)
+ : provideOptions;
+ for (const key in provides) {
+ provide(key, provides[key]);
+ }
+ });
}
}
// asset options.
@@ -2346,11 +2375,11 @@ function applyOptions(instance, options, deferredData = [], deferredWatch = [],
// lifecycle options
if (__VUE_CREATED_DEFERRED__) {
ctx.$callSyncHook = function (name) {
- return callSyncHook(name, options, publicThis, globalMixins);
+ return callSyncHook(name, "c" /* CREATED */, options, instance, globalMixins);
};
}
else if (!asMixin) {
- callSyncHook('created', options, publicThis, globalMixins);
+ callSyncHook('created', "c" /* CREATED */, options, instance, globalMixins);
}
if (beforeMount) {
onBeforeMount(beforeMount.bind(publicThis));
@@ -2396,44 +2425,44 @@ function applyOptions(instance, options, deferredData = [], deferredWatch = [],
instance.ctx.$onApplyOptions(options, instance, publicThis);
}
}
-function callSyncHook(name, options, ctx, globalMixins) {
- callHookFromMixins(name, globalMixins, ctx);
+function callSyncHook(name, type, options, instance, globalMixins) {
+ callHookFromMixins(name, type, globalMixins, instance);
const { extends: base, mixins } = options;
if (base) {
- callHookFromExtends(name, base, ctx);
+ callHookFromExtends(name, type, base, instance);
}
if (mixins) {
- callHookFromMixins(name, mixins, ctx);
+ callHookFromMixins(name, type, mixins, instance);
}
const selfHook = options[name];
if (selfHook) {
- selfHook.call(ctx);
+ callWithAsyncErrorHandling(selfHook.bind(instance.proxy), instance, type);
}
}
-function callHookFromExtends(name, base, ctx) {
+function callHookFromExtends(name, type, base, instance) {
if (base.extends) {
- callHookFromExtends(name, base.extends, ctx);
+ callHookFromExtends(name, type, base.extends, instance);
}
const baseHook = base[name];
if (baseHook) {
- baseHook.call(ctx);
+ callWithAsyncErrorHandling(baseHook.bind(instance.proxy), instance, type);
}
}
-function callHookFromMixins(name, mixins, ctx) {
+function callHookFromMixins(name, type, mixins, instance) {
for (let i = 0; i < mixins.length; i++) {
const chainedMixins = mixins[i].mixins;
if (chainedMixins) {
- callHookFromMixins(name, chainedMixins, ctx);
+ callHookFromMixins(name, type, chainedMixins, instance);
}
const fn = mixins[i][name];
if (fn) {
- fn.call(ctx);
+ callWithAsyncErrorHandling(fn.bind(instance.proxy), instance, type);
}
}
}
-function applyMixins(instance, mixins, deferredData, deferredWatch) {
+function applyMixins(instance, mixins, deferredData, deferredWatch, deferredProvide) {
for (let i = 0; i < mixins.length; i++) {
- applyOptions(instance, mixins[i], deferredData, deferredWatch, true);
+ applyOptions(instance, mixins[i], deferredData, deferredWatch, deferredProvide, true);
}
}
function resolveData(instance, dataFn, publicThis) {
@@ -2546,7 +2575,7 @@ const publicPropertiesMap = extend(Object.create(null), {
$emit: i => i.emit,
$options: i => (__VUE_OPTIONS_API__ ? resolveMergedOptions(i) : i.type),
$forceUpdate: i => () => queueJob(i.update),
- // $nextTick: () => nextTick, // fixed by xxxxxx
+ // $nextTick: i => nextTick.bind(i.proxy!), // fixed by xxxxxx
$watch: i => (__VUE_OPTIONS_API__ ? instanceWatch.bind(i) : NOOP)
});
const PublicInstanceProxyHandlers = {
@@ -2556,6 +2585,10 @@ const PublicInstanceProxyHandlers = {
if (key === "__v_skip" /* SKIP */) {
return true;
}
+ // for internal formatters to know that this is a Vue instance
+ if ((process.env.NODE_ENV !== 'production') && key === '__isVue') {
+ return true;
+ }
// data / props / ctx
// This getter gets called for every property access on the render context
// during render and is a major hotspot. The most expensive part of this
@@ -2900,7 +2933,7 @@ function setupStatefulComponent(instance, isSSR) {
}
}
// 0. create render proxy property access cache
- instance.accessCache = {};
+ instance.accessCache = Object.create(null);
// 1. create public instance / render proxy
// also mark it raw so it's never observed
instance.proxy = new Proxy(instance.ctx, PublicInstanceProxyHandlers);
@@ -3077,7 +3110,7 @@ function computed$1(getterOrOptions) {
}
// Core API ------------------------------------------------------------------
-const version = "3.0.0";
+const version = "3.0.2";
// import deepCopy from './deepCopy'
/**
diff --git a/packages/uni-mp-weixin/dist/uni.api.esm.js b/packages/uni-mp-weixin/dist/uni.api.esm.js
index ea78718369dc1d7882c3a7c8a3157fd5e6f27f59..7ef01a08b928f7d1fe22667d346c34be9d9ef6b1 100644
--- a/packages/uni-mp-weixin/dist/uni.api.esm.js
+++ b/packages/uni-mp-weixin/dist/uni.api.esm.js
@@ -487,19 +487,7 @@ const getSystemInfo = {
returnValue: addSafeAreaInsets
};
const getSystemInfoSync = getSystemInfo;
-const redirectTo = {};
-const createCanvasContext = {
- returnValue(fromRes, toRes) {
- const measureText = fromRes.measureText;
- toRes.measureText = function (text, callback) {
- const textMetrics = measureText.call(this, text);
- if (typeof callback === 'function') {
- setTimeout(() => callback(textMetrics), 0);
- }
- return textMetrics;
- };
- }
-};
+const redirectTo = {};
const getProvider = initGetProvider({
oauth: ['weixin'],
@@ -518,8 +506,7 @@ var protocols = /*#__PURE__*/Object.freeze({
redirectTo: redirectTo,
previewImage: previewImage,
getSystemInfo: getSystemInfo,
- getSystemInfoSync: getSystemInfoSync,
- createCanvasContext: createCanvasContext
+ getSystemInfoSync: getSystemInfoSync
});
var index = initUni(shims, protocols);
diff --git a/packages/uni-quickapp-webview/dist/uni.api.esm.js b/packages/uni-quickapp-webview/dist/uni.api.esm.js
index 09c73991afb88d24a63468a24c28e6b6bfa8653b..5c520ea24d1c105a125d10723d638572c149b79d 100644
--- a/packages/uni-quickapp-webview/dist/uni.api.esm.js
+++ b/packages/uni-quickapp-webview/dist/uni.api.esm.js
@@ -487,19 +487,7 @@ const getSystemInfo = {
returnValue: addSafeAreaInsets
};
const getSystemInfoSync = getSystemInfo;
-const redirectTo = {};
-const createCanvasContext = {
- returnValue(fromRes, toRes) {
- const measureText = fromRes.measureText;
- toRes.measureText = function (text, callback) {
- const textMetrics = measureText.call(this, text);
- if (typeof callback === 'function') {
- setTimeout(() => callback(textMetrics), 0);
- }
- return textMetrics;
- };
- }
-};
+const redirectTo = {};
const providers = {
oauth: [],
@@ -525,8 +513,7 @@ var protocols = /*#__PURE__*/Object.freeze({
redirectTo: redirectTo,
previewImage: previewImage,
getSystemInfo: getSystemInfo,
- getSystemInfoSync: getSystemInfoSync,
- createCanvasContext: createCanvasContext
+ getSystemInfoSync: getSystemInfoSync
});
var index = initUni(shims, protocols);