vue implementa el cambio de estilo de tema de múltiples ventanas y el siguiente cambio de sistema

vue implementa el cambio de estilo de tema de múltiples ventanas y el siguiente cambio de sistema

自我记录

1. Enlace a puntos de conocimiento: https://developer.mozilla.org/zh-CN/docs/Web/CSS/@media/prefers-color-scheme
1. Enlace a puntos de conocimiento: https://www.runoob. com/jsref/met-win-matchmedia.html
2. Supervisar los cambios de almacenamiento (comunicación cruzada)
3. Escucha watchEffect

1.js+css para que coincida con el color del tema del sistema

// 使用matchMedia API 去匹配css的媒体查询的 系统的主题是否为案(dark)颜色 (也可以去匹配屏幕的宽度高度等)
const match = matchMedia('(prefers-color-scheme:dark)')
console.log(match,'match');

Insertar descripción de la imagen aquí

2. Comunicación entre etiquetas

window.addEventListener('storage', (event) => {
    
    
      console.log(event.newValue)
    })

Cuando el almacenamiento de la página A cambia, la página B puede monitorearlo.
Insertar descripción de la imagen aquí

3. Supervisar los cambios en el almacenamiento local y asignar valores.

watchEffect(() => {
    
    
 localStorage.setItem(LOCAL_KEY, theme.value)
 document.documentElement.className = theme.value
})

4. Todos los códigos

<template>
  <a-layout-header class="head-box" :style="{ position: 'fixed', zIndex: 1, width: '100%' }">
    <a-row :gutter="{ xs: 24, sm: 24, md: 24, lg: 24 }">
      <a-col :xs="7" :sm="7" :md="7" :lg="7">奔跑的代码!</a-col>
      <a-col :xs="6" :sm="6" :md="6" :lg="6">奔跑的代码!</a-col>
      <a-col :xs="6" :sm="6" :md="6" :lg="6">奔跑的代码!</a-col>
      <a-col :xs="5" :sm="5" :md="5" :lg="5">
        <!-- 开关切换主题 -->
        <a-switch v-model:checked="checked" checked-children="经典" un-checked-children="深夜" @change="onChange" />
      </a-col>
    </a-row>
  </a-layout-header>
</template>
<script setup>
import {
    
     ref, watchEffect } from 'vue'

const checked = ref(false)
// 切换主题样式
// 'light' | 'dark'
const LOCAL_KEY = '__theme__'
const theme = ref(localStorage.getItem(LOCAL_KEY) || 'light')
// 使用matchMedia API 去匹配css的媒体查询的 系统的主题是否为案(dark)颜色 (也可以去匹配屏幕的宽度高度等)
const match = matchMedia('(prefers-color-scheme:dark)')
console.log(match,'match');
// 跟随系统
const followOs = () => {
    
    
  // 如果当前系统时暗色 
  if (match.matches) {
    
    
  	// 本地存储重新赋值
    localStorage.setItem(LOCAL_KEY, 'dark')
    // html 的class 重新赋值
    document.documentElement.className = 'dark'
    // 优化了 页面滑块按钮的赋值
    checked.value = true
  } else {
    
    
    localStorage.setItem(LOCAL_KEY, 'light')
    document.documentElement.className = 'light'
    checked.value = false
  }
}
// matchMedia 的API 当 matchMedia('(prefers-color-scheme:dark)') 查询结果有变化时
// 监听主题的变化 
match.addEventListener('change', followOs)

watchEffect(() => {
    
    
  // 仅需要多个标签页联动 用这俩  
  // localStorage.setItem(LOCAL_KEY, theme.value)
  // document.documentElement.className = theme.value
  // 使用跟随系统功能 用这个函数
  followOs()
})
// 这个是antd滑块的事件 
const onChange = (value) => {
    
    
  const temp = value ? 'dark' : 'light'
  if (value) {
    
    
    theme.value = temp
    localStorage.setItem(LOCAL_KEY, temp)
    document.documentElement.className = temp
  } else {
    
    
    theme.value = temp
    localStorage.setItem(LOCAL_KEY, temp)
    document.documentElement.className = temp
  }


};
// 监听本地存储的变化 为了实现多个标签页联动
addEventListener('storage', event => {
    
    
  console.log(event, 'ev');
  document.documentElement.className = event.newValue
  checked.value = event.newValue === 'light' ? false : true
})

