• 利用less实现多主题切换(配合天气现象)


    1. 先看效果:效果图
    2. 话不多说直接撸吧:

    • 原理:先给body元素添加style,再根据天气现象动态更改style
      在这里插入图片描述

    • 开撸:

    • 创建src/assets/style/variables.less 使用 @XXX:var(–XXX,‘style’) 声明系列变量,之后添加其他变量直接增加即可(由于之后要配置颜色,默认值可以先给" ")
      也可以声明一下常用的class,方便全局使用(这里已.backgroundCard 为例)

    // 默认的主题颜色
    @backgroundImg: var(--backgroundImg, ''); //背景
    @backgroundCard: var(--backgroundCard, ''); //卡片背景
    @backgroundTab: var(--backgroundTab, ''); //底部tab背景
    @backgroundDeep: var(--backgroundDeep, ''); //小时累计背景
    @backgroundDeepTextColor: var(--backgroundDeepTextColor, ''); //小时累计字体颜色
    @textColorStyle: var(--textColorStyle, ''); //卡片内的(包括不限于温度,降水,风)值得颜色
    @textColorStyleBottom: var(--textColorStyleBottom, ''); //卡片内的(包括不限于温度,降水,风)值下面的描述颜色
    @backgroundCardLine: var(--backgroundCardLine, ''); //卡片标题下面的线条
    @colorStopsOffset1: var(--colorStopsOffset1, ''); //echarts折线图渐变色0%处
    @colorStopsOffset2: var(--colorStopsOffset2, ''); //echarts折线图渐变色100%处
    @lineStyleClor: var(--lineStyleClor, ''); echarts折线颜色
    @backgroundPrecipitation: var(--backgroundPrecipitation, ''); //降水按钮背景
    @r: 25rem;
    //首页卡片
    .backgroundCard {
      position: relative;
      padding: 14 / @r;
      border-radius: 14 / @r;
      background-color: @backgroundCard;
      text-align: center;
      font-size: 13 / @r;
      color: #fff;
      margin-bottom: 14 / @r;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 创建src/config/model.ts 声明所有类型主题themes
    //定义主题使用条件及强制使用时间
    export const weatherType: any = [
      { typeNames: ['默认底部tabber'], theme: 'defaultTabbar', mandatoryUsageTime: [] },
      { typeNames: ['晴'], theme: 'default', mandatoryUsageTime: [] },
      {
        typeNames: [
          '雨',
          '阴',
          '阵雨',
          //...
        ],
        theme: 'rain',
        mandatoryUsageTime: []
      },
      { typeNames: ['夜晚'], theme: 'dark', mandatoryUsageTime: ['22:00:00', '7:00:00'] }
    ]
    // 定义主题色变量值
    // 默认使用default(蓝色);  '雾'使用rain(灰色);
    // 在mandatoryUsageTime[开始时间,第二天结束时间]之间使用dark
    export const themes: any = {
      defaultTabbar: {
        backgroundCard: 'rgba(35,115,191,0.8)',
        backgroundTab: 'rgba(35,115,191,0.8)',
        textColorStyle: '#FFDE3D'
      },
      default: {
        backgroundImg: 'url(/images/weatherBg/img-qinbtian.png)',
        backgroundCard: 'rgba(35, 115, 191, 0.80)',
        backgroundTab: '#2373BF',
        backgroundDeep: '#1C6CB7',
        backgroundDeepTextColor: '#00A4FF',
        backgroundPrecipitation: 'rgba(35, 115, 191, 0.80)',
        textColorStyle: '#FFDE3D',
        backgroundCardLine: 'rgba(255,255,255,.2)',
        textColorStyleBottom: '#95bde3',
        colorStopsOffset1: 'rgba(110, 186, 255,1)',
        colorStopsOffset2: 'rgba(255,255,255,0)',
        lineStyleClor: '#00A4FF'
      },
      dark: {
        backgroundImg: 'url(/images/weatherBg/img-wanshang.png)',
        backgroundCard: 'rgba(16, 4, 77, 0.80)',
        backgroundTab: '#10044D',
        backgroundDeep: '#281A72',
        backgroundDeepTextColor: '#D9D9D9',
        backgroundPrecipitation: 'rgba(16, 4, 77, 0.80)',
        textColorStyle: '#EB6ECC',
        backgroundCardLine: 'rgba(255,255,255,.2)',
        textColorStyleBottom: '#918ca9',
        colorStopsOffset1: 'rgba(235, 110, 204,1)',
        colorStopsOffset2: 'rgba(255,255,255,0)',
        lineStyleClor: '#EB6ECC'
      },
      rain: {
        backgroundImg: 'url(/images/weatherBg/img-yingtian.png)',
        backgroundCard: 'rgba(82, 102, 126, 0.80)',
        backgroundTab: '#52667E',
        backgroundDeep: '#4D617B',
        backgroundDeepTextColor: '#B5B5B5',
        backgroundPrecipitation: 'rgba(82, 102, 126, 0.8)',
        textColorStyle: '#64D2FE',
        backgroundCardLine: 'rgba(255,255,255,.2)',
        textColorStyleBottom: '#adb7c4',
        colorStopsOffset1: 'rgba(110, 186, 255,1)',
        colorStopsOffset2: 'rgba(255,255,255,0)',
        lineStyleClor: '#00A4FF'
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 创建src/config/weatherTheme.ts 进行逻辑处理
    import { themes, weatherType} from './model'
    import { store, pinia } from '@src/store'
    import { ref } from 'vue'
    import dayjs from 'dayjs'
    import * as webStorage from '@src/utils/web-storage'
    
    /**
     * 传入天气现象名称更改主题
     * @param typeName 天气现象名称
     */
    export function changeTheme(typeName) {
      const day = dayjs().format('YYYY-MM-DD')
      const dayAdd1 = dayjs().add(1, 'days').format('YYYY-MM-DD')
      const nowTime_ = new Date().getTime()
      let theme = 'default'
      for (let i = 0; i < weatherType.length; i++) {
        const ele = weatherType[i]
        store.system.useThemeStore(pinia).changeIsDark(false)
        //有强制使用时间先使用强制时间 ['21:00:00', '10:00:00']
        if (ele.mandatoryUsageTime.length && typeName != '默认底部tabber') {
          const sTime = `${day} ${ele.mandatoryUsageTime[1]}` //2023-08-09 22:00:00
          const eTime = `${day} ${ele.mandatoryUsageTime[0]}` //2023-08-10 10:00:00
          const sTime_ = dayjs(sTime).valueOf() //2023-08-09 09:44:00
          const eTime_ = dayjs(eTime).valueOf()
          if (nowTime_ >= sTime_ && nowTime_ <= eTime_) {
          } else { //使用夜晚风格
            setTheme(ele.theme)
            store.system.useThemeStore(pinia).changeIsDark(true)
            return
          }
        } else {
          if (ele.typeNames.includes(typeName)) theme = ele.theme
        }
      }
      setTheme(theme)
    }
    
    // 修改页面中的样式变量值
    const changeStyle = (obj: any, themeName: string) => {
      //存入主题类型
      store.system.useThemeStore(pinia).changeThemeType(themeName)
      for (const key in obj) {
        document.getElementsByTagName('body')[0].style.setProperty(`--${key}`, obj[key])
        //存入主题色
        store.system.useThemeStore(pinia).changeWeatherThemeObj(`--${key}`)
      }
    }
    // 改变主题的方法
    export const setTheme = (themeName: any) => {
      const themeConfig = themes[themeName]
      changeStyle(themeConfig, themeName)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 使用:再需要改变主题的页面或者逻辑中使用changeTheme()方法即可(这里已首次进入的.vue文件为例)
    //首先使用上次的主题
    const weatherThemeName = webStorage.getLocalStorage(`weatherThemeName`)
    changeTheme(weatherThemeName || '晴'
    )
    //我业务的逻辑是动态获取天气现象,根据天气现象的不同使用不同的主题,这里可以改成自己的逻辑(方法有筛检)
    const getWeatherInfo = async (time, posInfo) => {
      await api.windRain
        .weatherLiveBypoint() //自己的方法
        .then(res => {
          if (!res.code && res.data) {
            const data = res.data
            //只有再首页“风雨”模块使用,防止底部切换过快
            if (router.value.meta.title == pageStore.defaultname) {
              //每次将天气现象存到storage里,下次进来直接取
              webStorage.setLocalStorage('weatherThemeName', data.wpName)
              changeTheme(data.wpName || '晴')
            }
          }
          emit('getWeatherInfoData', weatherInfoData)
        })
    }
    
    getWeatherInfo()
    //css使用,这里只是一部分,在相应的class后直接使用之前定义的方法即可
    <style lang="less" scoped>
    .page-wind-rain {
      width: 100%;
      height: 100%;
      background-image: @backgroundImg;
      background-size: 100% 100%;
      background-color: @backgroundCard;	
    }
    </style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • vite.config.ts配置
      最后将我们定义的variable.less在css预处理器中配置
      在这里插入图片描述

    • 大功告成!!!

    在这里插入图片描述

  • 相关阅读:
    构建镜像,执行chown -R非常慢
    Apollo在NetCore实践
    R语言获取data.table数据中指定数据列的最小值所在的数据行(minimum)
    HttpSession的常见用法(javaWeb)
    Linux命令之sed批量替换字符串
    在Centos上配置bgp路由
    FFN -> GLU -> GAU
    《PostgreSQL中的JSON处理:技巧与应用》
    带头+双向+循环链表
    「JVS低代码开发平台」关于逻辑引擎的触发讲解
  • 原文地址:https://blog.csdn.net/cnailili/article/details/132756899