Merge remote-tracking branch 'upstream/main'
This commit is contained in:
commit
5a0365d944
11
CHANGELOG.md
11
CHANGELOG.md
|
@ -1,3 +1,14 @@
|
|||
## [3.4.21](https://github.com/vuejs/core/compare/v3.4.20...v3.4.21) (2024-02-28)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **runtime-dom:** avoid unset option's value ([#10416](https://github.com/vuejs/core/issues/10416)) ([b3f8b5a](https://github.com/vuejs/core/commit/b3f8b5a4e700d4c47a146b6040882287d180f6cb)), closes [#10412](https://github.com/vuejs/core/issues/10412) [#10396](https://github.com/vuejs/core/issues/10396)
|
||||
* **suspense:** ensure nested suspense patching if in fallback state ([#10417](https://github.com/vuejs/core/issues/10417)) ([7c97778](https://github.com/vuejs/core/commit/7c97778aec1e3513035e5df265e1b8a7801f6106)), closes [#10415](https://github.com/vuejs/core/issues/10415)
|
||||
* **warning:** stringify args in warn handler ([#10414](https://github.com/vuejs/core/issues/10414)) ([bc37258](https://github.com/vuejs/core/commit/bc37258caa2f6f67f4554ab8587aca3798d92124)), closes [#10409](https://github.com/vuejs/core/issues/10409)
|
||||
|
||||
|
||||
|
||||
## [3.4.20](https://github.com/vuejs/core/compare/v3.4.19...v3.4.20) (2024-02-26)
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@vue/compiler-core",
|
||||
"version": "3.4.20",
|
||||
"version": "3.4.21",
|
||||
"description": "@vue/compiler-core",
|
||||
"main": "index.js",
|
||||
"module": "dist/compiler-core.esm-bundler.js",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@vue/compiler-dom",
|
||||
"version": "3.4.20",
|
||||
"version": "3.4.21",
|
||||
"description": "@vue/compiler-dom",
|
||||
"main": "index.js",
|
||||
"module": "dist/compiler-dom.esm-bundler.js",
|
||||
|
|
|
@ -79,21 +79,6 @@ return { get FooBar() { return FooBar }, get foo() { return foo }, get bar() { r
|
|||
})"
|
||||
`;
|
||||
|
||||
exports[`import namespace 1`] = `
|
||||
"import { defineComponent as _defineComponent } from 'vue'
|
||||
import * as Foo from './foo'
|
||||
|
||||
export default /*#__PURE__*/_defineComponent({
|
||||
setup(__props, { expose: __expose }) {
|
||||
__expose();
|
||||
|
||||
|
||||
return { get Foo() { return Foo } }
|
||||
}
|
||||
|
||||
})"
|
||||
`;
|
||||
|
||||
exports[`js template string interpolations 1`] = `
|
||||
"import { defineComponent as _defineComponent } from 'vue'
|
||||
import { VAR, VAR2, VAR3 } from './x'
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@vue/compiler-sfc",
|
||||
"version": "3.4.20",
|
||||
"version": "3.4.21",
|
||||
"description": "@vue/compiler-sfc",
|
||||
"main": "dist/compiler-sfc.cjs.js",
|
||||
"module": "dist/compiler-sfc.esm-browser.js",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@vue/compiler-ssr",
|
||||
"version": "3.4.20",
|
||||
"version": "3.4.21",
|
||||
"description": "@vue/compiler-ssr",
|
||||
"main": "dist/compiler-ssr.cjs.js",
|
||||
"types": "dist/compiler-ssr.d.ts",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@vue/reactivity",
|
||||
"version": "3.4.20",
|
||||
"version": "3.4.21",
|
||||
"description": "@vue/reactivity",
|
||||
"main": "index.js",
|
||||
"module": "dist/reactivity.esm-bundler.js",
|
||||
|
|
|
@ -54,6 +54,18 @@ describe('Suspense', () => {
|
|||
}
|
||||
}
|
||||
|
||||
const RouterView = {
|
||||
setup(_: any, { slots }: any) {
|
||||
const route = inject('route') as any
|
||||
const depth = inject('depth', 0)
|
||||
provide('depth', depth + 1)
|
||||
return () => {
|
||||
const current = route.value[depth]
|
||||
return slots.default({ Component: current })[0]
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
test('fallback content', async () => {
|
||||
const Async = defineAsyncComponent({
|
||||
render() {
|
||||
|
@ -1041,18 +1053,6 @@ describe('Suspense', () => {
|
|||
|
||||
// #10098
|
||||
test('switching branches w/ nested suspense', async () => {
|
||||
const RouterView = {
|
||||
setup(_: any, { slots }: any) {
|
||||
const route = inject('route') as any
|
||||
const depth = inject('depth', 0)
|
||||
provide('depth', depth + 1)
|
||||
return () => {
|
||||
const current = route.value[depth]
|
||||
return slots.default({ Component: current })[0]
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
const OuterB = defineAsyncComponent({
|
||||
setup: () => {
|
||||
return () =>
|
||||
|
@ -1132,6 +1132,121 @@ describe('Suspense', () => {
|
|||
expect(serializeInner(root)).toBe(`<div>innerA</div>`)
|
||||
})
|
||||
|
||||
// #10415
|
||||
test('nested suspense (w/ suspensible) switch several times before parent suspense resolve', async () => {
|
||||
const OuterA = defineAsyncComponent({
|
||||
setup: () => {
|
||||
return () =>
|
||||
h(RouterView, null, {
|
||||
default: ({ Component }: any) => [
|
||||
h(Suspense, null, {
|
||||
default: () => h(Component),
|
||||
}),
|
||||
],
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
const InnerA = defineAsyncComponent({
|
||||
setup: () => {
|
||||
return () => h('div', 'innerA')
|
||||
},
|
||||
})
|
||||
|
||||
const route = shallowRef([OuterA, InnerA])
|
||||
const InnerB = defineAsyncComponent(
|
||||
{
|
||||
setup: () => {
|
||||
return () => h('div', 'innerB')
|
||||
},
|
||||
},
|
||||
5,
|
||||
)
|
||||
|
||||
const InnerB1 = defineAsyncComponent(
|
||||
{
|
||||
setup: () => {
|
||||
return () => h('div', 'innerB1')
|
||||
},
|
||||
},
|
||||
5,
|
||||
)
|
||||
|
||||
const InnerB2 = defineAsyncComponent(
|
||||
{
|
||||
setup: () => {
|
||||
return () => h('div', 'innerB2')
|
||||
},
|
||||
},
|
||||
5,
|
||||
)
|
||||
|
||||
const OuterB = defineAsyncComponent(
|
||||
{
|
||||
setup() {
|
||||
nextTick(async () => {
|
||||
await new Promise(resolve => setTimeout(resolve, 1))
|
||||
route.value = [OuterB, InnerB1]
|
||||
})
|
||||
|
||||
nextTick(async () => {
|
||||
await new Promise(resolve => setTimeout(resolve, 1))
|
||||
route.value = [OuterB, InnerB2]
|
||||
})
|
||||
|
||||
return () =>
|
||||
h(RouterView, null, {
|
||||
default: ({ Component }: any) => [
|
||||
h(
|
||||
Suspense,
|
||||
{ suspensible: true },
|
||||
{
|
||||
default: () => h(Component),
|
||||
},
|
||||
),
|
||||
],
|
||||
})
|
||||
},
|
||||
},
|
||||
5,
|
||||
)
|
||||
|
||||
const Comp = {
|
||||
setup() {
|
||||
provide('route', route)
|
||||
return () =>
|
||||
h(RouterView, null, {
|
||||
default: ({ Component }: any) => [
|
||||
h(Suspense, null, {
|
||||
default: () => h(Component),
|
||||
}),
|
||||
],
|
||||
})
|
||||
},
|
||||
}
|
||||
|
||||
const root = nodeOps.createElement('div')
|
||||
render(h(Comp), root)
|
||||
await Promise.all(deps)
|
||||
await nextTick()
|
||||
expect(serializeInner(root)).toBe(`<!---->`)
|
||||
|
||||
await Promise.all(deps)
|
||||
await nextTick()
|
||||
expect(serializeInner(root)).toBe(`<div>innerA</div>`)
|
||||
|
||||
deps.length = 0
|
||||
|
||||
route.value = [OuterB, InnerB]
|
||||
await nextTick()
|
||||
|
||||
await Promise.all(deps)
|
||||
await Promise.all(deps)
|
||||
await Promise.all(deps)
|
||||
await nextTick()
|
||||
expect(serializeInner(root)).toBe(`<div>innerB2</div>`)
|
||||
})
|
||||
|
||||
test('branch switch to 3rd branch before resolve', async () => {
|
||||
const calls: string[] = []
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@vue/runtime-core",
|
||||
"version": "3.4.20",
|
||||
"version": "3.4.21",
|
||||
"description": "@vue/runtime-core",
|
||||
"main": "index.js",
|
||||
"module": "dist/runtime-core.esm-bundler.js",
|
||||
|
|
|
@ -99,7 +99,11 @@ export const SuspenseImpl = {
|
|||
// 2. mounting along with the pendingBranch of parentSuspense
|
||||
// it is necessary to skip the current patch to avoid multiple mounts
|
||||
// of inner components.
|
||||
if (parentSuspense && parentSuspense.deps > 0) {
|
||||
if (
|
||||
parentSuspense &&
|
||||
parentSuspense.deps > 0 &&
|
||||
!n1.suspense!.isInFallback
|
||||
) {
|
||||
n2.suspense = n1.suspense!
|
||||
n2.suspense.vnode = n2
|
||||
n2.el = n1.el
|
||||
|
|
|
@ -44,7 +44,7 @@ export function warn(msg: string, ...args: any[]) {
|
|||
instance,
|
||||
ErrorCodes.APP_WARN_HANDLER,
|
||||
[
|
||||
msg + args.join(''),
|
||||
msg + args.map(a => a.toString?.() ?? JSON.stringify(a)).join(''),
|
||||
instance && instance.proxy,
|
||||
trace
|
||||
.map(
|
||||
|
|
|
@ -291,6 +291,18 @@ describe('runtime-dom: props patching', () => {
|
|||
expect(el.value).toBe('baz')
|
||||
})
|
||||
|
||||
test('init empty value for option', () => {
|
||||
const root = document.createElement('div')
|
||||
render(
|
||||
h('select', { value: 'foo' }, [h('option', { value: '' }, 'foo')]),
|
||||
root,
|
||||
)
|
||||
const select = root.children[0] as HTMLSelectElement
|
||||
const option = select.children[0] as HTMLOptionElement
|
||||
expect(select.value).toBe('')
|
||||
expect(option.value).toBe('')
|
||||
})
|
||||
|
||||
// #8780
|
||||
test('embedded tag with width and height', () => {
|
||||
// Width and height of some embedded element such as img、video、source、canvas
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@vue/runtime-dom",
|
||||
"version": "3.4.20",
|
||||
"version": "3.4.21",
|
||||
"description": "@vue/runtime-dom",
|
||||
"main": "index.js",
|
||||
"module": "dist/runtime-dom.esm-bundler.js",
|
||||
|
|
|
@ -34,20 +34,20 @@ export function patchDOMProp(
|
|||
// custom elements may use _value internally
|
||||
!tag.includes('-')
|
||||
) {
|
||||
// store value as _value as well since
|
||||
// non-string values will be stringified.
|
||||
el._value = value
|
||||
// #4956: <option> value will fallback to its text content so we need to
|
||||
// compare against its attribute value instead.
|
||||
const oldValue =
|
||||
tag === 'OPTION' ? el.getAttribute('value') || '' : el.value
|
||||
const newValue = value == null ? '' : value
|
||||
if (oldValue !== newValue) {
|
||||
if (oldValue !== newValue || !('_value' in el)) {
|
||||
el.value = newValue
|
||||
}
|
||||
if (value == null) {
|
||||
el.removeAttribute(key)
|
||||
}
|
||||
// store value as _value as well since
|
||||
// non-string values will be stringified.
|
||||
el._value = value
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@vue/server-renderer",
|
||||
"version": "3.4.20",
|
||||
"version": "3.4.21",
|
||||
"description": "@vue/server-renderer",
|
||||
"main": "index.js",
|
||||
"module": "dist/server-renderer.esm-bundler.js",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@vue/shared",
|
||||
"version": "3.4.20",
|
||||
"version": "3.4.21",
|
||||
"description": "internal utils shared across @vue packages",
|
||||
"main": "index.js",
|
||||
"module": "dist/shared.esm-bundler.js",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@vue/compat",
|
||||
"version": "3.4.20",
|
||||
"version": "3.4.21",
|
||||
"description": "Vue 3 compatibility build for Vue 2",
|
||||
"main": "index.js",
|
||||
"module": "dist/vue.runtime.esm-bundler.js",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "vue",
|
||||
"version": "3.4.20",
|
||||
"version": "3.4.21",
|
||||
"description": "The progressive JavaScript framework for building modern web UI.",
|
||||
"main": "index.js",
|
||||
"module": "dist/vue.runtime.esm-bundler.js",
|
||||
|
|
Loading…
Reference in New Issue