Files
laws-sinotruk-mobile/src/components/TreeSelectMultiple.vue
T

190 lines
4.1 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!--树形结构的多选组件value-所选树形结构体的id的集合 text所选树形结构名字-->
<template>
<div>
<van-field
v-bind="$attrs"
readonly
clearable
@click="showPopup"
v-model="showValue"
rows="1"
autosize
type="textarea"
/>
<van-popup
v-model="show"
style="height: 60vh"
position="bottom"
safe-area-inset-bottom
:close-on-click-overlay="false"
:close-on-popstate="true"
>
<div class="popup-box">
<div class="operate">
<span @click="cancel">取消</span>
<span @click="handleOk">确认</span>
</div>
<link-menu
:data="list"
value-key="key"
label-key="title"
:value="selectedDepartTemp"
@input="selected"
:multiple="multiple"
></link-menu>
</div>
</van-popup>
</div>
</template>
<script>
import LinkMenu from './LinkMenu'
export default {
name: 'TreeSelectMultiple',
components: {
LinkMenu
},
props: {
value: {
type: [Object, Array, String],
required: true,
default: () => []
},
list: {
type: Array,
default: () => []
},
readonly: {
type: Boolean,
required: false,
default: false
},
// 是否多选 默认是true
multiple: {
type: Boolean,
required: false,
default: true
}
},
watch: {
value: {
immediate: true,
deep: true,
handler () {
this.handleInitData()
}
},
list: {
immediate: true,
deep: true,
handler () {
this.handleInitData()
}
}
},
computed: {
// 当前显示的部门名称的字符串
showValue () {
if (this.multiple) {
return this.selectedDepart.map(tt => tt.title).join('')
} else {
return this.selectedDepart.title
}
}
},
data () {
return {
show: false, // 控制popup的显示隐藏
selectedDepart: [], // 选中的部门
selectedDepartTemp: [], // 选中的部门暂存 多选的时候是数组,单选的时候是对象
confirm: false // 是否点击了确认
}
},
methods: {
cancel () {
this.show = false
},
handleOk () {
if (this.multiple) {
this.$emit('input', this.selectedDepartTemp.map(tt => tt.key))
} else {
this.$emit('input', [this.selectedDepartTemp.key])
}
this.show = false
},
// 弹出层显示
showPopup () {
if (this.readonly) return
this.selectedDepartTemp = JSON.parse(JSON.stringify(this.selectedDepart))
this.show = true
},
selected (val) {
// 先临时转换
this.selectedDepartTemp = JSON.parse(JSON.stringify(val))
},
// 初始化数据,将id的形式转成所有对象的形式
handleInitData () {
const selectedDepart = []
this.findSelectedItemByKey(this.list, selectedDepart)
if (this.multiple) {
this.selectedDepart = [...selectedDepart]
} else {
this.selectedDepart = selectedDepart.length > 0 ? selectedDepart[0] : {}
}
},
// 循环遍历数据进行 选中的判断
findSelectedItemByKey (arr, result) {
arr.forEach(item => {
if (this.value.includes(item.key)) {
result.push(item)
}
if (item.children && item.children.length > 0) {
this.findSelectedItemByKey(item.children, result)
}
})
}
}
}
</script>
<style scoped lang="less">
@import '~@assets/less/common.less';
.wrap {
display: flex;
flex-direction: column;
padding: 0 @pad-base;
box-sizing: border-box;
height: 100%;
}
// 解决线上滚动条不灵敏的bug
.popup-box{
height: 100%;
position: relative;
/deep/& > .list-menu {
height: calc(100% - 0.8rem);
overflow: auto;
}
}
.operate {
padding: 0 @pad-base;
box-sizing: border-box;
font-size: 0.3rem;
font-weight: 600;
height: 0.8rem;
display: flex;
justify-content: space-between;
align-items: center;
}
.content {
width: 100%;
flex: 1;
}
</style>