zoukankan      html  css  js  c++  java
  • 基于elementUI 的颜色选择器组件

    组件代码:

    <template>
      <el-color-picker
        v-model="theme"
        class="theme-picker"
        :predefine="predefineColors"
        popper-class="theme-picker-dropdown"
      >
      </el-color-picker>
    </template>
    
    <script>
    const version = require("element-ui/package.json").version; // 版本号
    const ORIGINAL_THEME = "#409EFF";
    
    export default {
      name: "colorPicker",
      data() {
        return {
          chalk: "",
          theme: ORIGINAL_THEME,
          predefineColors: [
            "#409EFF",
            "#ff4500",
            "#ff8c00",
            "#ffd700",
            "#90ee90",
            "#00ced1",
            "#1e90ff",
            "#c71585"
          ]
        };
      },
      mounted() {
        if (this.CheckIsColor(localStorage.getItem("colorPicker"))) {
          this.theme = localStorage.getItem("colorPicker");
        }
      },
      watch: {
        theme(val, oldVal) {
          if (typeof val !== "string") return;
          localStorage.setItem("colorPicker", val);
          const themeCluster = this.getThemeCluster(val.replace("#", ""));
          const originalCluster = this.getThemeCluster(oldVal.replace("#", ""));
          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
            );
          });
          /* 当颜色改变时,使用vuex储存改变的颜色值 */
          this.$store.commit({
            type: "getThemeColor",
            color: val
          });
        }
      },
    
      methods: {
        CheckIsColor(bgVal) {
          var type = "^#[0-9a-fA-F]{6}$";
          var re = new RegExp(type);
          if (bgVal.match(re) == null) {
            type =
              // eslint-disable-next-line no-useless-escape
              "^[rR][gG][Bb][(]([\s]*(2[0-4][0-9]|25[0-5]|[01]?[0-9][0-9]?)[\s]*,){2}[\s]*(2[0-4]\d|25[0-5]|[01]?\d\d?)[\s]*[)]{1}$";
            re = new RegExp(type);
            if (bgVal.match(re) == null) {
              return false;
            } else {
              return true;
            }
          } else {
            return true;
          }
        },
        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>
    View Code

    存入到 store中:

    import Vue from "vue";
    import Vuex from "vuex";
    
    Vue.use(Vuex);
    
    export default new Vuex.Store({
      state: {
        /* 默认的主题颜色 */
        themeColor: "#409EFF"
      },
      getters: {},
      mutations: {
        getThemeColor(state, payload) {
          state.themeColor = payload.color;
        }
      },
      actions: {}
    });
    View Code

    最后在需要用到的组件中使用即可,如果想要全局使用可以直接在APP.vue中引入该组件。

    详情参考:https://blog.csdn.net/qq_42268364/article/details/101720295

  • 相关阅读:
    剑指offer【面试题10 :矩形覆盖】
    剑指offer【面试题3 :二维数组中的查找】
    GStreamer Tutorials
    CMake Tutorial
    python
    python
    python-线程、进程、协程
    python-类的继承
    python-操作缓存
    python-线程池
  • 原文地址:https://www.cnblogs.com/jervy/p/14251331.html
Copyright © 2011-2022 走看看