|
@@ -1,31 +1,65 @@
|
|
<template>
|
|
<template>
|
|
- <div>
|
|
|
|
- <div :class="{'embedded': outweigh}">
|
|
|
|
- <template v-if="outweigh">
|
|
|
|
- <span :class="{'act': actIndex === -1}">不限</span>
|
|
|
|
- <!-- <span class="text666 mr-2"></span> -->
|
|
|
|
- </template>
|
|
|
|
|
|
+ <div v-for="(list, levelIndex) in treeList" :key="`select${levelIndex}`">
|
|
|
|
+ <div v-if="levelIndex < props.defaultOpen">
|
|
|
|
+ <span v-for="(item, itemIndex) in list" :key="item.id">
|
|
|
|
+ <span
|
|
|
|
+ v-if="itemIndex + 1 <= num"
|
|
|
|
+ class="mx-3"
|
|
|
|
+ :class="{'act': calcAct(item.id, levelIndex)}"
|
|
|
|
+ style="line-height: 32px;"
|
|
|
|
+ @click="handleNext(item, levelIndex)"
|
|
|
|
+ >{{ item.name }}</span>
|
|
|
|
+ </span>
|
|
|
|
+ <!-- 其他 -->
|
|
|
|
+ <span v-if="list?.length > num" class="mx-3" style="line-height: 32px;">其他</span>
|
|
|
|
+ </div>
|
|
|
|
+ <div v-else class="embedded">
|
|
|
|
+ <span
|
|
|
|
+ v-for="item in list" :key="item.id"
|
|
|
|
+ class="mx-3"
|
|
|
|
+ :class="{'act': calcAct(item.id, levelIndex)}"
|
|
|
|
+ style="line-height: 32px;"
|
|
|
|
+ @click="handleNext(item, levelIndex)"
|
|
|
|
+ >{{ item.name }}</span>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ <!-- <div>
|
|
|
|
+ <div v-for="(item, index) in treeList" :key="`select${index}`">
|
|
|
|
+ <div :class="{'embedded': index + 1 > props.defaultOpen }">
|
|
|
|
+ <template v-for="(val, listIndex) in item" :key="`val${listIndex}`">
|
|
|
|
+ <span v-if="listIndex < num" class="mx-3" style="line-height: 32px;" @click="handleNext(val, index)">{{ val.name }}</span>
|
|
|
|
+ </template>
|
|
|
|
+ </div>
|
|
<span v-for="(item, index) in props.items" :key="item.id">
|
|
<span v-for="(item, index) in props.items" :key="item.id">
|
|
- <span v-if="index < num" class="mx-3" :class="{'act': actIndex === index}" style="line-height: 32px;" @click="handleClick(item, index)">{{ item.name }}</span>
|
|
|
|
|
|
+ <span v-if="index < num" class="mx-3" :class="{'act': calcAct(item)}" style="line-height: 32px;" @click="handleClick(item, index)">{{ item.name }}</span>
|
|
</span>
|
|
</span>
|
|
<template v-if="underAndEqual">
|
|
<template v-if="underAndEqual">
|
|
- <!-- <span class="text666 mr-2"></span> -->
|
|
|
|
<span v-if="props.items?.length >= num" @click="handleClick(props.items, 'other')">其他</span>
|
|
<span v-if="props.items?.length >= num" @click="handleClick(props.items, 'other')">其他</span>
|
|
</template>
|
|
</template>
|
|
</div>
|
|
</div>
|
|
<template v-if="children?.length">
|
|
<template v-if="children?.length">
|
|
<v-divider v-if="outweigh" class="mx-2"></v-divider>
|
|
<v-divider v-if="outweigh" class="mx-2"></v-divider>
|
|
- <recursive ref="childRef" :defaultOpen="props.defaultOpen" :items="children" :parentId="itemId"></recursive>
|
|
|
|
|
|
+ <recursive ref="childRef" :defaultOpen="props.defaultOpen" :items="children" :parentId="itemId" v-model="modelValueDeep"></recursive>
|
|
</template>
|
|
</template>
|
|
- </div>
|
|
|
|
|
|
+ </div> -->
|
|
</template>
|
|
</template>
|
|
<script setup>
|
|
<script setup>
|
|
-import { computed, reactive, ref, watch } from 'vue'
|
|
|
|
-import recursive from './recursive'
|
|
|
|
|
|
+import { reactive, ref } from 'vue'
|
|
|
|
+// import recursive from './recursive'
|
|
|
|
+// import { useRoute, useRouter } from 'vue-router'
|
|
defineOptions({ name:'common-components-areaTree-recursive'})
|
|
defineOptions({ name:'common-components-areaTree-recursive'})
|
|
|
|
+const emits = defineEmits('input')
|
|
|
|
+// const route = useRoute(); const router = useRouter()
|
|
|
|
+// const checked = reactive({})
|
|
|
|
+// console.log('to:/recruit/position-> query', route.query)
|
|
|
|
+// if (Object.keys(route.query).length) {
|
|
|
|
+// Object.keys(route.query).forEach(_e => {
|
|
|
|
+// checked[_e]
|
|
|
|
+// })
|
|
|
|
+// }
|
|
|
|
|
|
-const num = 14
|
|
|
|
-const childRef = ref(null)
|
|
|
|
|
|
+const num = 10
|
|
|
|
+// const childRef = ref(null)
|
|
const props = defineProps({
|
|
const props = defineProps({
|
|
items: Object,
|
|
items: Object,
|
|
defaultOpen: {
|
|
defaultOpen: {
|
|
@@ -37,68 +71,207 @@ const props = defineProps({
|
|
default: -1
|
|
default: -1
|
|
}
|
|
}
|
|
})
|
|
})
|
|
-// const currentRowType = computed(() => {
|
|
|
|
-// if (props.items?.length) return props.items[0].type - 0
|
|
|
|
-// else return 0
|
|
|
|
-// })
|
|
|
|
-let itemId = ref(0)
|
|
|
|
-let currentRowType = ref(0)
|
|
|
|
-let actIndex = ref(0)
|
|
|
|
-let currentRow = reactive({ id: -1})
|
|
|
|
-let children = ref([])
|
|
|
|
-const setRow = (item) => {
|
|
|
|
- if (item) {
|
|
|
|
- console.log('currentRow1', { ...item, children: null})
|
|
|
|
- currentRow = item
|
|
|
|
- children.value = currentRow.children
|
|
|
|
- itemId.value = currentRow.id || 0
|
|
|
|
- currentRowType.value = currentRow.type || 0
|
|
|
|
|
|
+
|
|
|
|
+const idChecked = reactive([])
|
|
|
|
+const getIdChecked = (item, levelIndex) => {
|
|
|
|
+ if (!idChecked[levelIndex]) idChecked[levelIndex] = [] // 不存在初始化为空
|
|
|
|
+ if (levelIndex < props.defaultOpen) {
|
|
|
|
+ idChecked[levelIndex] = [ item.id ]
|
|
} else {
|
|
} else {
|
|
- currentRow = { id: -1 }
|
|
|
|
- itemId.value = -1
|
|
|
|
- currentRowType.value = 0
|
|
|
|
|
|
+ const findIndex = idChecked[levelIndex]?.length ? idChecked[levelIndex].findIndex(j => j === item.id) : -1
|
|
|
|
+ if (findIndex !== -1) {
|
|
|
|
+ idChecked[levelIndex].splice(findIndex, 1) // 删除
|
|
|
|
+ } else {
|
|
|
|
+ idChecked[levelIndex].push(item.id) // 添加
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
+ // console.log('idChecked', idChecked)
|
|
}
|
|
}
|
|
|
|
|
|
-const init = () => {
|
|
|
|
- itemId.value = -1
|
|
|
|
- if (currentRowType.value < props.defaultOpen && props.items?.length) {
|
|
|
|
- setRow(props.items[0])
|
|
|
|
- actIndex.value = 0
|
|
|
|
|
|
+const treeList = ref([
|
|
|
|
+ [...props.items]
|
|
|
|
+])
|
|
|
|
+const handleNext = (item, index, stopExpand) => { // stopExpand:不展开下级
|
|
|
|
+ getIdChecked(item, index)
|
|
|
|
+ if (!stopExpand &&item.children && item.children.length) {
|
|
|
|
+ treeList.value[index + 1] = item.children
|
|
|
|
+ treeList.value.splice(index + 2, treeList.value.length)
|
|
} else {
|
|
} else {
|
|
- setRow(null)
|
|
|
|
|
|
+ treeList.value.splice(index + 1, treeList.value.length)
|
|
}
|
|
}
|
|
- if (currentRowType.value > props.defaultOpen) {
|
|
|
|
- actIndex.value = -1
|
|
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+if (props.defaultOpen > 0) {
|
|
|
|
+ for (let index = 0; index < props.defaultOpen; index++) {
|
|
|
|
+ if (treeList.value?.length && treeList.value[index]?.length && treeList.value[index][0]) {
|
|
|
|
+ const stopExpand = (index + 1) === props.defaultOpen
|
|
|
|
+ handleNext(treeList.value[index][0], index, stopExpand)
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
+ emits('input', idChecked)
|
|
}
|
|
}
|
|
|
|
|
|
-// 监听
|
|
|
|
-watch(
|
|
|
|
- () => props.parentId,
|
|
|
|
- () => {
|
|
|
|
- // 函数
|
|
|
|
- init()
|
|
|
|
- },
|
|
|
|
- { immediate: true },
|
|
|
|
- { deep: true }
|
|
|
|
-)
|
|
|
|
-
|
|
|
|
-const handleClick = (item, index) => {
|
|
|
|
- console.log('init', item.name)
|
|
|
|
- if (index === 'other') return
|
|
|
|
- else {
|
|
|
|
- actIndex.value = index
|
|
|
|
- currentRow.value = item
|
|
|
|
- children.value = item.children
|
|
|
|
- children.value = item.children
|
|
|
|
- itemId.value = item.id || 0
|
|
|
|
|
|
+const calcAct = (id, levelIndex) => {
|
|
|
|
+ if (!id) return false
|
|
|
|
+ if (Array.isArray(idChecked) && Array.isArray(idChecked[levelIndex])) {
|
|
|
|
+ const index = idChecked[levelIndex].findIndex(itemToCheck => itemToCheck=== id)
|
|
|
|
+ return index !== -1 ? true : false; // 如果找到返回索引,否则返回 false
|
|
}
|
|
}
|
|
|
|
+ else return false
|
|
}
|
|
}
|
|
|
|
|
|
-console.log('currentRowType', currentRowType)
|
|
|
|
-const outweigh = computed(() => (currentRowType.value > props.defaultOpen))
|
|
|
|
-const underAndEqual = computed(() => (currentRowType.value <= props.defaultOpen))
|
|
|
|
|
|
+
|
|
|
|
+// const modelValueDeep = ref([])
|
|
|
|
+// let itemId = ref(0)
|
|
|
|
+// let currentRowType = ref(0)
|
|
|
|
+// let actIndex = ref(0)
|
|
|
|
+// let currentRow = reactive({ id: -1})
|
|
|
|
+// let children = ref([])
|
|
|
|
+// const rowExtend = (item) => {
|
|
|
|
+// if (item) {
|
|
|
|
+// currentRow = item
|
|
|
|
+// itemId.value = currentRow.id || 0
|
|
|
|
+// currentRowType.value = currentRow.type || 0
|
|
|
|
+// } else {
|
|
|
|
+// currentRow = { id: -1 }
|
|
|
|
+// itemId.value = -1
|
|
|
|
+// currentRowType.value = 0
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+// // 选中回显
|
|
|
|
+// const checkedFun = (item) => {
|
|
|
|
+// const key = 'type' + item.type
|
|
|
|
+// let typeChecked = checked[key] || (checked[key] = []) // 不存在初始化为空
|
|
|
|
+// if (item.type <= props.defaultOpen) {
|
|
|
|
+// typeChecked.length = 0 // 清空数组
|
|
|
|
+// typeChecked.push({ id: item.id, name: item.name })
|
|
|
|
+// } else {
|
|
|
|
+// // 多选
|
|
|
|
+// const index = typeChecked.findIndex(itemToCheck => itemToCheck.id === item.id)
|
|
|
|
+// if (index !== -1) {
|
|
|
|
+// typeChecked.splice(index, 1) // 删除
|
|
|
|
+// } else {
|
|
|
|
+// typeChecked.push({ id: item.id, name: item.name }) // 添加
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+
|
|
|
|
+// const idChecked = ref([])
|
|
|
|
+// const getIdChecked = (item) => {
|
|
|
|
+// const { name, id } = item
|
|
|
|
+// // if (item.type <= props.defaultOpen) {
|
|
|
|
+// // idChecked.value = [{ name, id }]
|
|
|
|
+// // } else {
|
|
|
|
+// // const index = idChecked.value.findIndex(j => j.id === item.id)
|
|
|
|
+// // if (index !== -1) {
|
|
|
|
+// // idChecked.value.splice(index, 1) // 删除
|
|
|
|
+// // } else {
|
|
|
|
+// // idChecked.value.push({ name, id }) // 添加
|
|
|
|
+// // }
|
|
|
|
+// // }
|
|
|
|
+// // 提交已选中的给areaCascader-index组件
|
|
|
|
+// // const params = { [`type${item.type}`]: idChecked.value }
|
|
|
|
+
|
|
|
|
+// emits('update:modelValue', [...props.modelValue, {name, id}])
|
|
|
|
+// // console.log('params', props.value)
|
|
|
|
+// }
|
|
|
|
+
|
|
|
|
+// const init = () => {
|
|
|
|
+// if (props.items?.length) {
|
|
|
|
+// const item = props.items[0]
|
|
|
|
+// // 设置激活样式
|
|
|
|
+// actIndex.value = 0
|
|
|
|
+// if (item.type - 0 <= props.defaultOpen) getIdChecked(item)
|
|
|
|
+// // 显示子级数据
|
|
|
|
+// if (item.type - 0 < props.defaultOpen) {
|
|
|
|
+// children.value = item.children
|
|
|
|
+// } else {
|
|
|
|
+// children.value = []
|
|
|
|
+// }
|
|
|
|
+// rowExtend(item)
|
|
|
|
+// } else {
|
|
|
|
+// rowExtend(null)
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+
|
|
|
|
+// 监听
|
|
|
|
+// watch(
|
|
|
|
+// () => props.parentId,
|
|
|
|
+// () => {
|
|
|
|
+// // 函数
|
|
|
|
+// init()
|
|
|
|
+// },
|
|
|
|
+// { immediate: true },
|
|
|
|
+// { deep: true }
|
|
|
|
+// )
|
|
|
|
+// watch(
|
|
|
|
+// () => props.modelValue,
|
|
|
|
+// (val) => {
|
|
|
|
+// console.log('val', val)
|
|
|
|
+// },
|
|
|
|
+// { immediate: true },
|
|
|
|
+// { deep: true }
|
|
|
|
+// )
|
|
|
|
+// 点击事件
|
|
|
|
+// const handleClick = (item) => {
|
|
|
|
+// // console.log(item, index)
|
|
|
|
+// const { name, id } = item
|
|
|
|
+// emits('update:modelValue', [...props.modelValue, { name, id }])
|
|
|
|
+// // if (index === 'other') return
|
|
|
|
+// // else {
|
|
|
|
+// // actIndex.value = index
|
|
|
|
+// // if (item.children?.length) {
|
|
|
|
+// // if (item.type - 0 > props.defaultOpen - 1) { // 下一级是多选的情况下(props.defaultOpen的上一级)
|
|
|
|
+// // const i = { id: 0, name: '不限', type: currentRowType.value + 1, parentId: item.parentId, children: [] }
|
|
|
|
+// // children.value = [i, ...item.children]
|
|
|
|
+// // }
|
|
|
|
+// // else children.value = item.children
|
|
|
|
+// // } else children.value = []
|
|
|
|
+// // rowExtend(item) // 相关属性
|
|
|
|
+// // getIdChecked(item) // 加入checked
|
|
|
|
+
|
|
|
|
+// // // const key = `type${currentRowType.value}`
|
|
|
|
+// // // const query = { [`type${currentRowType.value}`]: idChecked.value.join('_') }
|
|
|
|
+// // // router.push({ path: route.path, query })
|
|
|
|
+// // }
|
|
|
|
+// }
|
|
|
|
+
|
|
|
|
+// // 设置激活样式
|
|
|
|
+// const calcActFun = (item) => {
|
|
|
|
+// // 首先确保 item 有 id 属性
|
|
|
|
+// if (!item?.id) {
|
|
|
|
+// return false
|
|
|
|
+// }
|
|
|
|
+// // 计算 key
|
|
|
|
+// const key = 'type' + item.type
|
|
|
|
+
|
|
|
|
+// // 尝试从 checked 对象中获取对应的数组
|
|
|
|
+// const typeChecked = checked[key]
|
|
|
|
+
|
|
|
|
+// // 如果 typeChecked 存在并且是一个数组,则查找索引
|
|
|
|
+// if (Array.isArray(typeChecked)) {
|
|
|
|
+// const index = typeChecked.findIndex(itemToCheck => itemToCheck.id === item.id)
|
|
|
|
+// return index !== -1 ? true : false; // 如果找到返回索引,否则返回 false
|
|
|
|
+// }
|
|
|
|
+
|
|
|
|
+// // 如果 typeChecked 不存在或不是一个数组,返回 false
|
|
|
|
+// return false
|
|
|
|
+// }
|
|
|
|
+
|
|
|
|
+// 设置激活样式
|
|
|
|
+// const calcAct = (item) => {
|
|
|
|
+// // 首先确保 item 有 id 属性
|
|
|
|
+// if (!item?.id) {
|
|
|
|
+// return false
|
|
|
|
+// }
|
|
|
|
+// if (Array.isArray(idChecked.value)) {
|
|
|
|
+// const index = idChecked.value.findIndex(itemToCheck => itemToCheck.id=== item.id)
|
|
|
|
+// return index !== -1 ? true : false; // 如果找到返回索引,否则返回 false
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+
|
|
|
|
+// const outweigh = computed(() => (currentRowType.value > props.defaultOpen))
|
|
|
|
+// const underAndEqual = computed(() => (currentRowType.value <= props.defaultOpen))
|
|
|
|
|
|
</script>
|
|
</script>
|
|
<style lang="scss" scoped>
|
|
<style lang="scss" scoped>
|
|
@@ -113,13 +286,15 @@ const underAndEqual = computed(() => (currentRowType.value <= props.defaultOpen)
|
|
color: var(--v-primary-base);
|
|
color: var(--v-primary-base);
|
|
}
|
|
}
|
|
span {
|
|
span {
|
|
|
|
+ span { cursor: pointer; }
|
|
cursor: pointer;
|
|
cursor: pointer;
|
|
&:hover {
|
|
&:hover {
|
|
- color: var(--v-primary-lighten1);
|
|
|
|
|
|
+ color: var(--v-primary-lighten2);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.embedded {
|
|
.embedded {
|
|
- padding: 4px 12px;
|
|
|
|
|
|
+ padding: 4px;
|
|
background-color: #f8f8f8;
|
|
background-color: #f8f8f8;
|
|
|
|
+ border-radius: 5px;
|
|
}
|
|
}
|
|
</style>
|
|
</style>
|