Nuxt 3.0使用color-mode时dark/light切换不生效问题

背景

最近在开发一个基于Nuxt3.0和Nuxt/content2.0的markdown文章管理系统(支持静态和动态两种模式),项目在mindpress。其中引入了color-mode用来检测当前浏览器是 dark 模式,还是 light 模式。代码如下:


<template>
    <NavBar />
    <main class="container">
        <md-editor v-model="text" :theme="theme" :toolbarsExclude="toolbarsExclude"
            style="background-color: var(--md-background-color);height:480px;" 
            @onChange="changeAction" @onSave="saveAction" />
    </main>
</template>

<script>
import { ref } from 'vue';
import MdEditor from 'md-editor-v3';
import 'md-editor-v3/lib/style.css';

export default {
    setup() {
        const route = useRoute()
        const colorMode = useColorMode()
        const text = ref('')
        const id = route.params.id
        const toolbarsExclude = ['github']

        // three values: system dark light, TODO: md-editor not support 'system'.
        const theme = colorMode.value

        // demo id: 8dd81d
        return {
            id,
            text,
            toolbarsExclude,
            theme
        }
    },
    components: {
        MdEditor
    },
    mounted() {
        console.log("article_id=" + this.id);
        window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', event => {
            const newColorScheme = event.matches ? "dark" : "light";
        });
    },
    methods: {
        changeAction(e) {
            // console.log('ch')
        },
        saveAction(text) {
            console.log('--- now save event triggled. ---')
            console.log(text)
        }
    }
}
</script>

问题

我发现以上代码里使用 const theme = colorMode.value 在不同的端打印出来的值不一样。在node端(server端)显示的是这样:
在这里插入图片描述
在浏览器端(client端)显示的是这样:
在这里插入图片描述
client端显示的 colorMode.value 为 dark 正是我期望的,但事实上真实的拿到的是 system 这个值。这个问题刚开始的时候百思不得其解。

原因

因为Nuxt是SSR的,渲染是发生在服务端,而服务端拿到的这个color-mode值是不对的。其实color-mode的官网里有说明到,参考:https://color-mode.nuxtjs.org/#caveats

修复

添加 <ColorScheme>这个组件解决:

<template>
    <NavBar />
    <main class="container">
        <ColorScheme placeholder="..." tag="span">
            <md-editor v-model="text" :theme="$colorMode.value" :toolbarsExclude="toolbarsExclude" style="height:480px;"
                @onChange="changeAction" @onSave="saveAction" />
        </ColorScheme>
    </main>
</template>

<script>
import { ref } from 'vue';
import MdEditor from 'md-editor-v3';
import 'md-editor-v3/lib/style.css';

export default {
    setup() {
        const route = useRoute()
        const text = ref(DEMO_TEXT_MARKDOWN)
        const id = route.params.id
        const toolbarsExclude = ['github']

        // demo id: 8dd81d
        return {
            id,
            text,
            toolbarsExclude
        }
    },
    components: {
        MdEditor
    },
    mounted() {
        console.log("article_id=" + this.id);
        this.theme = 'dark'
    },
    methods: {
        changeAction(e) {
            // console.log('ch')
        },
        saveAction(text) {
            console.log('--- now save event triggled. ---')
            console.log(text)
        }
    }
}

</script>

版权声明:本文为loveaborn原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。