Elementui动态换肤

Posted 码小余の博客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Elementui动态换肤相关的知识,希望对你有一定的参考价值。

Elementui 动态换肤

ThemePicker.vue
<template>
  <el-tooltip effect="dark" content="theme" placement="bottom">
    <el-color-picker v-model="theme" class="theme-picker" size="small" popper-class="theme-picker-dropdown" />
  </el-tooltip>
</template>

<script>

const version = require('element-ui/package.json').version // element-ui version from node_modules
const ORIGINAL_THEME = '#409EFF' // default color

export default 
  name: "ThemePicker",
  data() 
    return 
      chalk: '', // content of theme-chalk css
      theme: ORIGINAL_THEME
    
  ,
  watch: 
    theme(val, oldVal) 
      if (typeof val !== 'string') return
      const themeCluster = this.getThemeCluster(val.replace('#', ''))
      const originalCluster = this.getThemeCluster(oldVal.replace('#', ''))
      console.log(themeCluster, originalCluster)
      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
          console.log(newStyle);
        
      

      const chalkHandler = getHandler('chalk', 'chalk-style')

      if (!this.chalk) 
        const url = `https://unpkg.com/element-ui@$version/lib/theme-chalk/index.css`
        this.getCSSString(url, chalkHandler, 'chalk')
       else 
        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.$message(
        message: '换肤成功',
        type: 'success'
      )
    
  ,

  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, callback, variable) 
      const xhr = new XMLHttpRequest()
      xhr.onreadystatechange = () => 
        if (xhr.readyState === 4 && xhr.status === 200) 
          this[variable] = xhr.responseText.replace(/@font-face[^]+/, '')
          callback()
        
      
      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>

以上是关于Elementui动态换肤的主要内容,如果未能解决你的问题,请参考以下文章

vue2.0-基于elementui换肤[自定义主题]

vue2.0-基于elementui换肤[自定义主题]

vue+element做换肤效果

今日头条Android岗面试题:说说Android动态换肤实现原理

Qt编写安防视频监控系统11-动态换肤

Databinding+LiveData轻松实现无重启换肤