前端网站动态主题色解决方案

本文详细介绍了如何实现UI组件库如Element-UI和Vant-UI的主题色动态替换,通过获取远程CSS并替换颜色,实现在不刷新页面的情况下改变应用主题。同时,提出了系统主题色替换的方案,即通过后端存储用户自定义主题,并在用户访问时从数据库中获取。文章提供了关键代码示例,并鼓励读者进行实践。
摘要由CSDN通过智能技术生成

动态主题色替换分两种:UI 组件库主题色替换系统主题色替换

组件库 UI 动态主题替换现阶段只在 Element-UI 和 Vant-UI 测试过,根据排查这种方案应该适用于所有类似的动态主题色替换场景。

1. UI 组件库主题色替换

在进入到这一部分之前,需要了解PC和移动端项目在本地或者在正式运行环境运行的情况下,项目文件是不可以写的。

首先,通过 XHR 请求获取到远程原始的 css 资源。拿到原始数据之后,我们存在在某个变量中,便于后期处理。

 /**
   * 获取远程 css 内容,便于二次修改 css 样式
   * @param {url} string css 存放地址(记得解决跨域问题)
   * @param {variable} string 读取 css 内容之后,赋予的值的变量名
*/
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()
  })
}

然后,我们对我们的通过方法处理我们需要转换成的主题颜色生成themeCluster。同时,我们以相同的方式处理原始的主题颜色生成originalCluster。最后,我们需要通过正则的方式,用新的主题色取代原始的主题色,输出处理后的数据,得到处理完的数据后,将数据动态的写入到header头部。

由此一个替换组件主题色的流程结束。涉及的代码如下:

/**
 * 动态往头部插入 style 标签
 * @param {variable} string 存在的变量
 * @param {id} string 用于标记 style attr
 * @param {color} 要替换的主题颜色
*/
getHandler (variable, id, color) {
  return () => {
    const themeCluster = this.getThemeCluster(color.replace('#', ''))
    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
  }
}

处理新旧主题色的函数:

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
},

使用replace方式通过匹配正则去将原始主题色换成新的主题色。

/**
 * 用新的 color 替换旧的 color
 * @param {*} style 
 * @param {*} oldCluster 旧 color
 * @param {*} newCluster 新 color
 */
updateStyle(style, oldCluster, newCluster) {
  let newStyle = style
  oldCluster.forEach((color, index) => {
    newStyle = newStyle.replace(new RegExp(color, 'ig'), newCluster[index])
  })
  return newStyle
}

总的代码都已经一一列举,大家感兴趣可以亲自实践一下。

🎉 有问题下方评论探讨一下。(上方代码是在 Vue2.x 版本中进行编写,大家可以根据具体的应用进行稍微改写)

2. 系统主题色替换

系统主题色替代方案,我只提供一下方案,代码就不具体写了。系统主题色可以通过后端请求,将用户变更的主题配色保存在sql中,每个用户修改的主题色有一个对应的表记录,下次访问的时候可以从表中取出。

用户访问系统,系统的主题展示根据登录用户的唯一标记来从数据库查询,没有找到用默认,找到使用数据库数据。拿到则用数据库记录,没有查到等异常情况用默认主题色。

上面就是我自己对UI 组件库主题色替换系统主题色替换的具体实现的相关介绍和具体思路,描述不清楚或者描述不对可以在下方评论。

👏 谢谢大家花时间观看,希望大家都有所收获。

— 微信公众号:全栈之鬼影重重 —
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值