Skip to content

Commit 9f64d2b

Browse files
committed
chore: Merge branch 'main' into minor
2 parents eb12f21 + 4e7967f commit 9f64d2b

File tree

8 files changed

+152
-6
lines changed

8 files changed

+152
-6
lines changed

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,16 @@
1+
## [3.3.12](https://github.com/vuejs/core/compare/v3.3.11...v3.3.12) (2023-12-16)
2+
3+
### Bug Fixes
4+
5+
* **hydration:** handle appear transition before patch props ([#9837](https://github.com/vuejs/core/issues/9837)) ([e70f4c4](https://github.com/vuejs/core/commit/e70f4c47c553b6e16d8fad70743271ca23802fe7)), closes [#9832](https://github.com/vuejs/core/issues/9832)
6+
* **sfc/cssVars:** fix loss of CSS v-bind variables when setting inline style with string value ([#9824](https://github.com/vuejs/core/issues/9824)) ([0a387df](https://github.com/vuejs/core/commit/0a387dfb1d04afb6eae4296b6da76dfdaca77af4)), closes [#9821](https://github.com/vuejs/core/issues/9821)
7+
* **ssr:** fix suspense hydration of fallback content ([#7188](https://github.com/vuejs/core/issues/7188)) ([60415b5](https://github.com/vuejs/core/commit/60415b5d67df55f1fd6b176615299c08640fa142))
8+
* **types:** add `xmlns:xlink` to `SVGAttributes` ([#9300](https://github.com/vuejs/core/issues/9300)) ([0d61b42](https://github.com/vuejs/core/commit/0d61b429ecf63591d31e09702058fa4c7132e1a7)), closes [#9299](https://github.com/vuejs/core/issues/9299)
9+
* **types:** fix `shallowRef` type error ([#9839](https://github.com/vuejs/core/issues/9839)) ([9a57158](https://github.com/vuejs/core/commit/9a571582b53220270e498d8712ea59312c0bef3a))
10+
* **types:** support for generic keyof slots ([#8374](https://github.com/vuejs/core/issues/8374)) ([213eba4](https://github.com/vuejs/core/commit/213eba479ce080efc1053fe636f6be4a4c889b44))
11+
12+
13+
114
# [3.4.0-beta.2](https://github.com/vuejs/core/compare/v3.4.0-beta.1...v3.4.0-beta.2) (2023-12-14)
215

316

packages/dts-test/ref.test-d.ts

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,17 @@ const state = reactive({
163163

164164
expectType<string>(state.foo.label)
165165

166+
describe('ref with generic', <T extends { name: string }>() => {
167+
const r = {} as T
168+
const s = ref(r)
169+
expectType<string>(s.value.name)
170+
171+
const rr = {} as MaybeRef<T>
172+
// should at least allow casting
173+
const ss = ref(rr) as Ref<T>
174+
expectType<string>(ss.value.name)
175+
})
176+
166177
// shallowRef
167178
type Status = 'initial' | 'ready' | 'invalidating'
168179
const shallowStatus = shallowRef<Status>('initial')
@@ -201,11 +212,28 @@ if (refStatus.value === 'initial') {
201212
expectType<IsAny<typeof a>>(false)
202213
}
203214

204-
describe('shallowRef with generic', <T>() => {
205-
const r = ref({}) as MaybeRef<T>
206-
expectType<ShallowRef<T> | Ref<T>>(shallowRef(r))
215+
describe('shallowRef with generic', <T extends { name: string }>() => {
216+
const r = {} as T
217+
const s = shallowRef(r)
218+
expectType<string>(s.value.name)
219+
expectType<ShallowRef<T>>(shallowRef(r))
220+
221+
const rr = {} as MaybeRef<T>
222+
// should at least allow casting
223+
const ss = shallowRef(rr) as Ref<T> | ShallowRef<T>
224+
expectType<string>(ss.value.name)
207225
})
208226

227+
{
228+
// should return ShallowRef<T> | Ref<T>, not ShallowRef<T | Ref<T>>
229+
expectType<ShallowRef<{ name: string }> | Ref<{ name: string }>>(
230+
shallowRef({} as MaybeRef<{ name: string }>)
231+
)
232+
expectType<ShallowRef<number> | Ref<string[]> | ShallowRef<string>>(
233+
shallowRef('' as Ref<string[]> | string | number)
234+
)
235+
}
236+
209237
// proxyRefs: should return `reactive` directly
210238
const r1 = reactive({
211239
k: 'v'

packages/reactivity/src/ref.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,9 +127,13 @@ export type ShallowRef<T = any> = Ref<T> & { [ShallowRefMarker]?: true }
127127
* @param value - The "inner value" for the shallow ref.
128128
* @see {@link https://vuejs.org/api/reactivity-advanced.html#shallowref}
129129
*/
130-
export function shallowRef<T>(value: MaybeRef<T>): Ref<T> | ShallowRef<T>
131-
export function shallowRef<T extends Ref>(value: T): T
132-
export function shallowRef<T>(value: T): ShallowRef<T>
130+
export function shallowRef<T>(
131+
value: T
132+
): Ref extends T
133+
? T extends Ref
134+
? IfAny<T, ShallowRef<T>, T>
135+
: ShallowRef<T>
136+
: ShallowRef<T>
133137
export function shallowRef<T = any>(): ShallowRef<T | undefined>
134138
export function shallowRef(value?: unknown) {
135139
return createRef(value, true)

packages/runtime-core/__tests__/hydration.spec.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1255,6 +1255,41 @@ describe('SSR hydration', () => {
12551255
expect(`mismatch`).not.toHaveBeenWarned()
12561256
})
12571257

1258+
test('transition appear w/ event listener', async () => {
1259+
const container = document.createElement('div')
1260+
container.innerHTML = `<template><button>0</button></template>`
1261+
createSSRApp({
1262+
data() {
1263+
return {
1264+
count: 0
1265+
}
1266+
},
1267+
template: `
1268+
<Transition appear>
1269+
<button @click="count++">{{count}}</button>
1270+
</Transition>
1271+
`
1272+
}).mount(container)
1273+
1274+
expect(container.firstChild).toMatchInlineSnapshot(`
1275+
<button
1276+
class="v-enter-from v-enter-active"
1277+
>
1278+
0
1279+
</button>
1280+
`)
1281+
1282+
triggerEvent('click', container.querySelector('button')!)
1283+
await nextTick()
1284+
expect(container.firstChild).toMatchInlineSnapshot(`
1285+
<button
1286+
class="v-enter-from v-enter-active"
1287+
>
1288+
1
1289+
</button>
1290+
`)
1291+
})
1292+
12581293
describe('mismatch handling', () => {
12591294
test('text node', () => {
12601295
const { container } = mountWithHydration(`foo`, () => 'bar')

packages/runtime-dom/__tests__/helpers/useCssVars.spec.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,4 +293,35 @@ describe('useCssVars', () => {
293293
await nextTick()
294294
expect(target.children.length).toBe(0)
295295
})
296+
297+
test('with string style', async () => {
298+
document.body.innerHTML = ''
299+
const state = reactive({ color: 'red' })
300+
const root = document.createElement('div')
301+
const disabled = ref(false)
302+
303+
const App = {
304+
setup() {
305+
useCssVars(() => state)
306+
return () => [
307+
h(
308+
'div',
309+
{ style: disabled.value ? 'pointer-events: none' : undefined },
310+
'foo'
311+
)
312+
]
313+
}
314+
}
315+
render(h(App), root)
316+
await nextTick()
317+
for (const c of [].slice.call(root.children as any)) {
318+
expect((c as HTMLElement).style.getPropertyValue(`--color`)).toBe('red')
319+
}
320+
disabled.value = true
321+
await nextTick()
322+
323+
for (const c of [].slice.call(root.children as any)) {
324+
expect((c as HTMLElement).style.getPropertyValue(`--color`)).toBe('red')
325+
}
326+
})
296327
})

packages/runtime-dom/src/helpers/useCssVars.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
} from '@vue/runtime-core'
1111
import { ShapeFlags } from '@vue/shared'
1212

13+
export const CSS_VAR_TEXT = Symbol(__DEV__ ? 'CSS_VAR_TEXT' : '')
1314
/**
1415
* Runtime helper for SFC's CSS variable injection feature.
1516
* @private
@@ -79,8 +80,11 @@ function setVarsOnVNode(vnode: VNode, vars: Record<string, string>) {
7980
function setVarsOnNode(el: Node, vars: Record<string, string>) {
8081
if (el.nodeType === 1) {
8182
const style = (el as HTMLElement).style
83+
let cssText = ''
8284
for (const key in vars) {
8385
style.setProperty(`--${key}`, vars[key])
86+
cssText += `--${key}: ${vars[key]};`
8487
}
88+
;(style as any)[CSS_VAR_TEXT] = cssText
8589
}
8690
}

packages/runtime-dom/src/modules/style.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { isString, hyphenate, capitalize, isArray } from '@vue/shared'
22
import { camelize, warn } from '@vue/runtime-core'
33
import { vShowOldKey } from '../directives/vShow'
4+
import { CSS_VAR_TEXT } from '../helpers/useCssVars'
45

56
type Style = string | Record<string, string | string[]> | null
67

@@ -22,6 +23,11 @@ export function patchStyle(el: Element, prev: Style, next: Style) {
2223
const currentDisplay = style.display
2324
if (isCssString) {
2425
if (prev !== next) {
26+
// #9821
27+
const cssVarText = (style as any)[CSS_VAR_TEXT]
28+
if (cssVarText) {
29+
;(next as string) += ';' + cssVarText
30+
}
2531
style.cssText = next as string
2632
}
2733
} else if (prev) {

pnpm-lock.yaml

Lines changed: 25 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)