vue2 中,基于color-picker,二次封装一个颜色选择器

2,337 阅读2分钟

在vue2系统中,基于 vue-color插件的组件 Chrome,二次封装一个颜色选择器。

因为Chrome只有一个颜色面板,不够用。

image.png

我看 element PLUS 框架是有颜色选择器组件的color-picker

浅浅复制一下对方的样式来用,人家设计过的,挺好看的


未选择颜色的时候

image.png

用popover包起来,加上面板,及选择颜色后

image.png

加个保存按钮,以及点击、清空按钮,感觉中文不好看,放个英文,就酱紫啦

image.png

完整代码

<template>
  <div class="color-box">
    <el-popover
      placement="bottom"
      :width="265"
      v-model="popVisible"
    >
      <div>
        <chrome-picker v-model="colors" />
        <div class="btn-group">
          <el-button
            plain
            size="mini"
            @click="clearColor"
          >
            清除
          </el-button>
          <el-button
            plain
            type="primary"
            size="mini"
            @click="confirmColor"
          >
            确定
          </el-button>
        </div>
      </div>
      <template #reference>
        <div class="el-color-picker">
          <div class="el-color-picker__trigger">
            <span class="el-color-picker__color is-alpha">
              <span class="el-color-picker__color-inner" :style="`background-color: ${showColor};`">
                <i class="el-icon-arrow-down el-color-picker__icon"></i>
              </span>
            </span>
          </div>
        </div>
      </template>
    </el-popover>
  </div>
</template>

<script>
import { Chrome } from "vue-color";

export default {
  name: 'ReColorPicker',
  components: {
    "chrome-picker": Chrome,
  },
  props: {
    colorsConfig: {
      type: Object,
      default: () => ({
        hex: "#00000000", // 默认颜色 完全透明的黑色
        hex8: "#00000000", // 带透明度的颜色
      }),
    },
    colorStr: {
      type: String,
      default: "",
    },
  },
  data() {
    return {
      popVisible: false,  // 控制颜色选择器弹出框显示
      showColor: this.colorStr || this.colorsConfig.hex, // 初始化颜色
      colors: this.colorStr || this.colorsConfig.hex,  // 初始化颜色
    };
  },
  watch: {
    // 监听 colorStr 更新,更新颜色
    colorStr(newValue) {
      this.showColor = newValue || this.showColor;
      this.colors = newValue || this.colors;
    },
  },
  methods: {
    confirmColor() {
      const { hex8, hex } = this.colors;
      this.showColor = hex8 || hex; // 默认使用 hex8 或者 hex
      this.popVisible = false;
      this.$emit('colorChange', this.showColor); // 触发颜色变更事件
    },
    clearColor() {
      this.showColor = "";
      this.popVisible = false;
      this.$emit('colorChange', this.showColor);
    },
  },
};
</script>

<style scoped lang="scss">
.color-box {
  width: auto;
  height: 32px;
  display: inline-block;
  position: relative;
}

.el-color-picker{
  height: 32px;
  display: inline-block;
  position: relative;
  line-height: normal;
  outline: none;
  --el-color-picker-alpha-bg-a: #ccc;
  --el-color-picker-alpha-bg-b: transparent;

  .el-color-picker__trigger {
    display: inline-flex;
    justify-content: center;
    align-items: center;
    box-sizing: border-box;
    height: 32px;
    width: 32px;
    padding: 4px;
    border: 1px solid rgb(220, 223, 230);
    border-radius: 4px;
    font-size: 0;
    position: relative;
    cursor: pointer;
  }
  .el-color-picker__color {
    position: relative;
    display: block;
    box-sizing: border-box;
    border: 1px solid rgb(220, 223, 230);
    border-radius: 4px;
    width: 100%;
    height: 100%;
    text-align: center;
  }
  .el-color-picker__color.is-alpha {
    background-image: linear-gradient(45deg, var(--el-color-picker-alpha-bg-a) 25%, var(--el-color-picker-alpha-bg-b) 25%), linear-gradient(135deg, var(--el-color-picker-alpha-bg-a) 25%, var(--el-color-picker-alpha-bg-b) 25%), linear-gradient(45deg, var(--el-color-picker-alpha-bg-b) 75%, var(--el-color-picker-alpha-bg-a) 75%), linear-gradient(135deg, var(--el-color-picker-alpha-bg-b) 75%, var(--el-color-picker-alpha-bg-a) 75%);
    background-size: 12px 12px;
    background-position: 0 0, 6px 0, 6px -6px, 0 6px;
  }
  .el-color-picker__color-inner {
    display: inline-flex;
    justify-content: center;
    align-items: center;
    width: 100%;
    height: 100%;
  }

  .el-color-picker__icon {
    display: inline-flex;
    justify-content: center;
    align-items: center;
    color: #fff;
    font-size: 12px;
  }
}

.btn-group {
  display: flex;
  margin-top: 8px;
  justify-content: center;
  /deep/ .el-button {
    width: 60px;
  }
}

</style>

<style>
.vc-chrome {
  box-shadow: 0 0 1px rgba(0,0,0,.3), 0 0px 0px rgba(0,0,0,.3)!important;
}
</style>

使用此组件

<ReColorPicker @colorChange="(val) => { color1 = val }" :colorStr="color1"/>