视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
vue用递归组件写树形控件的实例代码
2020-11-27 22:11:21 责编:小采
文档

最近在vue项目中遇到需要用树形控件的部分,比如导航目录是不确定的,所以必须要用树形结构,不管导航目录有几级,都可以自动显示出来,我一开始觉得element-ui有树形控件,不需要自己写,调用就可以了,后来才发现,调用完事之后,样式不可控,而且要加东西特别困难,无法满足项目需求,于是,一首《凉凉》送给自己,后来去翻vue官网,发现居然有递归组件,一开始我写了两个组件,互相调用,可以写出来,后来返现,如果项目要用到5棵树,我要写10个组件,而且样式控制起来超级恶心,于是我就各种查资料,原生的也试过了,原生js写的并不能在vue项目中使用,因为它用js创造的元素,违反了vue数据驱动视图的原则,所以pass,又听一遍《凉凉》,当然如果有小伙伴对原生js写的树形结构感兴趣我也可以贴出来,那么我们先来看看vue版的吧,后来,我就一直在默念“递归”这个词,递归不就是自己调自己吗,我可以只写一个组件,来调用自己啊,也许应该可以,后来,经过试验终于成功了,下面我贴上代码

vue版的树形控件

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <meta http-equiv="X-UA-Compatible" content="ie=edge">
 <title>树形结构2</title>
</head>
<body>
 <div id = "app">
 <tree :folder = "trees" :select = "select"></tree>
 </div>
 <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
 <script>
 Vue.component('tree', {
 name:"tree",
 template:`<ul>
 <li v-for = "item in folder">
 <span @click = "select(item)">{{ item.label }}</span>
 <tree v-if = "item.children" :folder = "item.children" :select = "select"></tree>
 </li>
 </ul>`,
 props:["folder","select"],
 })
 // <tree v-if = "item.children" :folder = "item.children"></tree>
 var app = new Vue({
 el:"#app",
 data:{
 msg:"hello world",
 trees: [
 {
 id:1,
 label:"1级目录1",
 show:false,
 children:[
 {
 id:"1-1",
 label:"1.1目录"
 },
 {
 id:"1-2",
 label:"1.2目录"
 },
 {
 id:"1-3",
 label:"1.3目录"
 },
 ]
 },
 {
 id:2,
 label:"1级目录2",
 show:false
 },
 {
 id:3,
 label:"1级目录3",
 show:false,
 children:[
 {
 id:"3-1",
 label:"3.1目录"
 },
 {
 id:"3-2",
 label:"3.2目录",
 show:false,
 children:[
 {
 id:"3-2-1",
 label:"3.2.1目录"
 },
 {
 id:"3-2-2",
 label:"3.2.2目录"
 },
 {
 id:"3-2-3",
 label:"3.2.3目录"
 }
 ]
 }
 ]
 },
 {
 id:4,
 label:"1级目录4",
 show:false,
 children:[
 {
 id:"4-1",
 label:"4.1目录"
 },
 {
 id:"4-2",
 label:"4.2目录",
 show:false,
 children:[
 {
 id:"4-2-1",
 label:"4.2.1目录"
 }
 ]
 }
 ]
 },
 {
 id:5,
 label:"1级目录5",
 show:false,
 children:[
 {
 id:"5-1",
 label:"5.1目录",
 show:false,
 children:[
 {
 id:"5-1-1",
 label:"5.1.1目录"
 },
 {
 id:"5-1-2",
 label:"5.1.2目录",
 show:false,
 children:[
 {
 id:"5-1-2-1",
 label:"5.1.2.1目录"
 },
 ]
 }
 ]
 },
 {
 id:"5-2",
 label:"5.2目录",
 show:false
 }
 ]
 },
 ]
 },
 methods:{
 clickHandler(){
 console.log(23333);
 },
 select(data){
 console.log(data);
 }
 },
 mounted(){
 console.log(this.trees);
 }
 })
 </script>
</body>
</html>

看下结果

当然我用的全局组件,如果用vue-cli搭建的环境是一样的,引入组件就可以了,但是一定要注意,组件内必须要用name属性,而且name的名称要和组件名称(组件标签名称)一致才可以

贴一个项目中用的模板吧,相当于做笔记了

