234 lines
5.6 KiB
Vue
234 lines
5.6 KiB
Vue
|
<template>
|
||
|
<div class="dh-field">
|
||
|
<div class="van-hairline--bottom">
|
||
|
<van-field v-model="resultLabel" v-bind="$attrs" readonly :label="label"
|
||
|
:is-link="$attrs.disabled === undefined" error-message-align="right" input-align="right" class="dh-cell"
|
||
|
@click="showPopu($attrs.disabled)" :rules="[{ required: require, message: requireMessage }]" />
|
||
|
<van-popup v-model:show="show" position="bottom" class="" :style="{ height: '30%' }">
|
||
|
<div class="van-picker__toolbar flex_around flex_items mt30 plr50">
|
||
|
<view class="van-picker__cancel" @click="cancel">
|
||
|
取消
|
||
|
</view>
|
||
|
<div class="van-ellipsis van-picker__title">{{ $attrs.label }}</div>
|
||
|
<view style="color: #409EFF;" class="van-picker__confirm" @click="onConfirm">
|
||
|
确认
|
||
|
</view>
|
||
|
</div>
|
||
|
<div style="max-height: 264px; overflow-y: auto">
|
||
|
<!-- <van-field
|
||
|
v-if="isSearch"
|
||
|
v-model="searchVal"
|
||
|
input-align="left"
|
||
|
placeholder="搜索"
|
||
|
@input="search"
|
||
|
@click="toggleAll"
|
||
|
/> -->
|
||
|
<!-- <van-cell ref="checkAll" title="全选" clickable @click="toggleAll">
|
||
|
<template #right-icon>
|
||
|
<div>
|
||
|
<van-checkbox v-model="checkedAll" name="all" />
|
||
|
</div>
|
||
|
</template>
|
||
|
</van-cell> -->
|
||
|
<van-checkbox-group ref="checkboxGroup" v-model="checkboxValue" @change="change">
|
||
|
<van-cell-group>
|
||
|
<van-cell v-for="(item, index) in columnsData" :key="item[option.value]"
|
||
|
:title="item[option.label]" clickable @click="toggle(index)">
|
||
|
<!-- @click="toggle(index)" -->
|
||
|
<template #right-icon>
|
||
|
<div @click="toggle(index)">
|
||
|
<van-checkbox ref="checkboxes" :name="item[option.value]" />
|
||
|
</div>
|
||
|
</template>
|
||
|
</van-cell>
|
||
|
</van-cell-group>
|
||
|
</van-checkbox-group>
|
||
|
</div>
|
||
|
</van-popup>
|
||
|
</div>
|
||
|
</div>
|
||
|
</template>
|
||
|
|
||
|
<script>
|
||
|
export default {
|
||
|
name: "VanFieldCheckbox",
|
||
|
model: {
|
||
|
prop: "selectValue",
|
||
|
},
|
||
|
props: {
|
||
|
require: {
|
||
|
type: Boolean,
|
||
|
default: true,
|
||
|
},
|
||
|
requireMessage: {
|
||
|
type: String,
|
||
|
default: "",
|
||
|
},
|
||
|
label: {
|
||
|
type: String,
|
||
|
default: "标题",
|
||
|
},
|
||
|
columns: {
|
||
|
type: Array,
|
||
|
default: function() {
|
||
|
return [];
|
||
|
},
|
||
|
},
|
||
|
selectValue: {
|
||
|
type: Array,
|
||
|
default: function() {
|
||
|
return [];
|
||
|
},
|
||
|
},
|
||
|
types: {
|
||
|
type: String,
|
||
|
default: "product"
|
||
|
},
|
||
|
option: {
|
||
|
type: Object,
|
||
|
default: function() {
|
||
|
return {
|
||
|
label: "label",
|
||
|
value: "value"
|
||
|
};
|
||
|
},
|
||
|
},
|
||
|
// 是否支持搜索
|
||
|
isSearch: {
|
||
|
type: Boolean,
|
||
|
default: true,
|
||
|
},
|
||
|
},
|
||
|
computed: {
|
||
|
resultLabel: {
|
||
|
get() {
|
||
|
const res = this.columns.filter((item) => {
|
||
|
return this.resultValue.indexOf(item[this.option.value]) > -1;
|
||
|
});
|
||
|
const resLabel = res.map((item) => {
|
||
|
return item[this.option.label];
|
||
|
});
|
||
|
return resLabel.join(",");
|
||
|
},
|
||
|
set() {},
|
||
|
},
|
||
|
},
|
||
|
data() {
|
||
|
return {
|
||
|
show: false,
|
||
|
searchVal: "",
|
||
|
columnsData: JSON.parse(JSON.stringify(this.columns)),
|
||
|
checkboxValue: JSON.parse(JSON.stringify(this.selectValue)),
|
||
|
checkedAll: false,
|
||
|
resultValue: JSON.parse(JSON.stringify(this.selectValue)),
|
||
|
};
|
||
|
},
|
||
|
methods: {
|
||
|
// 搜索
|
||
|
search(val) {
|
||
|
if (val) {
|
||
|
this.columnsData = this.columnsData.filter((item) => {
|
||
|
return item[this.option.label].indexOf(val) > -1;
|
||
|
});
|
||
|
} else {
|
||
|
this.columnsData = JSON.parse(JSON.stringify(this.columns));
|
||
|
}
|
||
|
},
|
||
|
getData(val) {
|
||
|
const res = this.columnsData.filter((item) => {
|
||
|
return val.indexOf(item[this.option.value]) > -1;
|
||
|
});
|
||
|
return res;
|
||
|
},
|
||
|
onConfirm() {
|
||
|
let infos = {
|
||
|
arr: this.checkboxValue,
|
||
|
types: this.types
|
||
|
}
|
||
|
this.resultValue = this.checkboxValue;
|
||
|
this.show = !this.show;
|
||
|
this.$emit("confirm", infos, this.getData(this.resultValue));
|
||
|
},
|
||
|
change(val) {
|
||
|
this.$emit("change", val, this.getData(this.resultValue));
|
||
|
},
|
||
|
cancel() {
|
||
|
this.show = !this.show;
|
||
|
this.$emit("cancel", this.resultValue);
|
||
|
},
|
||
|
toggle(index) {
|
||
|
this.$refs.checkboxes[index].toggle();
|
||
|
},
|
||
|
toggleAll(all) {
|
||
|
console.log(all);
|
||
|
// this.checkedAll = !this.checkedAll;
|
||
|
this.$refs.checkboxGroup.toggleAll(this.checkedAll);
|
||
|
},
|
||
|
showPopu(disabled) {
|
||
|
console.log(disabled);
|
||
|
this.columnsData = JSON.parse(JSON.stringify(this.columns));
|
||
|
this.checkboxValue = JSON.parse(JSON.stringify(this.selectValue));
|
||
|
this.resultValue = JSON.parse(JSON.stringify(this.selectValue));
|
||
|
if (disabled !== undefined && disabled !== false) {
|
||
|
return false;
|
||
|
} else {
|
||
|
this.show = !this.show;
|
||
|
}
|
||
|
},
|
||
|
},
|
||
|
watch: {
|
||
|
selectValue: function(newVal) {
|
||
|
this.resultValue = newVal;
|
||
|
},
|
||
|
resultValue(val) {
|
||
|
this.searchVal = "";
|
||
|
this.columnsData = JSON.parse(JSON.stringify(this.columns));
|
||
|
this.$emit("input", val);
|
||
|
},
|
||
|
columnsData: {
|
||
|
handler(val) {
|
||
|
if (val.length && val.length === this.checkboxValue.length) {
|
||
|
this.checkedAll = true;
|
||
|
} else {
|
||
|
this.checkedAll = false;
|
||
|
}
|
||
|
},
|
||
|
immediate: true,
|
||
|
},
|
||
|
checkboxValue: {
|
||
|
handler(val) {
|
||
|
if (val.length && val.length === this.columnsData.length) {
|
||
|
this.checkedAll = true;
|
||
|
} else {
|
||
|
this.checkedAll = false;
|
||
|
}
|
||
|
},
|
||
|
immediate: true,
|
||
|
},
|
||
|
},
|
||
|
};
|
||
|
</script>
|
||
|
|
||
|
<style lang="scss" scoped>
|
||
|
::v-deep .van-cell__title {
|
||
|
padding: 0 0.3rem;
|
||
|
}
|
||
|
|
||
|
.dh-field {
|
||
|
padding: 0;
|
||
|
background: #fff;
|
||
|
|
||
|
.dh-cell.van-cell {
|
||
|
padding: 10px 0;
|
||
|
}
|
||
|
|
||
|
.dh-cell.van-cell--required::before {
|
||
|
left: -8px;
|
||
|
}
|
||
|
|
||
|
.van-popup {
|
||
|
border-radius: 20px 20px 0 0;
|
||
|
}
|
||
|
}
|
||
|
</style>
|