相信大部分小伙伴们在实际开发中都使用UI框架来节省开发时间,提升工作效率。Vue诞生后出现了许多优秀的UI框架,如element-ui、ant-design等。不管你用哪个,它们都是在Vue之上进行的二次封装,今天我们就来自己封装一个框架中的树形组件。

你可能会说,有现成的框架不使,为什么非要自己写一个呢?对于这个问题,不用我说,相信你自己会找到答案!

在贴代码之前,你必须知道什么是递归,而且还要知道在vue中组件如何递归。请看下图:

如果没看懂也没关系,你只要记住组件如果要调用自身,必须通过name属性,下面是treeMenus组件:

<template>
  <ul>
    <li v-for="(item,index) in list " :key="index">
      <p class="title" @click="changeStatus(index)">{{item.text}}</p>
      <tree-menus v-if="scopesDefault[index]" :list="item.nodes"></tree-menus>
    </li>
  </ul>
</template>

<script>
export default {
  name: "treeMenus",
  props: {
    list: Array
  },
  data() {
    return {
      scopesDefault: []
    };
  },
  methods: {
    changeStatus(index) {
      if (this.scopesDefault[index] === true) {
        this.$set(this.scopesDefault, index, false);
      } else {
        this.$set(this.scopesDefault, index, true);
      }
    }
  },
  created() {}
};
</script>

<style scoped>
ul {
  list-style: none;
}
p {
  margin: 0;
}
.title {
  cursor: pointer;
  border-top: 1px solid #dedede;
  border-bottom: 1px solid #dedede;
}
</style>

下面展示树形组件的数据以及父组件的调用:

<template>
   <my-trees :list="treeData.area_list"></my-trees>
</template>

<script>
// 父组件引用子组件,如果你想直接拿来用,路径要改对。
import myTrees from '../components/TreeMenu.vue'

