由于项目中,需要用到追加表单项目的功能,而表单项目在 PC 端是树形列表的形式展现,而且要实现多选功能,依上述需求开发了树形分类选择组件。
组件开发中用到的知识要点是:组件递归调用,组件递归调用不仅可以用来实现树形分类选择器,也可以用来实现多级菜单展示。
注意点:
由于 AVM 框架有自己的一套触发和监听子组件事件的方式,监听子组件事件
子组件内部递归调用的时候也需要进行事件的监听,同时进行 “this.fire” 进行触发。如果在递归调用的子组件中不进行监听的话,会导致父组件只能监听到第一层级触发的事件,从第二级开始触发的时间父组件无法监听到。
fire 方法有两个参数,第一个参数为事件名称,第二个参数为要传递的自定义数据,在父组件监听方法里面通过 e.detail 获取传递的数据。 在递归调用子组件的监听方法中给父组件传递参数的时候需要去 e.detail,不能直接传 e, 否则会出现多个 detail 的层级。
组件代码
<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\"}]}}"
}
]
}]
}
]