141 lines
4.4 KiB
Vue
141 lines
4.4 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.bz_1 != ''" class="vm" shape="square" :size="25"
|
|||
|
:src="$store.state.settings.host + '/Data/UploadFiles/category/' + item.bz_1">
|
|||
|
</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 = 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 = 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>
|