纵有疾风起
人生不言弃

使用Python3.7+Django2.0.4配合vue.js2.0的组件递归来实现无限级分类(递归层级结构)

原文转载自「刘悦的技术博客」https://v3u.cn/a_id_133

所谓的无限极分类是啥?其实简单点说就是一个人类可以繁衍出多个后代,然后一个后代又可以分另外多个后代这样无限繁衍下去(可以想象神奇动物在哪里2里面莱斯特兰奇的家族族谱),就好象linux系统你可以新建一个文件夹,然后在这个文件夹里又可以建一些个文件夹,在文件夹底下还可以建一些文件夹一样,随后使用tree命令就可以查看文件夹目录层级。

那么这种层级结构也成为树结构在日常的开发需求里也是很常见的,比如美多商城系统的商品分类,课程的目录章节,以及以及论坛里的帖子回复等等,本次我们后台利用Django来写一个能够返回层级结构数据的接口,接口将该数据以json的形式返回前端,前端使用vue的组件递归来展示数据。

首先,打开django项目中的models.py,新建一个类别的模型类,这里我们以最简单的parentid的形式来建立

class Cate(models.Model):    #主键 通过参数声明主键    id = models.AutoField(primary\_key=True)    #分类名称    name = models.CharField(max\_length=500)    #父级id    pid = models.IntegerField()    #表名    class Meta:        db\_table = 'cate'

由于我们的项目基于drf框架,所以要增加一个序列器类,如果你的项目没有用drf,可以直接用json模块来进行序列化

from rest\_framework import serializersfrom myapp.models import Cateclass CateSer(serializers.ModelSerializer):    class Meta:        model = Cate        fields = "\_\_all\_\_"

由于django序列化出来的类不具备层级结构,所以我们提前写好一个用来递归的方法:

def xTree(datas):    lists=\[\]    tree={}    parent\_id=''    for i in datas:        item=i        tree\[item\['id'\]\]=item    root=None    for i in datas:        obj=i        if not obj\['pid'\]:            root=tree\[obj\['id'\]\]            lists.append(root)        else:            parent\_id=obj\['pid'\]            if 'childlist' not in tree\[parent\_id\]:                   tree\[parent\_id\]\['childlist'\]=\[\]            tree\[parent\_id\]\['childlist'\].append(tree\[obj\['id'\]\])    return lists

此时我们写一个视图接口,用来从数据库中读取数据

class MyTree(APIView):    def get(self,request):        #获取订单列表        catelist = Cate.objects.filter()        #序列化        catelist\_ser = CateSer(catelist,many=True)        mylist= xTree(catelist\_ser.data)        return Response(mylist)

请在mysql库里存一些测试数据

使用Python3.7+Django2.0.4配合vue.js2.0的组件递归来实现无限级分类(递归层级结构)插图
image

测试一下接口,看看是否以json的形式返回了层级结构

使用Python3.7+Django2.0.4配合vue.js2.0的组件递归来实现无限级分类(递归层级结构)插图1
image

ok,接口没有问题,现在我们把目光投向前端,打开vue项目,新建一个Reply.vue组件

所谓递归组件: 就是组件可以在它们自己的模板中调用自身,不过它们只能通过 name 选项来做这件事,例如给组件设置属性 name: ‘Reply’,然后在模板中就可以使用 Reply 调用自己进行递归调用了

<template>    <div>            <li >                    <div :class="\[data.id==0 ? 'root': '', 'reply'\]">{{ data.name }}</div>                                <ul v-if="data.childlist && data.childlist.length>0">                        <Reply v-for="child in data.childlist" :key="child.id" :data="child"/>                    </ul>                </li>        </div></template>        <script>    export default {        name: 'Reply', // 递归组件需要设置 name 属性,才能在模板中调用自己        props:\['data'\],    };    </script>        <style >    .reply {        padding-left: 4px;        border-left: 1px solid #eee;    }    ul {            padding-left: 20px;            list-style: none;        }        .root { display: none; }        </style>

然后在其他任意组件中调用该Reply.vue组件,传入刚刚写好的接口数据

<template>        <div>                                <Reply :data="data" />            </div>    </template>             <script>            import {config,formatXml} from '../config.js';        import mh\_test from './mh\_test.vue';        import Reply from './Reply.vue';            import md5 from 'js-md5';              export default {        data () {          return {              data:{},            online: 0          }        },        components: {            //'mh\_test':mh\_test            Reply      },            //钩子方法        mounted:function(){                            this.get\_token();        },        //绑定事件        methods:{                get\_token(){                 this.axios.get('http://localhost:8000/mytree/').then((result) =>{            console.log(result);            var mytree = {'id':0,name:'123'};            mytree\['childlist'\] = result.data;            this.data = mytree;            console.log(this.data);            });            },                   }      }      </script>           <style>        .on {                background: #cdcbff;            }    .off {        background: #fefdff;        }        </style>

最后请求页面,可以看到展示的效果:

使用Python3.7+Django2.0.4配合vue.js2.0的组件递归来实现无限级分类(递归层级结构)插图2
image

当然了,vue组件也可以间接的调用自己实现递归,这涉及到组件之间的循环引用,这样比较麻烦,可读性也间接的降低了不少。

原文转载自「刘悦的技术博客」 https://v3u.cn/a_id_133

文章转载于:https://www.jianshu.com/p/dc098b5ff99d

原著是一个有趣的人,若有侵权,请通知删除

未经允许不得转载:起风网 » 使用Python3.7+Django2.0.4配合vue.js2.0的组件递归来实现无限级分类(递归层级结构)
分享到: 生成海报

评论 抢沙发

评论前必须登录!

立即登录