</script>
<style lang="less" scoped>
.head-box {
    
    
  width: 100%;
  height: 64px;
  background: @bgc-head-color;
  padding: 0 20px;
}
</style>

elemento Plus cambio de tema

Efecto de visualización final

Las API de código utilizadas para implementar las funciones están todas arriba. También puede implementar las funciones deseadas según sus propias preferencias.
Al principio, solo implementé una función de cambio de tema. Ayer, una amiga de repente me dijo que su gerente de producto de hadas quería una. tantos como Element Plus. La función de cambio de tema de enlace de cada página de pestaña.
A continuación, está el código anterior. Si te ayuda, ¡dale me gusta y recógelo para respaldarlo!

A continuación se muestra mi registro de configuración simple de cambio de tema de vite+vue3+antd

Insertar descripción de la imagen aquí
Insertar descripción de la imagen aquí
Insertar descripción de la imagen aquí
vite.config.js

import {
    
    defineConfig} from 'vite'
import vue from '@vitejs/plugin-vue' //是vite 对vue 对支持插件
import Components from 'unplugin-vue-components/vite'
import path from 'path'
import themePreprocessorPlugin from "@zougt/vite-plugin-theme-preprocessor";
import VueSetupExtend from 'vite-plugin-vue-setup-extend'
import {
    
     AntDesignVueResolver } from 'unplugin-vue-components/resolvers'

// https://vitejs.dev/config/
export default defineConfig(({
     
      mode }) => {
    
    
    return {
    
    
        plugins: [
            vue(),
            VueSetupExtend(),
            Components({
    
    
                resolvers: [
                    AntDesignVueResolver({
    
    
                        importStyle: 'less', // 一定要开启这个配置项
                    }),
                ],
            }),
            themePreprocessorPlugin({
    
    
                less: {
    
    
                    // 各个主题文件的位置
                    multipleScopeVars: [
                        {
    
    
                            scopeName: "light",
                            path: path.resolve("src/assets/style/light.less"),
                        },
                        {
    
    
                            scopeName: "dark",
                            path: path.resolve("src/assets/style/dark.less"),
                        },
                    ],
                },
            }),
        ],
        base: "./",//公共基础路径 打包路径
        resolve: {
    
    
            alias: {
    
    
                '@': path.resolve(__dirname, './src')//别名设置
            },
            extensions: ['.js', '.ts', '.jsx', '.tsx', '.json', '.vue']
        },
        server: {
    
    
            // host: 'localhost',
            port: 8081,//启动端口
            // https: true, // 开启https
            open: true, // 自动开启窗口
            proxy: {
    
     // 代理配置
                '/api': {
    
    
                    target: 'xxx',//后端服务地址
                    changeOrigin: true,
                    rewrite: (path) => path.replace(/^\/api/, '') // 重写路径
                }
            },
        },
        css: {
    
    
            preprocessorOptions: {
    
    
                less: {
    
    
                    // modifyVars:
                    //     {
    
    
                    //         'primary-color': '#1DA57A',
                    //         'link-color': '#1DA57A',
                    //         'border-radius-base': '2px',
                    // },
                    additionalData: `@import './src/assets/style/index.less';`,
                    javascriptEnabled: true,
                },
                stylus: {
    
    
                    /*vite  根据官档  @import 引入stylus不生效 需要通过绝对路径导入 */
                    // imports: [path.resolve(__dirname, 'src/stylus/...styl')]  //配置全局变量
                }
            },
        },
    }
})

No es fácil de resumir, pero espero que les sea útil y que podamos aprender y progresar juntos.

Supongo que te gusta

Origin blog.csdn.net/zhgweb/article/details/131004125
Recomendado
Clasificación