253 lines
6.0 KiB
Vue
253 lines
6.0 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 v-if="kind=='duo'" style="max-height: 264px; overflow-y: auto">
|
|
<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>
|
|
<!-- dan -->
|
|
<div v-if="kind=='dan'" style="max-height: 264px; overflow-y: auto">
|
|
<van-radio-group v-model="radio">
|
|
<van-cell-group>
|
|
<van-cell v-for="(item, index) in columnsData" :key="index" :title="item.name" clickable
|
|
@click="choseradio(index)">
|
|
<template #right-icon>
|
|
<van-radio :name="item.id" />
|
|
</template>
|
|
</van-cell>
|
|
</van-cell-group>
|
|
</van-radio-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 [];
|
|
},
|
|
},
|
|
kind: {
|
|
type: String,
|
|
default: 'duo'
|
|
},
|
|
selectradio: {
|
|
type: String,
|
|
default: 'duo'
|
|
},
|
|
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)),
|
|
// dan
|
|
radio: this.selectradio
|
|
};
|
|
},
|
|
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() {
|
|
if (this.kind == 'duo') {
|
|
let infos = {
|
|
arr: this.checkboxValue,
|
|
types: this.types
|
|
}
|
|
this.resultValue = this.checkboxValue;
|
|
this.show = !this.show;
|
|
this.$emit("confirm", infos, this.getData(this.resultValue));
|
|
} else {
|
|
this.show = !this.show;
|
|
this.resultValue = []
|
|
this.resultValue.push(this.radio)
|
|
this.$emit('confirm2', this.radio)
|
|
}
|
|
|
|
},
|
|
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) {
|
|
this.columnsData = JSON.parse(JSON.stringify(this.columns));
|
|
this.checkboxValue = JSON.parse(JSON.stringify(this.selectValue));
|
|
if (this.kind == 'duo') {
|
|
this.resultValue = JSON.parse(JSON.stringify(this.selectValue));
|
|
}
|
|
if (disabled !== undefined && disabled !== false) {
|
|
return false;
|
|
} else {
|
|
this.show = !this.show;
|
|
}
|
|
},
|
|
choseradio(index) {
|
|
this.radio = this.columnsData[index].id
|
|
},
|
|
},
|
|
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> |