<template>
<div class="eo-cascader-panel" :style="[panelStyle()]">
<view
v-if="multiple && incrementCount > 1"
class="flex-row row-column-center row-between"
:style="[selectBtnStyle(), { height: '80rpx' }]"
@click.stop="selectAll"
>
<text class="option ellipsis_one" style="padding:0;">全选</text>
<view v-if="multiple" class="checkbox" :style="{ backgroundColor: checkedAll ? '#0092ff' : 'transparent' }">
<view class="gou"></view>
</view>
</view>
<scroll-view scroll-y class="eo-cascader-menu" :style="[menuStyle()]">
<li class="has-child" v-for="(item, index) in list" :key="index">
<view
class="option flex-row row-column-center row-between"
:style="{ backgroundColor: item.childVisible ? '#ffffff' : '' }"
@click="changeList(item, index)"
>
<view v-if="item.childVisible && incrementCount === 1 && line" class="vertical-line"></view>
<text :style="[optionStyle(item)]" class="list-name ellipsis_one">{{ item.name }}</text>
<image
v-if="incrementCount === deep && item.childVisible && !multiple && selectBtnVisible"
src="@/static/icon/check.png"
class="radio-img"
></image>
<view
v-if="incrementCount === deep && multiple && selectBtnVisible"
class="checkbox"
@click.stop="multipleSelect(item, index)"
:style="{ backgroundColor: item.selected ? '#0092ff' : 'transparent' }"
>
<view class="gou"></view>
</view>
</view>
</li>
</scroll-view>
<cascade-option
ref="CascadeOption"
v-if="currentOption.childVisible && currentOption.children"
:options="currentOption.children"
:cascadeWidth="cascadeWidth"
:treeWidth="treeWidth"
:selectBtnWidth="cascadeWidth - firstUlWidth"
:incrementCount="count"
:deep="deep"
></cascade-option>
</div>
</template>
<script>
import CascadeOption from "@/pages/templates/CascadeSelection/CascadeOptions.vue";
import Bus from "./bus";
export default {
name: "CascadeOption",
components: {
CascadeOption
},
props: {
options: {
type: Array,
default: []
},
firstUlWidth: {
type: Number,
default: 100
},
firstUlBackgroundColor: {
type: String,
default: "#fff"
},
treeWidth: {
type: Number,
default: 142
},
cascadeWidth: {
type: Number,
default: 0
},
multiple: {
type: Boolean,
default: false
},
selectBtnWidth: {
type: Number,
default: 0
},
incrementCount: {
type: Number,
default: 1
},
deep: {
type: Number,
default: 1
},
line: {
type: Boolean,
default: true
}
},
data() {
return {
list: [],
currentOption: null,
selectBtnVisible: true,
checkedAll: false,
multipleOperate: true
};
},
computed: {
count() {
let c = this.incrementCount;
return ++c;
}
},
created() {
this.init(this.options);
},
methods: {
update(props) {
this.init(props);
},
init(options) {
this.list = options;
this.selectBtnVisible = true;
this.$parent.selectBtnVisible = false;
this.$parent.checkedAll = false;
if (this.$parent.list) {
this.$parent.list.forEach(item => {
item.selected = false;
});
}
for (let i = 0; i < this.list.length; i++) {
if (this.list[i].childVisible) {
this.currentOption = this.list[i];
}
}
this.$nextTick(() => {
if (Object.keys(this.$refs).length) {
this.$refs.CascadeOption.update(this.currentOption.children);
}
});
},
changeList(item, index) {
this.multipleOperate = false;
if (!item.childVisible) {
for (let i = 0; i < this.list.length; i++) {
this.list[i].childVisible = false;
this.changeChildVisible(this.list, false);
}
item.childVisible = true;
this.selectBtnVisible = true;
}
this.currentOption = item;
this.$nextTick(() => {
if (Object.keys(this.$refs).length) {
this.$refs.CascadeOption.update(this.currentOption.children);
}
});
Bus.$emit("getValue", item, this.incrementCount);
},
selectAll() {
this.checkedAll = !this.checkedAll;
if (this.checkedAll) {
this.changeTree(this.list, true);
} else {
this.changeTree(this.list, false);
}
},
changeChildVisible(data, visible) {
if (data) {
data.forEach(item => {
item.childVisible = visible;
if (item.children) {
this.changeChildVisible(item.children, visible);
}
});
}
},
changeTree(data, selected) {
if (data) {
data.forEach(item => {
item.selected = selected;
});
}
},
multipleSelect(item, index) {
this.multipleOperate = true;
this.currentOption = item;
item.selected = !item.selected;
if (this.judgeSelectedAll()) {
this.checkedAll = true;
} else {
this.checkedAll = false;
}
Bus.$emit("getValue", item);
},
judgeSelectedAll() {
let flag = false;
this.list.forEach(item => {
if (!item.selected) flag = false;
if (item.selected) flag = true;
});
return flag;
},
panelStyle() {
let style = {};
if (this.incrementCount === 1) {
style.width = `${this.firstUlWidth}px`;
style.backgroundColor = `${this.firstUlBackgroundColor} !important`;
} else {
style.width = `${this.treeWidth}px`;
}
if (this.incrementCount <= 2) {
style.left = `${this.firstUlWidth * (this.incrementCount - 1)}px`;
} else {
style.left = `${this.treeWidth}px`;
}
return style;
},
optionStyle(item) {
let style = {};
if (item.childVisible) {
style.color = "rgba(0, 146, 255, 1)";
style.fontWeight = "bold";
}
return style;
},
selectBtnStyle() {
let style = {
position: "relative",
boxSizing: "border-box",
padding: "0 28rpx"
};
style.width = `${this.selectBtnWidth}px`;
if (!this.selectBtnVisible) {
style.visibility = "hidden";
}
if (this.incrementCount > 1) {
style.top = "0";
style.left = `-${this.treeWidth * (this.incrementCount - 2)}px`;
}
return style;
},
menuStyle() {
let style = {};
if (this.multiple && this.incrementCount > 1) {
style.height = "calc(100% - 44px)";
}
if (this.incrementCount === 1) {
style.border = "none";
}
return style;
}
}
};
</script>
<style lang="scss" scoped>
.eo-cascader-panel {
height: 100%;
position: absolute;
background: #fff;
top: 0;
left: 0;
}
.eo-cascader-menu {
width: 100%;
height: 100%;
box-sizing: border-box;
color: #606266;
border-right: 2rpx solid rgba(240, 240, 240, 1);
-webkit-overflow-scrolling: auto !important;
}
.eo-cascader-menu li {
width: 100%;
height: 30px;
line-height: 30px;
box-sizing: border-box;
}
.option {
position: relative;
box-sizing: border-box;
padding: 0 14px;
}
.vertical-line {
width: 8rpx;
height: 38rpx;
background: #0092ff;
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
}
.eo-cascader-menu li.has-child:after {
content: "";
position: absolute;
right: 10px;
top: -2px;
transform: scaleY(1.8);
font-size: 12px;
color: #606266;
}
.radio-img {
width: 42rpx;
height: 42rpx;
position: absolute;
right: 28rpx;
}
.list-name {
max-width: 280rpx;
font-size: 28rpx;
font-weight: 400;
font-family: PingFangSC-Medium, PingFang SC;
color: rgba(89, 89, 89, 1);
}
.checkbox {
width: 28rpx;
height: 28rpx;
border: 2rpx solid #bfbfbf;
border-radius: 4rpx;
position: relative;
}
.gou {
width: 9rpx;
height: 18rpx;
border-right: 2rpx solid #fff;
border-bottom: 2rpx solid #fff;
position: absolute;
top: 50%;
left: 50%;
transform: rotate(40deg) translate(-120%, -38%);
}
</style>
请移步uni-app官方社区
请移步uni-app官方社区
请移步uni-app官方社区