0
点赞
收藏
分享

微信扫一扫

vue自定义颜色选择器

承蒙不弃 2022-01-12 阅读 110

样式效果

在这里插入图片描述

说明

以上效果是基于第三方插件二次封装得来。 默认第三方插件只有如下样式:
在这里插入图片描述
第三方插件源码地址: vColorPicker

使用 :

1. 安装插件

npm install vcolorpicker -S

2. 全局注册

# main.js
import vcolorpicker from 'vcolorpicker'
Vue.use(vcolorpicker)

3. 基于vColorPicker二次封装子组件 : ColorPick

子组件文档说明
传参props :

color:数据类型(字符),默认颜色值(非必须)

插槽slot:

inset:自定义按钮样式

事件event:

change :颜值值改变, 参数:(新的颜色 )

<template>
<div
style="height:38px;"
@click="openColor"
>

<slot
name="inset"
:row="nowColor"
>
</slot>
<colorPicker
style="marginLeft:10px;marginTop:-20px"
ref="colorPicker"
v-model="nowColor"
@hide="close"
:defaultColor="nowColor"
@change="headleChangeColor"
>
</colorPicker>
</div>
</template>

<script>
export default {
data () {
return {
nowColor: ""
}
},
created () {
this._initData()
},
watch: {
color: '_initData'
},
beforeMount(){
this._close = (e)=>{
if(this.$el.contains(e.target)) return
this.$emit('hide')
}
document.body.addEventListener('click', this._close)
},
beforeDestroy(){
document.body.removeEventListener('click',this._close)
},
props: {
color: {
type: String,
default: "#7993ae"
}
},
methods: {
_initData () {
this.nowColor = this.$props.color
},
headleChangeColor (item) {
this.$emit('change', item)
},
openColor () {
this.$refs.colorPicker.openPanel()
this.$emit('open')
},
},
}
</script>

<style scoped lang="less">
/deep/ .m-colorPicker .colorBtn {
width: 0;
height: 0;
}
</style>

4. 父组件调用

<template>
<div style="width:100px">
<ColorPick
@change="change"
@open="changeDom(true)"
@hide="changeDom(false)"
:color="color"
>

<template v-slot:inset="{row}">
<div class="selectColor">
<div
class="box"
:style="{backgroundColor:row}"
>
</div>
<div
class="el-icon-arrow-up change"
ref="rotate"
>
</div>
</div>
</template>
</ColorPick>
</div>
</template>

<script>
import ColorPick from "./children/index.vue"

export default {
data () {
return {
color: '#ccc'
}
},
methods: {
// change颜色改变
change () {
this.changeDom(false)
},
// 边框和连接线的颜色选择样式切换
changeDom (item) {
this.$refs.rotate.className = item ? "el-icon-arrow-up change rotate" : "el-icon-arrow-up change"
},

},
components: {
ColorPick
}
}
</script>

<style scoped lang="less">
.selectColor {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
height: 40px;
border: 1px solid #dcdfe6;
box-sizing: border-box;
border-radius: 6px;
cursor: pointer;
.box {
position: static;
width: 48px;
height: 20px;
left: 8px;
top: 6px;
background: #6866ff;
border-radius: 4px;
flex: none;
order: 0;
flex-grow: 0;
margin: 0px 4px;
}

.change {
transition: all 0.5s;
transform: rotate(180deg);
margin-right: 10px !important;
color: #dccfce;
}
.rotate {
transform: rotate(0deg);
}
}
</style>

补充说明

如果该功能作用在 el-popover中, 就会存在在el-popover组件中无法执行给body添加的click事件,因此,就无法执行回调的hide参数。
解决办法:

  1. 不需要ui样式切换效果。三角箭头直接朝下即可
  2. 修改导入的插件加上emit事件。如下:
    2.1 复制node_modules下的vColorPicker插件,拷贝出来到自定义组件中。
    2.2 修改对应文件,下图中lib文件夹下第一个为未压缩的,第二个为压缩的。默认使用的是压缩文件。因此需要修改压缩文件。全局找到 closePanel 方法,添加如下代码 this. e m i t ( ′ h i d e ′ ) ; 上 一 行 可 加 上 t h i s . emit('hide'); 上一行可加上this. emit(hide);this.emit(‘show’); 作为传参出来。
    在这里插入图片描述

2.3 最终子组件需要为如下, 父组件调用不做修改

<template>
<div
style="height:38px;"
@click="openColor"
>

<slot
name="inset"
:row="nowColor"
>
</slot>
<colorPicker
style="marginLeft:10px;marginTop:-20px"
ref="colorPicker"
v-model="nowColor"
@hide="close"
:defaultColor="nowColor"
@change="headleChangeColor"
>
</colorPicker>
</div>
</template>

<script>
export default {
data () {
return {
nowColor: ""
}
},
created () {
this._initData()
},
watch: {
color: '_initData'
},

props: {
color: {
type: String,
default: "#7993ae"
}
},
methods: {
_initData () {
this.nowColor = this.$props.color
},
headleChangeColor (item) {
this.$emit('change', item)
},
openColor () {
this.$refs.colorPicker.openPanel()
this.$emit('open')
},
close () {
this.$emit('hide');
}
},
}
</script>

<style scoped lang="less">
/deep/ .m-colorPicker .colorBtn {
width: 0;
height: 0;
}
</style>

举报

相关推荐

0 条评论