由于项目中,需要用到追加表单项目的功能,而表单项目在 PC 端是树形列表的形式展现,而且要实现多选功能,依上述需求开发了树形分类选择组件。

组件开发中用到的知识要点是:组件递归调用,组件递归调用不仅可以用来实现树形分类选择器,也可以用来实现多级菜单展示。

注意点:

由于 AVM 框架有自己的一套触发和监听子组件事件的方式,监听子组件事件

APICloud AVM 框架 封装树形分类选择组件 组件递归调用_递归调用

子组件内部递归调用的时候也需要进行事件的监听,同时进行 “this.fire” 进行触发。如果在递归调用的子组件中不进行监听的话,会导致父组件只能监听到第一层级触发的事件,从第二级开始触发的时间父组件无法监听到。

fire 方法有两个参数,第一个参数为事件名称,第二个参数为要传递的自定义数据,在父组件监听方法里面通过 e.detail 获取传递的数据。 在递归调用子组件的监听方法中给父组件传递参数的时候需要去 e.detail,不能直接传 e, 否则会出现多个 detail 的层级。

APICloud AVM 框架 封装树形分类选择组件 组件递归调用_json_02


组件代码

<template>
    <view class="easy-tree-box">
        <view v-for="(item,index) in listdata">
            <view class="easy-tree-node" >
                <view class="easy-tree-option" v-if="item.itemType==3" >
                    <image class="easy-tree-ico" src='../../image/tree-ico.png' mode="widthFix"></image>
                    <text class="easy-tree-title">{item.itemName}</text>
                </view>
                <view class="easy-tree-option" v-else-if="item.itemType==6" >
                    <checkbox color="#3b72e6" data-item={item} name="item-option" notallow="checkItem"/>
                    <text class="easy-tree-item">{item.itemName}</text>
                </view>                
                <easy-tree :listdata='item.children' v-if="item.children" notallow="checkNode"></easy-tree>
            </view>        
        </view>
    </view>
</template>
<script>
    export default {
        name: 'easy-tree',
        installed(){
            // this.fire('selectitem','3333');
        },
        props:{
            listdata:Object
        },
        data() {
            return{
                result:{}
            }
        },
        methods: {
            checkItem(e){            
                // console.log(JSON.stringify(e));
                // console.log(JSON.stringify(e.dataset.item.formJson));
                this.data.result={
                    type:e.dataset.item.fieldType,
                    name:e.dataset.item.itemName,
                    options:JSON.parse(e.dataset.item.formJson).options,
                    model:e.dataset.item.id,
                    key:e.dataset.item.id,
                    isCheck:e.detail.checked
                }
                this.fire('selectitem',this.data.result);            
            },
            checkNode(e){
                //console.log (JSON.stringify (e)+"委托");
                this.fire('selectitem',e.detail);
            }
        }
    }
</script>
<style>
    .easy-tree-box {
        background-color: #ffffff;
        padding-top: 10px;
        padding-right: 10px;
    }
    .easy-tree-node{
        padding-left: 10px;
    }
    .easy-tree-title{
        font-size: 15px;
    }
    .easy-tree-item{
        font-size: 13px;
        padding-left: 10px;
    }
    .easy-tree-option{
        flex-flow: row nowrap;
        justify-content: flex-start;
        align-items: center;
    }
    .easy-tree-ico{
        width: 20px;
    }
</style>


组件调用示例

<template>
    <scroll-view class="page">
        <safe-area></safe-area>
        <easy-tree :listdata={listdata} notallow="checkNode"></easy-tree>
    </scroll-view>
</template>
<script>
    import '../../components/easy-tree.stml'
    import {POST, GET} from "../../script/req.js"
    import $util from "../../utils/util.js"
    export default {
        name: 'activity-check-item',
        apiready(){
            this.queryItems();    
        },
        data() {
            return{
                listdata: [],
                checkList:[]
            }
        },
        methods: {
            queryItems(){
                var optinotallow={
                    headers: {
                        'token': ''
                    }
                };
                var data={
                    itemStatus:3
                };
                api.showProgress();
                POST('inspect/item/treeData', data, option).then(ret =>{
                    // console.log(JSON.stringify(ret));
                    if(ret.success){
                        this.data.listdata = ret.treeData;
                    }
                    api.hideProgress();
                })
            },
            checkNode(e){
                // console.log(JSON.stringify(e));
                if(this.data.checkList.filter(item => item.model==e.detail.model).length>0){
                    // 判断是否已存在,存在则更新选中状态
                    this.data.checkList.filter(item => item.model==e.detail.model)[0].isCheck=e.detail.isCheck;
                }
                else{
                    // 不存在直接更新数据
                    this.data.checkList.push(e.detail);
                }
                // console.log(JSON.stringify(this.data.checkList));            
            }
        }
    }
</script>
<style>
    .page {
        height: 100%;
        background-color: #ffffff;
    }
</style>


数据格式

[
    {
        "id":"2ae030d494d647a79456effedb11f65a",
        "parentIds":"0,",
        "sort":30,
        "children":[
        ],
        "itemName":"测试专用",
        "itemType":"3",
        "fieldType":"",
        "formJson":""
    },
    {
        "id":"7cda428fa3cd43179e92e7585ccc321b",
         "itemName":"信息是否完善",
        "itemType":"3",
        "children":[
            {
                "id":"8ea6072328dc443eae46d17495ab7f2b",
                "children":[
                    {
                        "id":"8c372e0e3f01485486a707e79bdb00c4",
                    
                        "children":[
                        ],
                        "itemName":"信息公开,正副本是否齐全",
                        "itemType":"6",
                     
                        "fieldType":"radio",
                        "formJson":"{\"type\":\"radio\",\"name\":\"\",\"options\":{\"inline\": true,\"showLabel\": true,\"options\":[{\"label\":\" 齐全 \",\"value\":\"0\"},{\"label\":\" 不齐全 \",\"value\":\"1\"}]}}"
                        
                    },
                    {
                        "id":"eaf7af968cf84acbb939c9dda3b340e7",
                        
                        "children":[
                        ],
                        "itemName":"信息是否公开",
                        "itemType":"6",
                        
                        "fieldType":"radio",
                        "formJson":"{\"type\":\"radio\",\"name\":\"\",\"options\":{\"inline\": true,\"showLabel\": true,\"options\":[{\"label\":\" 已公开 \",\"value\":\"0\"},{\"label\":\" 未公开 \",\"value\":\"1\"}]}}"
                    }
                ]        
            }]
    }
]
 


示例展示

APICloud AVM 框架 封装树形分类选择组件 组件递归调用_json_03