效果图如下
代码如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link href="https://cdn.bootcdn.net/ajax/libs/font-awesome/5.13.0/css/all.css" rel="stylesheet">
<style>
* {
margin: 0;
padding: 0;
list-style: none;
}
.sb-tree {
cursor: pointer;
padding: 5px;
color: #555;
}
</style>
</head>
<body>
<div id="app">
<sb-tree style="margin:10px;background: #ccc;" :keys="k1" :load="loadNode"></sb-tree>
</div>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.11/vue.js"></script>
<script>
Vue.component("sb-tree", {
props: {
load: {
type: Function,
required: true
},
level: {
type: Number,
default: 0
},
code: {
type: [String, Number],
default: ''
},
keys: {
type: Object,
validator: function (value) {
let keys = Object.keys(value)
return keys.includes('label') && keys.includes('code')
},
default() {
return {
label: "label",
code: 'code'
}
}
}
},
data() {
return {
mylist: []
}
},
created() {
this.load({
level: this.level,
code: this.code
}, data => {
data.forEach(r => {
r.showChildren = false
})
this.mylist = data
})
},
template: `
<ul class="sb-tree" v-if="mylist&& mylist.length">
<li v-for="(item,i) in mylist">
<span @click="item.showChildren = !item.showChildren">
<i class="fa fa-chevron-right" aria-hidden="true"></i> {{item[keys.label]}}
</span>
<sb-tree :code="item.code" :level="level+1" style="padding-left:30px"
:keys="keys" v-if="item.showChildren"
:load="load"></sb-tree>
</li>
</ul>
`
})
let province = [
{
code: "3",
name: "江苏省"
},
{
code: "4",
name: "安徽省"
},
{
code: "5",
name: "浙江省"
}
]
let cities = [
{
code: "30",
name: "南京市"
},
{
code: "31",
name: "苏州市"
},
{
code: "35",
name: "南通市"
},
{
code: "40",
name: "芜湖市"
},
{
code: "41",
name: "六安"
},
{
code: "42",
name: "蚌埠"
},
{
code: "50",
name: "湖州市"
},
{
code: "51",
name: "金华市"
},
{
code: "52",
name: "舟山"
}
]
let countries = [
{
code: "301",
name: "鼓楼区"
},
{
code: "302",
name: "江宁区"
},
{
code: "311",
name: "吴江区"
},
{
code: "312",
name: "苏中区"
},
{
code: "401",
name: "庐州区"
},
{
code: "422",
name: "xx区"
},
{
code: "500",
name: "上城区"
},
{
code: "511",
name: "下城区"
},
{
code: "502",
name: "下沙区"
}
]
new Vue({
el: "#app",
data() {
return {
k1: {
label: "name",
code: "code"
}
}
},
methods: {
loadNode(node, resolve) {
console.log(node);
if (node.level === 0) {
return resolve(province)
}
setTimeout(() => {
let data = []
if (node.level === 1) data = cities.filter(r => r.code.startsWith(node.code))
else data = countries.filter(r => r.code.startsWith(node.code))
return resolve(data)
}, 200);
}
}
})
</script>
</body>
</html>