151 lines
4.9 KiB
Vue
151 lines
4.9 KiB
Vue
<template>
|
||
<el-select v-model="form.path" filterable placeholder="'请选择,也可输入搜索'" @input="updatePath">
|
||
<el-option v-if="allSel === true" label="所有分类" value="">
|
||
<el-avatar class="vm f-s-12" shape="square" :size="25"> all </el-avatar>
|
||
<span class="m-l-15">所有分类</span>
|
||
</el-option>
|
||
<el-option v-for="item in categoryListArr" :key="item.id" :label="item.name" :value="item.path">
|
||
<el-avatar v-if="item.photo != ''" class="vm" shape="square" :size="25"
|
||
:src="item.photo[0]">
|
||
</el-avatar>
|
||
<el-avatar v-else :size="25" class="vm" shape="square" icon="iconfont icon-tuxiang"></el-avatar>
|
||
<span v-for="element in item.pathLen" :key="element" class="m-l-30"></span>
|
||
<span v-if="item.isFinal == true" class="m-l-30">└─</span>
|
||
<span v-else class="m-l-30">├─</span>
|
||
<span class="m-l-5">{{ item.name }}</span>
|
||
</el-option>
|
||
<el-option label="未分类" value="none">
|
||
<el-avatar class="vm f-s-12" shape="square" :size="25"> 其 </el-avatar>
|
||
<span class="m-l-15">未分类</span>
|
||
</el-option>
|
||
</el-select>
|
||
</template>
|
||
|
||
<script>
|
||
export default {
|
||
name: 'SelectionPath',
|
||
props: {
|
||
value: String, // 接收父级的值作为 prop
|
||
allSel: { // 是否显示 所有商铺选项
|
||
type: Boolean,
|
||
default: false
|
||
},
|
||
shop_id: String, // 接收父级给的默认 shop_id
|
||
defaultPath: { // 接收父级给的默认path 默认值是空 不传的话则默认是所有分类
|
||
type: String,
|
||
default: ''
|
||
}
|
||
},
|
||
data () {
|
||
return {
|
||
form: {
|
||
path: ''
|
||
}
|
||
}
|
||
},
|
||
computed: {
|
||
// 获取分类列表
|
||
categoryList () {
|
||
return this.$store.state.categoryList
|
||
},
|
||
// 格式化分类列表
|
||
categoryListArr () {
|
||
let formattedList = this.categoryList.filter((item) => item.shop_id === this.shop_id)
|
||
// 找到顶级节点并调用递归函数开始排序
|
||
formattedList = this.findChildren(formattedList, '0')
|
||
// 为每个项目添加pathLen属性 和 isFinal属性
|
||
formattedList.forEach((item, index) => {
|
||
// pathLen属性
|
||
const pathSegments = item.path.split('-')
|
||
item.pathLen = pathSegments.length - 1
|
||
// isFinal属性
|
||
item.isFinal = true
|
||
const pid = item.pid
|
||
for (let i = index + 1; i < formattedList.length; i++) {
|
||
if (pid === formattedList[i].pid) { // 遍历 对比出是否是同类分组的最后一项
|
||
item.isFinal = false
|
||
break
|
||
}
|
||
}
|
||
})
|
||
return formattedList
|
||
}
|
||
},
|
||
watch: {
|
||
categoryList (val) {
|
||
if (this.defaultPath !== '') { // 首先 默认不是所有分类 先归为未分类
|
||
this.form.path = 'none'
|
||
}
|
||
val.forEach(element => { // 再遍历对比 所有分类 看默认分类是否存在 存在则改成对应分类
|
||
if (element.path === this.defaultPath) {
|
||
this.form.path = this.defaultPath
|
||
}
|
||
})
|
||
this.updatePath()
|
||
},
|
||
shop_id () { // 商铺selection改变时 分类selection如果不是"全部分类" 则改成"未分类"
|
||
if (this.defaultPath !== '') {
|
||
this.form.path = this.defaultPath
|
||
}
|
||
this.updatePath()
|
||
},
|
||
defaultPath (val) {
|
||
this.form.path = val
|
||
this.updatePath()
|
||
}
|
||
},
|
||
created () {
|
||
if (this.categoryList.length > 0) {
|
||
if (this.defaultPath !== '') { // 首先 默认不是所有分类 先归为未分类
|
||
this.form.path = 'none'
|
||
}
|
||
this.categoryList.forEach(element => { // 再遍历对比 所有分类 看默认分类是否存在 存在则改成对应分类
|
||
if (element.path === this.defaultPath) {
|
||
this.form.path = this.defaultPath
|
||
}
|
||
})
|
||
this.updatePath()
|
||
}
|
||
},
|
||
methods: {
|
||
updatePath () {
|
||
this.$emit('input', this.form.path) // 发送 input 事件给父级
|
||
},
|
||
// 递归函数,根据指定的父节点ID查找子节点并排序
|
||
findChildren (categoryList, parentId) {
|
||
const children = []
|
||
// 遍历分类列表中的每个对象
|
||
for (const item of categoryList) {
|
||
// 如果当前对象的pid等于指定的父节点ID,表示是子节点
|
||
if (item.pid === parentId) {
|
||
// 递归调用findChildren函数,查找当前子节点的子节点
|
||
const subChildren = this.findChildren(categoryList, item.id)
|
||
// 如果子节点有内容,将当前子节点和子节点的子节点合并到结果数组中
|
||
if (subChildren.length > 0) {
|
||
children.push(item, ...subChildren)
|
||
} else {
|
||
// 如果子节点没有内容,直接将当前子节点加入结果数组
|
||
children.push(item)
|
||
}
|
||
}
|
||
}
|
||
return children
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.centered-avatar {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
|
||
.rspan {
|
||
float: right;
|
||
color: #8492a6;
|
||
font-size: 13px
|
||
}
|
||
</style>
|