问题#
每次刷新时,页面闪屏,比如设置了黑色刷新初始为白色, 然后又变为黑色
原因#
useDark 默认存储在 local storage 中,而 ssr 状态下获取不到 local storage
处理#
// nuxt.config.ts
export default defineNuxtConfig({
app: {
head: {
script: [
{
innerHTML: `
(function() {
const isDark = localStorage.getItem('darkMode') === 'true' ||
(!localStorage.getItem('darkMode') && window.matchMedia('(prefers-color-scheme: dark)').matches);
document.documentElement.classList.toggle('dark', isDark);
})();
`,
type: 'text/javascript',
},
],
},
},
})
后续问题#
Hydration class mismatch
原因#
虽然解决了闪屏问题,但是 useDark 在 ssr 时初始化的值还是一个错误的值(获取不到 local storage)
解决#
使用 seesion 来存储
const isDark = useDark({
storageKey: 'vueuse-color-scheme',
storage: {
getItem(key: string) {
if (import.meta.server) {
// 服务端从 headers 中获取 cookie
const cookieStr = useRequestHeaders(['cookie'])?.cookie || ''
return cookieStr.split('; ').find(row => row.startsWith(key))?.split('=')[1] || null
}
return document.cookie.split('; ').find(row => row.startsWith(key))?.split('=')[1] || null
},
setItem(key: string, value: string) {
document.cookie = `${key}=${value};path=/;max-age=${60 * 60 * 24 * 30}`
},
} as Storage,
})
// nuxt.config.ts
script: [
{
innerHTML: `
(function() {
var getCookie = function(name) {
return document.cookie.split('; ').find(row => row.startsWith(name))?.split('=')[1] || null;
};
var darkMode = getCookie('vueuse-color-scheme');
if (darkMode === 'dark') {
document.documentElement.classList.add('dark');
} else {
document.documentElement.classList.remove('dark');
}
})();
`,
type: 'text/javascript',
},
],