Vue + Element UI front-end (6): Changing skin themes

Custom theme

Command line theme tool

1. Install theme tools

First install the "Theme Generation Tool", which can be installed globally or under the current project. It is recommended to install it in the project so that others can directly install the dependencies and start them when they clone the project.

yarn add element-theme --dev
2.Install the chalk theme

To install the Chalk theme, you can install it from npm or pull the latest code from GitHub, here install it from npm.

yarn add element-theme-chalk -D
3.Initialize variable file 

After the theme generation tool is successfully installed, if it is installed globally, you can call the tool through et on the command line. If it is installed in the current directory, you need to call it through node_modules/.bin/et Access the command. Execute -i to initialize the variable file. The default output is to element-variables.scss. Of course, you can pass parameters to specify the file output directory.

node_modules/.bin/et -i

Excuting an order

After the command is successfully executed, the scss file element-variables.scss will be generated in the root directory.

 

4. Modify the theme color 

Modify $–color-primary:#4b5f6e in the element-variables.scss file, which is the theme color you want

5. Compile theme 

Execute the theme compilation command to generate a theme, and a theme folder will be generated in the root directory.

node_modules/.bin/et

6. Introduce custom themes 

Rename the generated theme according to color and place it in the src/theme directory.

Import ‘path/index.css’ in main.js.

7. Effect display

After reloading, we see that the button color is no longer the default blue.

 

Dynamic skin changer method

1. Add the encapsulated skin-changing component at the location shown below.

index.vue

Copy code

<template>
  <el-color-picker
    class="theme-picker"
    popper-class="theme-picker-dropdown"
    v-model="theme"></el-color-picker>
</template>

<script>

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

export default {
  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
        }
      }

      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: 'Skin change successful',
        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>

<style>
.theme-picker .el-color-picker__trigger {
  vertical-align: middle;
}

.theme-picker-dropdown .el-color-dropdown__link-btn {
  display: none;
}
</style>

Copy code

 2. Directly reference in the component

 Introduced in Home.vue

Add a skin change component to the left of language switching

 3. Skin resurfacing test

Click on the component and select a color to confirm

We see that the relevant theme colors take effect immediately

Return to the login interface to view

 

Guess you like

Origin blog.csdn.net/y19910825/article/details/132696778