vue3 使用css新属性v-bind (v-bind+pinia)实现颜色主题切换

1.注意点css v-bind的绑定方式

<template>
    <div class="box">
        123
        <div class="span">
            456
        </div>
    </div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
// 用法一
let color = ref('red');
// 用法二
let span = ref({
    color: 'blue',
    fontSize: '20px',
    width : '200px'
})
</script>
<style scoped lang="scss">
.box {
    color: v-bind(color);
    .span {
        // 对象调用需要使用字符串包裹
        color: v-bind('span.color') !important;
    }
}
</style>

2.开始实现颜色主题切换

2.1 创建一个文件 themeColorData.ts
// 这个文件用来定义主题颜色
export let themeColorData = {
  // 白色主题
  white: {
    bgColor: "#fff",
    textColor: "#000",
  },
  // 黑色主题
  black: {
    bgColor: "#000",
    textColor: "#fff",
  },
  // 橙色主题
  orange: {
    bgColor: "#ffa500",
    textColor: "#008000",
  },
  // 绿色主题
  green: {
    bgColor: "#008000",
    textColor: "#ffa500",
  },
};
2.2 创建 themeColorStore.ts 使用pinia来管理主题
import { defineStore } from "pinia";
interface themeColorType {
  bgColor: string;
  textColor: string;
}
interface State {
  themeColor: themeColorType;
}

export const themeColorStore = defineStore("themeColor", {
  state: (): State => ({
    // 默认主题颜色
    themeColor: {
      bgColor: "#000",
      textColor: "#fff",
    },
  }),
  actions: {
    // 修改颜色主题
    setThemeColor(data: themeColorType) {
      this.themeColor = data;
    },
  },
  // persist:true, // 整个 Store 将使用默认持久化配置保存。
  persist: {
    key: "themeColor", //存储名称
    storage: localStorage, // 存储方式
    paths: ["themeColor"], //指定 state 中哪些数据需要被持久化。[] 表示不持久化任何状态,undefined 或 null 表示持久化整个 state
  },
});

这里我使用了pinia的持久化 如果你也想持久化 跳转以下   pinia的持久化

2.3 创建一个组件 用来提供pinia 命名为piniaProvider.vue
<template>
    <slot></slot>
</template>
<script setup lang="ts">
import { defineComponent, provide } from 'vue'
import { themeColorStore } from '@/store/themeColorStore';
const themeColor = themeColorStore();
provide('themeColor', themeColor);
</script>
2.4 main.ts 导入这个组件 组件作为根组件的父组件
import { createApp } from 'vue'
import '@/assets/style/style.css'
import App from './App.vue';
// 导入状态管理
import pinia from "@/store/index";
// 实现一个pinia组件
import PiniaProvider from '@/components/piniaProvider.vue';
const app = createApp(App);
app.use(pinia);
app.component('pinia-provider', PiniaProvider);
app.mount('#app');
2.5 在你的app.vue使用这个组件 
<template>
    <pinia-provider>
        // 你的应用程序内容
        <router-view />
    </pinia-provider>
</template>
2.6 实现切换主题色 

不喜欢单个页面写css样式 请看下一步

<template>
    <div class="bg w-full h-screen">
        <el-button class="fs" @click="qiehuan('white')">白色</el-button>
        <el-button class="fs" @click="qiehuan('black')">黑色</el-button>
        <el-button class="fs" @click="qiehuan('orange')">橙色</el-button>
        <el-button class="fs" @click="qiehuan('green')">绿色</el-button>
    </div>
</template>
<script setup lang="ts">
// 引入主题色
import { themeColorData } from '@/utils/themeColorData';
import { ref , inject} from 'vue';
// 拿到pinia定义的颜色
const themeColor:any = inject('themeColor');

// 通过方法修改主题色
let qiehuan = (type:string) => {
    themeColor.setThemeColor(themeColorData[type]);
}
</script>
<style lang="scss">
.bg{
    background-color: v-bind('themeColor.themeColor.bgColor');
    .fs {
        color: v-bind('themeColor.themeColor.textColor');
    }
}
</style>
2.7 css 全局实现 不局限于单个页面 找到piniaProvider.vue组件
# 注意:你可以将通用的主题css写在piniaProvider这个组件里面去
# 这样下面的页面都能直接使用这个组件定义的css

<template>
    <slot></slot>
</template>
<script setup lang="ts">
import { defineComponent, provide } from 'vue'
import { themeColorStore } from '@/store/themeColorStore';
const themeColor = themeColorStore();
provide('themeColor', themeColor);
</script>
<style lang="scss">
// 在这里定义通用的主题颜色
.bg {
    background-color: v-bind('themeColor.themeColor.bgColor');
    .fs {
        color: v-bind('themeColor.themeColor.textColor');
    }
}
</style>

 这样下面的组件能直接使用piniaProvider.vue 定义的css

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值