fix(nuxt): use addEventListener to register cookie store listener (#28193)

This commit is contained in:
Daniel Roe 2024-07-18 15:52:40 +01:00 committed by GitHub
parent 0c3cc4cf30
commit eb31abe10e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 29 additions and 12 deletions

View File

@ -12,7 +12,8 @@ declare global {
interface Window { interface Window {
cookieStore?: { cookieStore?: {
onchange: (event: any) => void addEventListener: (type: 'change', listener: (event: any) => void) => void
removeEventListener: (type: 'change', listener: (event: any) => void) => void
} }
} }
} }

View File

@ -83,13 +83,16 @@ export function useCookie<T = string | null | undefined> (name: string, _opts?:
const handleChange = (data: { value?: any, refresh?: boolean }) => { const handleChange = (data: { value?: any, refresh?: boolean }) => {
const value = data.refresh ? readRawCookies(opts)?.[name] : opts.decode(data.value) const value = data.refresh ? readRawCookies(opts)?.[name] : opts.decode(data.value)
watchPaused = true watchPaused = true
cookies[name] = cookie.value = value cookie.value = value
cookies[name] = klona(value)
nextTick(() => { watchPaused = false }) nextTick(() => { watchPaused = false })
} }
let watchPaused = false let watchPaused = false
if (getCurrentScope()) { const hasScope = !!getCurrentScope()
if (hasScope) {
onScopeDispose(() => { onScopeDispose(() => {
watchPaused = true watchPaused = true
callback() callback()
@ -98,10 +101,14 @@ export function useCookie<T = string | null | undefined> (name: string, _opts?:
} }
if (store) { if (store) {
store.onchange = (event) => { const changeHandler = (event: any) => {
const cookie = event.changed.find((c: any) => c.name === name) const cookie = event.changed.find((c: any) => c.name === name)
if (cookie) { handleChange({ value: cookie.value }) } if (cookie) { handleChange({ value: cookie.value }) }
} }
store.addEventListener('change', changeHandler)
if (hasScope) {
onScopeDispose(() => store.removeEventListener('change', changeHandler))
}
} else if (channel) { } else if (channel) {
channel.onmessage = ({ data }) => handleChange(data) channel.onmessage = ({ data }) => handleChange(data)
} }

View File

@ -591,7 +591,7 @@ describe('nuxt composables', () => {
}, },
}) })
const cookies = res.headers.get('set-cookie') const cookies = res.headers.get('set-cookie')
expect(cookies).toMatchInlineSnapshot('"set-in-plugin=true; Path=/, set=set; Path=/, browser-set=set; Path=/, browser-set-to-null=; Max-Age=0; Path=/, browser-set-to-null-with-default=; Max-Age=0; Path=/, browser-object-default=%7B%22foo%22%3A%22bar%22%7D; Path=/"') expect(cookies).toMatchInlineSnapshot('"set-in-plugin=true; Path=/, accessed-with-default-value=default; Path=/, set=set; Path=/, browser-set=set; Path=/, browser-set-to-null=; Max-Age=0; Path=/, browser-set-to-null-with-default=; Max-Age=0; Path=/, browser-object-default=%7B%22foo%22%3A%22bar%22%7D; Path=/"')
}) })
it('updates cookies when they are changed', async () => { it('updates cookies when they are changed', async () => {
const { page } = await renderPage('/cookies') const { page } = await renderPage('/cookies')

View File

@ -1,28 +1,37 @@
<script setup> <script setup lang="ts">
useCookie('accessed-but-not-used') useCookie('accessed-but-not-used')
useCookie('accessed-with-default-value', () => 'default') useCookie('accessed-with-default-value', { default: () => 'default' })
useCookie('set').value = 'set' useCookie('set').value = 'set'
useCookie('set-to-null').value = null useCookie('set-to-null').value = null
useCookie('set-to-null-with-default', () => 'default').value = null useCookie<string | null>('set-to-null-with-default', { default: () => 'default' }).value = null
// the next set are all sent by browser // the next set are all sent by browser
useCookie('browser-accessed-but-not-used') useCookie('browser-accessed-but-not-used')
useCookie('browser-accessed-with-default-value', () => 'default') useCookie('browser-accessed-with-default-value', { default: () => 'default' })
useCookie('browser-set').value = 'set' useCookie('browser-set').value = 'set'
useCookie('browser-set-to-null').value = null useCookie('browser-set-to-null').value = null
useCookie('browser-set-to-null-with-default', () => 'default').value = null useCookie<string | null>('browser-set-to-null-with-default', { default: () => 'default' }).value = null
const objectCookie = useCookie('browser-object-default') const objectCookie = useCookie<{ foo: string } | undefined>('browser-object-default')
const objectCookieSecond = useCookie('browser-object-default', { const objectCookieSecond = useCookie('browser-object-default', {
default: () => ({ foo: 'bar' }), default: () => ({ foo: 'bar' }),
}) })
function changeCookie () {
console.log(objectCookie.value, objectCookieSecond.value)
if (objectCookie.value!.foo === 'baz') {
objectCookie.value!.foo = 'bar'
} else {
objectCookie.value!.foo = 'baz'
}
}
</script> </script>
<template> <template>
<div> <div>
<div>cookies testing page</div> <div>cookies testing page</div>
<pre>{{ objectCookie?.foo }}</pre>
<pre>{{ objectCookieSecond.foo }}</pre> <pre>{{ objectCookieSecond.foo }}</pre>
<button @click="objectCookie.foo === 'baz' ? objectCookie.foo = 'bar' : objectCookie.foo = 'baz'"> <button @click="changeCookie">
Change cookie Change cookie
</button> </button>
<button @click="refreshCookie('browser-object-default')"> <button @click="refreshCookie('browser-object-default')">