<template>
 <ul class = "dataBaseTree">
 <li v-for = "(item,index) in folder" :key = "index">
 <span @click = "select(item)" :class = "{'active':currentId == item.id}">
 <i class = "folderIcon" v-if = "item.children">
 <icon :icon = "'xiala'" v-if = "item.show"></icon>
 <icon :icon = "'xiala2'" v-else></icon>
 </i>
 {{ item.label }}
 </span>
 <el-collapse-transition>
 <DatabaseTree v-if = "item.children && item.show" :folder = "item.children" :select = "select" :currentId = "currentId"></DatabaseTree>
 </el-collapse-transition>
 </li>
 </ul>
</template>

<script>
 import { mapGetters , mapActions} from 'vuex';
 export default{
 name:"DatabaseTree",
 props:["folder","select","currentId"],
 data(){
 return{
 addParams:{
 label:"",
 children:[]
 },
 noteData:{
 children:[]
 }
 }
 },
 computed:{
 ...mapGetters(["catalog"])
 },
 methods:{}
 }
</script>

<style lang="scss" scoped>
 .dataBaseTree{
 padding-left:12%;
 line-height:40px;
 ul{
 padding-left:12%;
 line-height:40px;
 li{
 span{
 display:inline-block;
 padding-left:23%;
 height:100%;
 width:120%;
 color:#ababab;
 font-size:14px;
 position: relative;
 cursor: pointer;
 &:hover{
 background: #EDF0F5;
 }
 .folderIcon{
 color:#BCBCBC;
 position: absolute;
 top:-1px;
 left:22px;
 }
 }
 }
 }
 li{
 position: relative;
 span{
 display:inline-block;
 padding-left:40px;
 font-size:14px;
 height:100%;
 width:120%;
 cursor: pointer;
 position: relative;
 right:25px;
 top:-2px;
 color:#ababab;
 &:hover{
 background: #EDF0F5;
 }
 .titleIcon{
 color:#C3C3C3;
 font-size:16px;
 position: absolute;
 top:12px;
 left:16px;
 }
 .folderIcon{
 color:#BCBCBC;
 position: absolute;
 top:-1px;
 left:22px;
 }
 }
 .active{
 background: #EDF0F5;
 }
 }
 }
</style>

vue版的就到这里了

 下面贴一个原生js版的,感兴趣的小伙伴可以继续往下看

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <meta http-equiv="X-UA-Compatible" content="ie=edge">
 <title>Document</title>
</head>
<body>
 <script>
 var tree=[
 {
 id:1,
 label:"1级目录1",
 children:[
 {
 id:"1-1",
 label:"1.1目录"
 },
 {
 id:"1-2",
 label:"1.2目录"
 },
 {
 id:"1-3",
 label:"1.3目录"
 },
 ]
 },
 {
 id:2,
 label:"1级目录2",
 },
 {
 id:3,
 label:"1级目录3",
 children:[
 {
 id:"3-1",
 label:"3.1目录"
 },
 {
 id:"3-2",
 label:"3.2目录",
 children:[
 {
 id:"3-2-1",
 label:"3.2.1目录"
 },
 {
 id:"3-2-2",
 label:"3.2.2目录"
 },
 {
 id:"3-2-3",
 label:"3.2.3目录"
 }
 ]
 }
 ]
 },
 {
 id:4,
 label:"1级目录4",
 children:[
 {
 id:"4-1",
 label:"4.1目录"
 },
 {
 id:"4-2",
 label:"4.2目录",
 children:[
 {
 id:"4-2-1",
 label:"4.2.1目录"
 }
 ]
 }
 ]
 },
 {
 id:5,
 label:"1级目录5",
 children:[
 {
 id:"5-1",
 label:"5.1目录",
 children:[
 {
 id:"5-1-1",
 label:"5.1.1目录"
 },
 {
 id:"5-1-2",
 label:"5.1.2目录",

 children:[
 {
 id:"5-1-2-1",
 label:"5.1.2.1目录"
 },
 ]
 }
 ]
 },
 {
 id:"5-2",
 label:"5.2目录"
 }
 ]
 },
 ];
 var render = function(tree) {
 if (!tree) return null
 var ul = document.createElement('ul');
 for(var i = 0; i < tree.length;i++){
 var li = document.createElement('li')
 // 创建span标签
 var span = document.createElement('span'); span.innerText = tree[i].label;
 li.appendChild(span);
 if(tree[i].children){
 var sub = render(tree[i].children);
 li.appendChild(sub);
 }
 ul.appendChild(li);
 }
 return ul
 };
 document.body.innerHTML = '';
 document.body.appendChild(render(tree)); 
 </script>
</body>
</html>

看下结果

总结

以上所述是小编给大家介绍的vue用递归组件写树形控件的实例代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

下载本文
显示全文
专题