主题定制的集中方案

方法一:不借助less或sass预处理器的情况

我们可以使用:root选择器选取html的根元素,在根元素上定义属性被当作全局属性

 :root是一个伪类,表示文档根元素,所有主流浏览器均支持 :root 选择器,除了 IE8 及更早的版本。在:root中声明相当于全局属性,只要当前页面引用了:root segment所在文件,都可以使用var()来引用。

使用方法

第一步:创建一个单独的文件color.css,专门用来存储根元素的属性,也就是全局属性

​
:root {
    /* 背景 */
    --background: white;
    --gradualBackground: linear-gradient(to right bottom, #ee7752, #e73c7e, #23a6d5, #23d5ab);
    --favoriteBg: #f8efd0;

    /* 字体 */
    --fontColor: black;
    /* 边框 */
    --borderColor: rgba(0, 0, 0, 0.5);
    /* 边框 */
    --borderHoverColor: rgba(110, 110, 110, 0.4);
    /* 文章字体 */
    --articleFontColor: #1f1f1f;
    /* 文章灰色字体 */
    --articleGreyFontColor: #616161;
    /* 评论背景颜色 */
    --commentContent: #F7F9FE;


    /* 主题背景 */
    --themeBackground: orange;
    /* 主题悬停背景 */
    --gradualRed: linear-gradient(to right, #ff4b2b, #ff416c);

    /* 导航栏字体 */
    --toolbarFont: #333333;
    /* 导航栏背景 */
    --toolbarBackground: rgba(255, 255, 255, 1);
    /* 灰色字体 */
    --greyFont: #797979;
    --maxGreyFont: #595A5A;
    /* footer背景 */
    --gradientBG: linear-gradient(-90deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);
    /* 白色遮罩 */
    --whiteMask: rgba(255, 255, 255, 0.3);
    /* max白色遮罩 */
    --maxWhiteMask: rgba(255, 255, 255, 0.5);
    --maxMaxWhiteMask: rgba(255, 255, 255, 0.7);
    /* mini白色遮罩 */
    --miniWhiteMask: rgba(255, 255, 255, 0.15);
    /* 透明 */
    --transparent: rgba(0, 0, 0, 0);
    /* mini黑色遮罩 */
    --miniMask: rgba(0, 0, 0, 0.15);
    /* 黑色遮罩 */
    --mask: rgba(0, 0, 0, 0.3);
    /* 半透明 */
    --translucent: rgba(0, 0, 0, 0.5);
    /* 深黑遮罩 */
    --maxMask: rgba(0, 0, 0, 0.7);


    --white: white;

    --red: red;
    --lightRed: #ff4b2b;
    --maxLightRed: #ff416c;
    --orangeRed: #EF794F;

    --azure: #ECF7FE;
    --blue: rgb(3, 169, 244);

    --lightGray: #DDDDDD;
    --maxLightGray: #EEEEEE;
    --maxMaxLightGray: rgba(242, 242, 242, 0.5);

    --lightGreen: #39c5bb;

    --green: #67C23A;
    --black: black;
    --lightYellow: #F4E1C0;

    --globalFont: SmileySans;

    --commentURL: url(../file/comment.jpg);
    --springBg: url(../file/bg1.jpg);
    --admireImage: url(../file/bg1.jpg);
    --toTop: url(../file/top.jpg);
    --bannerWave1: url(../file/bannerwave1.png) repeat-x;
    --bannerWave2: url(../file/bannerwave2.png) repeat-x;
    --verifyImage: url(../file/bg1.jpg);
    --toolbar: url(../file/bg.jpg);
    --love: url(../file/bg.jpg);
    --bg:url('https://blog-ethereal-hx.oss-cn-heyuan.aliyuncs.com/bg1.webp') no-repeat fixed;
}

​

 第二步:将color.css引入到入口文件。比如在vue项目就引入到mian.js

import './assets/css/color.css'

第三步:在vue组件使用以及在其他.css样式文件使用

     var()函数可以代替元素中任何属性中的值的任何部分。var()函数不能作为属性名、选择器或者其他除了属性值之外的值。(这样做通常会产生无效的语法或者一个没有关联到变量的值。)

<div style="background: var(--background)">
</div>


<style> 
.printer {
    cursor: pointer;
    color: var(--white);
    background: var(--translucent);
    border-radius: 10px;
    padding-left: 10px;
    padding-right: 10px;
  }

  #bannerWave1 {
    height: 84px;
    background: var(--bannerWave1);
    position: absolute;
    width: 200%;
    bottom: 0;
    z-index: 10;
    animation: gradientBG 120s linear infinite;
  }
</style>

实际运用场景:黑夜白天切换

<template>
  <div class="my-setting">
       <div>
            <!-- 太阳按钮 -->
            <i
              v-if="isDark"
              class="el-icon-sunny"
              @click="changeColor()"
            ></i>
            <!-- 月亮按钮 -->
            <i
              v-else
              class="fa fa-moon-o"
              @click="changeColor()"
            ></i>
        </div>
   <div>
</template>


<script>
import { getCity } from "../utils/getCity"
import mousedown from '../utils/mousedown';
import { mapMutations } from 'vuex';
export default {
  data () {
    return {
      isDark: false
    }
  },
  mounted () {
    if (this.isDaylight()) {
      this.isDark = true;
      let root = document.querySelector(":root");
      root.style.setProperty("--background", "#272727");
      root.style.setProperty("--fontColor", "white");
      root.style.setProperty("--borderColor", "#4F4F4F");
      root.style.setProperty("--borderHoverColor", "black");
      root.style.setProperty("--articleFontColor", "#E4E4E4");
      root.style.setProperty("--articleGreyFontColor", "#D4D4D4")
      root.style.setProperty("--commentContent", "#D4D4D4");
      root.style.setProperty("--favoriteBg", "#1e1e1e");
    }
  },
  methods: {
    // 手动切换
    changeColor () {
      this.isDark = !this.isDark;
      let root = document.querySelector(":root");
      if (this.isDark) {
        root.style.setProperty("--background", "#272727");
        root.style.setProperty("--fontColor", "white");
        root.style.setProperty("--borderColor", "#4F4F4F");
        root.style.setProperty("--borderHoverColor", "black");
        root.style.setProperty("--articleFontColor", "#E4E4E4");
        root.style.setProperty("--articleGreyFontColor", "#D4D4D4");
        root.style.setProperty("--commentContent", "#D4D4D4");
        root.style.setProperty("--favoriteBg", "#1e1e1e");
      } else {
        root.style.setProperty("--background", "white");
        root.style.setProperty("--fontColor", "black");
        root.style.setProperty("--borderColor", "rgba(0, 0, 0, 0.5)");
        root.style.setProperty("--borderHoverColor", "rgba(110, 110, 110, 0.4)");
        root.style.setProperty("--articleFontColor", "#1F1F1F");
        root.style.setProperty("--articleGreyFontColor", "#616161");
        root.style.setProperty("--commentContent", "#F7F9FE");
        root.style.setProperty("--favoriteBg", "#f7f9fe");
      }
    },
       //页面加载的完,根据时间判断白天黑夜 
    isDaylight () {
      let currDate = new Date();
      if (currDate.getHours() > 22 || currDate.getHours() < 7) {
        return true;
      } else {
        return false;
      }
    },
  }
}
</script>

方法二:借用less预处理器实现

借用less可以定义变量的特性来实现

想了解跟多有关less的特性可以看预处理器Less_less预处理器-CSDN博客

实际运用场景:复杂的主题设置

第一步:在src下创建theme文件夹,然后创建model.js文件,用来装各种主题对象:

这里我只定义了白天主题和夜晚主题

//model.js
// 一套白天主题以及一黑夜主题
export const themes = {
  default: {
    primaryColor: '#fff',
    primaryTextColor: '#000'
  },
  dark: {
    primaryColor: '#000',
    primaryTextColor: '#fff'
  }
}

第二步:在theme文件下创建theme.js,用来定义改变主题的方法:

import { themes } from './model'
// 修改页面中的样式变量值
const changeStyle = (obj) => {
  for (const key in obj) {
    document
      .getElementsByTagName('body')[0]
      .style.setProperty(`--${key}`, obj[key])
  }
}
// 改变主题的方法
export const setTheme = (themeName) => {
  const themeConfig = themes[themeName]
  // 如果有主题名称,那么则采用我们定义的主题
  if (themeConfig) {
    changeStyle(themeConfig) // 改变样式
  } else {
   ...
  }
}

第三步:将当前主题名称themeName保存到Vuex中进行全局管理,方便所有组件使用

// 将风格
import { setTheme } from '../theme/theme'

export default new Vuex.Store({
  state: {
    theme: localStorage.getItem('theme') || 'default',//如果本地没有记录,就让主题默认
  },
  getters: {
  },
  mutations: {
    setThemeStore (state, theme) {
      setTheme(theme)
      localStorage.setItem('theme', theme) // 保存主题到本地,下次进入使用该主题
    },
  },
  actions: {},
  modules: {}
})

这一步弄好了其实基本上实现了,但是以上都没有涉及到less的变量定义。为了让我们样式变得更加灵活,最好加上less预处理器,让我们的代码享受更高效的编程。

第四步:在theme文件新建style.less文件,用于定义变量

首先必须下载以下包作为加载器,因为浏览器不认识less

npm i less less-loader

然后对vue.config.js进行配置:

const { defineConfig } = require('@vue/cli-service')
const path = require('path')
module.exports = defineConfig({
  transpileDependencies: true,
  pluginOptions: {
    'style-resources-loader': {
      preProcessor: 'less',
      patterns: [
        // 加上自己的路径--任何组件中都能使用less中的变量
        path.resolve(__dirname, './src/theme/style.less')
      ]
    }
  }
})

theme/style.less: 

// 默认的主题颜色
@primaryColor: var(--primaryColor);
@primaryTextColor: var(--primaryTextColor);

样式中使用less变量:

<style lang="less">
.contanier {
  background-color: @primaryColor;
  color: @primaryTextColor;
  position: relative;
  width: 100wv;
}
</style>

 实现主题切换:

<template>
  <div id="app">
    <div class="center">
      <div class="switch" @click="setThemeStoreFn">
        <img
          src="@/assets/images/绳子.png"
          alt=""
          width="15px"
          height="100%"
          text="切换为黑暗模式"
        />
      </div>
    </div>
  </div>
</template>

<script>
export default {
 data () {
    return {
      isRouterAlive: true,
      light: ''
    }
  },
  methods: {
    setThemeStoreFn () {
      if (this.light === 'default') {
        this.setThemeStore('dark')
        this.light = 'dark'
      } else {
        this.setThemeStore('default')
        this.light = 'default'
      }
    },
    // 主题初始化
    init () {
      this.setThemeStore(this.$store.state.theme)
      this.light = this.$store.state.theme
    },
    ...mapMutations(['setThemeStore'])
  },
  mounted () {
    this.init() // 调用初始化主题方法
  },
}
</script>

以上是我用到过的主题切换方法,先总结到这里。

  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值