// 树形组件数据,一次性全部加载。建议存到vuex或者本地缓存中。
let treeData = {
  'state': 0,
  'area_list': [{
    'text': '全部地区',
    'area_id': 1,
    'nodes': [{
      'province': '广东省',
      'city': '',
      'area_id': 3,
      'text': '广东省',
      'county': '',
      'nodes': [{
        'province': '广东省',
        'city': '东莞',
        'area_id': 5,
        'text': '东莞',
        'county': '',
        'nodes': [{
          'province': '广东省',
          'text': '东莞区',
          'area_id': 81,
          'county': '县级市',
          'city': '东莞'
        }]
      }, {
        'province': '广东省',
        'city': '佛山市',
        'area_id': 28,
        'text': '中山',
        'county': '禅城区',
        'nodes': [{
          'province': '广东省',
          'text': '中山大学',
          'area_id': 32,
          'county': '中山区',
          'city': '中山'
        }, {
          'province': '广东省',
          'text': '华南理工',
          'area_id': 35,
          'county': '天河区',
          'city': '广州'
        }, {
          'province': '广东省',
          'text': '越秀区',
          'area_id': 77,
          'county': '越秀区',
          'city': '广州'
        }]
      }, {
        'province': '广东省',
        'city': '江门市',
        'area_id': 29,
        'text': '深圳',
        'county': '江海区',
        'nodes': [{
          'province': '广东省',
          'text': '南山区',
          'area_id': 157,
          'county': '南山区',
          'city': '深圳市'
        }]
      }, {
        'province': '山西省',
        'text': '韶关',
        'area_id': 30,
        'county': '小店区',
        'city': '太原市'
      }, {
        'province': '辽宁省',
        'text': '汕头',
        'area_id': 31,
        'county': '中山区',
        'city': '大连市'
      }, {
        'province': '吉林省',
        'text': '茂名',
        'area_id': 33,
        'county': '昌邑区',
        'city': '吉林市'
      }, {
        'province': '辽宁省',
        'text': '肇庆',
        'area_id': 36,
        'county': '中山区',
        'city': '大连市'
      }, {
        'province': '广东省',
        'text': '湛江',
        'area_id': 37,
        'county': '坡头区',
        'city': '湛江市'
      }, {
        'province': '广东省',
        'text': '茂名',
        'area_id': 38,
        'county': '茂南区',
        'city': '茂名市'
      }, {
        'province': '广东省',
        'text': '肇庆',
        'area_id': 40,
        'county': '鼎湖区',
        'city': '肇庆市'
      }, {
        'province': '广东省',
        'text': '宝安区',
        'area_id': 79,
        'county': '宝安区',
        'city': '深圳'
      }, {
        'province': '广东省',
        'city': '广州',
        'area_id': 88,
        'text': '广州',
        'county': '县级市',
        'nodes': [{
          'province': '广东省',
          'city': '广州',
          'area_id': 89,
          'text': '天河区',
          'county': '天河区',
          'nodes': [{
            'province': '广东省',
            'text': '黄埔大道西163号富星1号梯',
            'area_id': 183,
            'county': '天河区',
            'city': '广州市'
          }]
        }, {
          'province': '广东省',
          'text': '越秀区',
          'area_id': 90,
          'county': '县级市',
          'city': '广州'
        }, {
          'province': '广东省',
          'text': '番禺区',
          'area_id': 91,
          'county': '县级市',
          'city': '广州'
        }, {
          'province': '广东省',
          'text': '白云区',
          'area_id': 92,
          'county': '县级市',
          'city': '广州'
        }, {
          'province': '广东省',
          'text': '花都区',
          'area_id': 93,
          'county': '县级市',
          'city': '广州'
        }, {
          'province': '广东省',
          'text': '南沙区',
          'area_id': 94,
          'county': '县级市',
          'city': '广州'
        }, {
          'province': '广东省',
          'text': '从化区',
          'area_id': 95,
          'county': '县级市',
          'city': '广州'
        }, {
          'province': '广东省',
          'text': '增城区',
          'area_id': 96,
          'county': '县级市',
          'city': '广州'
        }, {
          'province': '广东省',
          'city': '广州',
          'area_id': 97,
          'text': '黄埔区',
          'county': '县级市',
          'nodes': [{
            'province': '广东省',
            'text': '双岗',
            'area_id': 182,
            'county': '黄埔区',
            'city': '广州市'
          }]
        }, {
          'province': '广东省',
          'text': '荔湾区',
          'area_id': 98,
          'county': '县级市',
          'city': '广州'
        }, {
          'province': '广东省',
          'text': '海珠区',
          'area_id': 99,
          'county': '县级市',
          'city': '广州'
        }, {
          'province': '广东省',
          'text': '南沙区',
          'area_id': 180,
          'county': '南沙区',
          'city': '广州市'
        }]
      }]
    }, {
      'province': '福建省',
      'city': '',
      'area_id': 17,
      'text': '福建省',
      'county': '',
      'nodes': [{
        'province': '福州',
        'city': '',
        'area_id': 18,
        'text': '福州',
        'county': '',
        'nodes': [{
          'province': '福建省',
          'text': '福建师范',
          'area_id': 51,
          'county': null,
          'city': '厦门'
        }, {
          'province': '福建省',
          'text': '福州大学',
          'area_id': 52,
          'county': null,
          'city': '福州'
        }, {
          'province': '安徽省',
          'text': '安徽师范',
          'area_id': 75,
          'county': null,
          'city': null
        }]
      }, {
        'province': '厦门',
        'city': '',
        'area_id': 19,
        'text': '厦门',
        'county': '',
        'nodes': [{
          'province': '福建省',
          'text': '厦门大学',
          'area_id': 50,
          'county': null,
          'city': '厦门'
        }]
      }, {
        'province': '福建省',
        'text': '莆田',
        'area_id': 43,
        'county': null,
        'city': null
      }, {
        'province': '福建省',
        'text': '三明',
        'area_id': 44,
        'county': null,
        'city': null
      }, {
        'province': '福建省',
        'text': '泉州',
        'area_id': 45,
        'county': null,
        'city': null
      }, {
        'province': '福建省',
        'text': '漳州',
        'area_id': 46,
        'county': null,
        'city': null
      }, {
        'province': '福建省',
        'text': '南平',
        'area_id': 47,
        'county': null,
        'city': null
      }, {
        'province': '福建省',
        'text': '龙岩',
        'area_id': 48,
        'county': null,
        'city': null
      }, {
        'province': '福建省',
        'text': '宁德',
        'area_id': 49,
        'county': null,
        'city': null
      }]
    }, {
      'province': '湖北省',
      'city': '',
      'area_id': 21,
      'text': '湖北省',
      'county': '',
      'nodes': [{
        'province': '湖北省',
        'city': '',
        'area_id': 22,
        'text': '武汉',
        'county': '',
        'nodes': [{
          'province': '湖北省',
          'text': '东西湖区',
          'area_id': 23,
          'county': '东西湖区',
          'city': '武汉'
        }, {
          'province': '湖北省',
          'text': '武汉大学',
          'area_id': 53,
          'county': null,
          'city': '武汉'
        }, {
          'province': '湖北省',
          'text': '华中科技',
          'area_id': 58,
          'county': null,
          'city': null
        }]
      }, {
        'province': '湖北省',
        'city': '',
        'area_id': 25,
        'text': '十堰',
        'county': '',
        'nodes': [{
          'province': '湖北省',
          'text': '竹山县',
          'area_id': 66,
          'county': null,
          'city': null
        }, {
          'province': '湖北省',
          'text': '竹溪县',
          'area_id': 70,
          'county': null,
          'city': null
        }, {
          'province': '湖北省',
          'text': '郧西县',
          'area_id': 74,
          'county': null,
          'city': null
        }, {
          'province': '湖北省',
          'text': '湖北汽车工业学院',
          'area_id': 80,
          'county': '茅箭区',
          'city': '十堰'
        }]
      }, {
        'province': '湖北省',
        'text': '黄石',
        'area_id': 27,
        'county': null,
        'city': null
      }, {
        'province': '湖北省',
        'text': '宜昌',
        'area_id': 54,
        'county': null,
        'city': null
      }, {
        'province': '湖北省',
        'text': '鄂州',
        'area_id': 55,
        'county': null,
        'city': null
      }, {
        'province': '湖北省',
        'text': '荆门',
        'area_id': 56,
        'county': null,
        'city': null
      }, {
        'province': '湖北省',
        'text': '孝感',
        'area_id': 57,
        'county': null,
        'city': null
      }, {
        'province': '湖北省',
        'text': '咸宁',
        'area_id': 59,
        'county': null,
        'city': null
      }, {
        'province': '湖北省',
        'text': '随州',
        'area_id': 60,
        'county': null,
        'city': null
      }, {
        'province': '湖北省',
        'text': '恩施自治州',
        'area_id': 61,
        'county': null,
        'city': '恩施'
      }, {
        'province': '湖北省',
        'text': '仙桃',
        'area_id': 62,
        'county': null,
        'city': null
      }, {
        'province': '湖北省',
        'text': '天门',
        'area_id': 63,
        'county': null,
        'city': null
      }, {
        'province': '湖北省',
        'text': '神农架',
        'area_id': 64,
        'county': null,
        'city': null
      }, {
        'province': '湖北省',
        'text': '潜江',
        'area_id': 65,
        'county': null,
        'city': null
      }]
    }, {
      'province': '海南省',
      'city': '地级市',
      'area_id': 100,
      'text': '海南省',
      'county': '县级市',
      'nodes': [{
        'province': '海南省',
        'text': '海口',
        'area_id': 101,
        'county': '县级市',
        'city': '地级'
      }]
    }, {
      'province': '河南省',
      'city': '地级市',
      'area_id': 102,
      'text': '河南省',
      'county': '县级市',
      'nodes': [{
        'province': '河南省',
        'text': '洛阳',
        'area_id': 104,
        'county': '县级市',
        'city': '洛阳'
      }, {
        'province': '河南省',
        'text': '郑州',
        'area_id': 105,
        'county': '县级市',
        'city': '郑州'
      }]
    }, {
      'province': '省份',
      'city': '地级市',
      'area_id': 148,
      'text': '江苏省',
      'county': '市/县级市',
      'nodes': [{
        'province': '江苏省',
        'text': '苏州市',
        'area_id': 149,
        'county': '市/县级市',
        'city': '苏州'
      }, {
        'province': '江苏省',
        'text': '镇江市',
        'area_id': 150,
        'county': '市/县级市',
        'city': '镇江'
      }, {
        'province': '江苏省',
        'text': '虎丘区',
        'area_id': 152,
        'county': '虎丘区',
        'city': '苏州'
      }]
    }, {
      'province': '云南省',
      'city': '昆明市',
      'area_id': 154,
      'text': '云南省',
      'county': '官渡区',
      'nodes': [{
        'province': '云南省',
        'text': '云南省',
        'area_id': 155,
        'county': '宣威市',
        'city': '曲靖市'
      }]
    }, {
      'province': '湖南省',
      'city': '长沙市',
      'area_id': 162,
      'text': '湖南省',
      'county': '长沙市',
      'nodes': [{
        'province': '湖南省',
        'city': '长沙市',
        'area_id': 163,
        'text': '长沙市',
        'county': '长沙市',
        'nodes': [{
          'province': '湖南省',
          'city': '长沙市',
          'area_id': 167,
          'text': '岳麓区',
          'county': '岳麓区',
          'nodes': [{
            'province': '湖南省',
            'text': '涉外经济学院',
            'area_id': 170,
            'county': '岳麓区',
            'city': '长沙市'
          }]
        }, {
          'province': '湖南省',
          'text': '芙蓉区',
          'area_id': 168,
          'county': '芙蓉区',
          'city': '长沙市'
        }, {
          'province': '湖南省',
          'text': '长沙市',
          'area_id': 169,
          'county': '长沙市',
          'city': '长沙市'
        }]
      }, {
        'province': '湖南省',
        'text': '张家界',
        'area_id': 164,
        'county': '县级市',
        'city': '张家界市'
      }, {
        'province': '湖南省',
        'text': '常德市',
        'area_id': 165,
        'county': '县级市',
        'city': '常德市'
      }]
    }, {
      'province': '省份',
      'city': '地级市',
      'area_id': 196,
      'text': '未定义分组电梯',
      'county': '县级市',
      'nodes': [{
        'province': '省份',
        'text': '未分配电梯',
        'area_id': 217,
        'county': '县级市',
        'city': '地级市'
      }]
    }, {
      'province': '新疆',
      'city': '',
      'area_id': 203,
      'text': '新疆',
      'county': '',
      'nodes': [{
        'province': '新疆',
        'city': '乌鲁木齐市',
        'area_id': 204,
        'text': '乌鲁木齐',
        'county': '天山区',
        'nodes': [{
          'province': '新疆',
          'city': '乌鲁木齐市',
          'area_id': 205,
          'text': '新市区',
          'county': '乌鲁木齐',
          'nodes': [{
            'province': '新疆',
            'text': '飞机场',
            'area_id': 210,
            'county': '新市区',
            'city': '乌鲁木齐市'
          }, {
            'province': '新疆',
            'text': '送变电小区',
            'area_id': 216,
            'county': '新市区',
            'city': '乌鲁木齐市'
          }, {
            'province': '新疆',
            'text': '乌鲁木齐环境监测中心',
            'area_id': 218,
            'county': '新市区',
            'city': '乌鲁木齐市'
          }]
        }]
      }]
    }, {
      'province': '山东省',
      'city': '',
      'area_id': 207,
      'text': '山东',
      'county': '',
      'nodes': [{
        'province': '山东省',
        'city': '',
        'area_id': 208,
        'text': '烟台市',
        'county': '',
        'nodes': [{
          'province': '山东省',
          'text': '',
          'area_id': 209,
          'county': '县级市',
          'city': '烟台市'
        }]
      }]
    }]
  }]
}

export default {
  components: {
    // 这里别忘了注册子组件
    myTrees
  },
  data () {
    return {
      treeData
    }
  },
  methods: {}
}
</script>

<style scoped>
</style>

完成上述代码后,你应该可以看到效果,笔者对于框架的使用还是很赞同的,但是如果遇到项目中需要使用树形组件,而使用的ui框架中恰巧没有,总不能直接把element-ui整个加载到项目中吧,所以自己造造轮子还是很有必要的。

树形组件的封装就这些了,如果使用中遇到问题,欢迎留言。若有需要改进的地方,欢迎指正~

Logo

前往低代码交流专区

更多推荐