文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Vue怎么使用Less与Scss实现主题切换

2023-07-05 06:48

关注

这篇文章主要介绍“Vue怎么使用Less与Scss实现主题切换”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Vue怎么使用Less与Scss实现主题切换”文章能帮助大家解决问题。

一、Less/Scss变量换肤

具体实现:

初始化vue项目

安装插件:

npm install style-resources-loader -D

npm install vue-cli-plugin-style-resources-loader -D

当然也要安装less、less-loader等插件,具体的安装配置,请自行google

新建theme.less文件用于全局样式配置。在src目录下新建theme文件夹,在这个文件夹下新建theme.less文件。具体如下:

/src/theme/theme.less// 默认的主题颜色@primaryColor: var(--primaryColor, #000);@primaryTextColor: var(--primaryTextColor, green);// 导出变量:export {  name: "less";  primaryColor: @primaryColor;  primaryTextColor: @primaryTextColor;}

配置vue.config.js文件,实现全局使用变量实现换肤

const path = require("path");module.exports = {  pluginOptions: {    "style-resources-loader": {      preProcessor: "less",      patterns: [        // 这个是加上自己的路径,不能使用(如下:alias)中配置的别名路径        path.resolve(__dirname, "./src/theme/theme.less"),      ],    },  },};

具体的使用:

<template>  <div class="hello">    <p>我是测试文字</p>  </div></template><script>export default {  name: "HelloWorld",};</script><style scoped lang="less">.hello {  p {    color: @primaryTextColor;  }}</style>

备注:如果是用scss也基本同以上用法,只是scss的变量名用&lsquo;$&rsquo;作为前缀,less使用@

至此,我们已经实现了静态更换皮肤,那如何实现动态换肤呢,最重要的就是以下的文件了。

我们可以多配置几种默认主题

在theme文件夹下新建model.js文件,用于存放默认主题

// 一套默认主题以及一套暗黑主题// 一套默认主题以及一套暗黑主题export const themes = {  default: {    primaryColor: `${74}, ${144},${226}`,    primaryTextColor: `${74}, ${144},${226}`,  },  dark: {    primaryColor: `${0},${0},${0}`,    primaryTextColor: `${0},${0},${0}`,  },};

实现动态切换:

在/src/theme文件夹下新建theme.js文件,代码如下:

import { themes } from "./model";// 修改页面中的样式变量值const changeStyle = (obj) => {  for (let key in obj) {    document      .getElementsByTagName("body")[0]      .style.setProperty(`--${key}`, obj[key]);  }};// 改变主题的方法export const setTheme = (themeName) => {  localStorage.setItem("theme", themeName); // 保存主题到本地,下次进入使用该主题  const themeConfig = themes[themeName];  // 如果有主题名称,那么则采用我们定义的主题  if (themeConfig) {    localStorage.setItem("primaryColor", themeConfig.primaryColor); // 保存主题色到本地    localStorage.setItem("primaryTextColor", themeConfig.primaryTextColor); // 保存文字颜色到本地    changeStyle(themeConfig); // 改变样式  } else {    let themeConfig = {      primaryColor: localStorage.getItem("primaryColor"),      primaryTextColor: localStorage.getItem("primaryTextColor"),    };    changeStyle(themeConfig);  }};

切换主题

this.setTheme('dark')

二、element-UI组件的换肤

一般elementUI主题色都有这样一个文件element-variables.scss:

$--color-primary: #1890ff;$--color-success: #13ce66;$--color-warning: #ffba00;$--color-danger: #ff4949;// $--color-info: #1E1E1E;$--button-font-weight: 400;// $--color-text-regular: #1f2d3d;$--border-color-light: #dfe4ed;$--border-color-lighter: #e6ebf5;$--table-border: 1px solid #dfe6ec;$--font-path: "~element-ui/lib/theme-chalk/fonts";@import "~element-ui/packages/theme-chalk/src/index";// the :export directive is the magic sauce for webpack// https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass:export {  theme: $--color-primary;}

main.js中引用

import './styles/element-variables.scss'

在store文件夹下新建settings.js文件,用于页面基础设置

import variables from '@/styles/element-variables.scss'const state = {  theme: variables.theme}const mutations = {  CHANGE_SETTING: (state, { key, value }) => {    // eslint-disable-next-line no-prototype-builtins    if (state.hasOwnProperty(key)) {      state[key] = value    }  }}const actions = {  changeSetting({ commit }, data) {    commit('CHANGE_SETTING', data)  }}export default {  namespaced: true,  state,  mutations,  actions}

一般换肤都是需要有个颜色选择器,用于皮肤设置

在src目录下新建ThemePicker文件夹,新建index.vue文件。

<template>  <el-color-picker    v-model="theme"    :predefine="['#409EFF', '#1890ff', '#304156','#212121','#11a983', '#13c2c2', '#6959CD', '#f5222d', ]"    class="theme-picker"    popper-class="theme-picker-dropdown"  /></template><script>const version = require('element-ui/package.json').version // element-ui version from node_modulesconst ORIGINAL_THEME = '#409EFF' // default colorexport default {  data() {    return {      chalk: '', // content of theme-chalk css      theme: ''    }  },  computed: {    defaultTheme() {      return this.$store.state.settings.theme    }  },  watch: {    defaultTheme: {      handler: function(val, oldVal) {        this.theme = val      },      immediate: true    },    async theme(val) {      const oldVal = this.chalk ? this.theme : ORIGINAL_THEME      if (typeof val !== 'string') return      const themeCluster = this.getThemeCluster(val.replace('#', ''))      const originalCluster = this.getThemeCluster(oldVal.replace('#', ''))      console.log(themeCluster, originalCluster)      const $message = this.$message({        message: '  Compiling the theme',        customClass: 'theme-message',        type: 'success',        duration: 0,        iconClass: 'el-icon-loading'      })      const getHandler = (variable, id) => {        return () => {          const originalCluster = this.getThemeCluster(ORIGINAL_THEME.replace('#', ''))          const newStyle = this.updateStyle(this[variable], originalCluster, themeCluster)          let styleTag = document.getElementById(id)          if (!styleTag) {            styleTag = document.createElement('style')            styleTag.setAttribute('id', id)            document.head.appendChild(styleTag)          }          styleTag.innerText = newStyle        }      }      if (!this.chalk) {        const url = `https://unpkg.com/element-ui@${version}/lib/theme-chalk/index.css`        await this.getCSSString(url, 'chalk')      }      const chalkHandler = getHandler('chalk', 'chalk-style')      chalkHandler()      const styles = [].slice.call(document.querySelectorAll('style'))        .filter(style => {          const text = style.innerText          return new RegExp(oldVal, 'i').test(text) && !/Chalk Variables/.test(text)        })      styles.forEach(style => {        const { innerText } = style        if (typeof innerText !== 'string') return        style.innerText = this.updateStyle(innerText, originalCluster, themeCluster)      })      this.$emit('change', val)      $message.close()    }  },  methods: {    updateStyle(style, oldCluster, newCluster) {      let newStyle = style      oldCluster.forEach((color, index) => {        newStyle = newStyle.replace(new RegExp(color, 'ig'), newCluster[index])      })      return newStyle    },    getCSSString(url, variable) {      return new Promise(resolve => {        const xhr = new XMLHttpRequest()        xhr.onreadystatechange = () => {          if (xhr.readyState === 4 && xhr.status === 200) {            this[variable] = xhr.responseText.replace(/@font-face{[^}]+}/, '')            resolve()          }        }        xhr.open('GET', url)        xhr.send()      })    },    getThemeCluster(theme) {      const tintColor = (color, tint) => {        let red = parseInt(color.slice(0, 2), 16)        let green = parseInt(color.slice(2, 4), 16)        let blue = parseInt(color.slice(4, 6), 16)        if (tint === 0) { // when primary color is in its rgb space          return [red, green, blue].join(',')        } else {          red += Math.round(tint * (255 - red))          green += Math.round(tint * (255 - green))          blue += Math.round(tint * (255 - blue))          red = red.toString(16)          green = green.toString(16)          blue = blue.toString(16)          return `#${red}${green}${blue}`        }      }      const shadeColor = (color, shade) => {        let red = parseInt(color.slice(0, 2), 16)        let green = parseInt(color.slice(2, 4), 16)        let blue = parseInt(color.slice(4, 6), 16)        red = Math.round((1 - shade) * red)        green = Math.round((1 - shade) * green)        blue = Math.round((1 - shade) * blue)        red = red.toString(16)        green = green.toString(16)        blue = blue.toString(16)        return `#${red}${green}${blue}`      }      const clusters = [theme]      for (let i = 0; i <= 9; i++) {        clusters.push(tintColor(theme, Number((i / 10).toFixed(2))))      }      clusters.push(shadeColor(theme, 0.1))      return clusters    }  }}</script><style>.theme-message,.theme-picker-dropdown {  z-index: 99999 !important;}.theme-picker .el-color-picker__trigger {  height: 26px !important;  width: 26px !important;  padding: 2px;}.theme-picker-dropdown .el-color-dropdown__link-btn {  display: none;}</style>

在使用ThemePicker组件的位置,去调用vuex中的changeSetting函数

 <theme-picker  @change="themeChange" />import ThemePicker from '@/components/ThemePicker'export default {  components: { ThemePicker },methods:{  themeChange(val) {      this.$store.dispatch('settings/changeSetting', {        key: 'theme',        value: val      })    }}}

关于“Vue怎么使用Less与Scss实现主题切换”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注编程网行业资讯频道,小编每天都会为大家更新不同的知识点。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