<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
本文範例為大家分享了微信小程式自定義多層級核取方塊選單的具體程式碼,供大家參考,具體內容如下
因客戶需要,有一個功能是需要註冊使用者時選擇多個【單元 - 樓層 - 裝置】的繫結,谷歌了一通,沒有找到想要的,無奈之舉只能手寫一個…
1、初始化時,預設展開選中的選單
2、點選每一層父級選單,會自動摺疊其子選單
3、選中子級節點會預設選中父級節點
4、子級節點都沒選中預設取消選中父級節點
5、選中父級節點預設選中其所有子級節點
這裡沒寫元件,如果需要可以改為元件。
可能會有一個疑問為哈是 treeMenu2 不是 treeMenu1
因為 treeMenu1 寫的low,treeMenu2 升級了js程式碼。
1、treeMenu2.js
js裡面的各種事件均為遞迴操作,可根據載入的資料動態進行操作。
// pages/biz/treeMenu/treeMenu.js Page({ /** * 頁面的初始資料 */ data: { menuTreeImgLeft: "../../../icon/f_left.png", menuTreeImgBottom: "../../../icon/f_bottom.png", menuTree: [{ "checked": false, "children": [{ "checked": false, "children": [{ "id": "1-1-1", "checked": true, "field": "1", "title": "裝置1", }, { "id": "1-1-2", "checked": false, "field": "2", "title": "裝置2" }], "id": "1-1", "field": "1-floor", "title": "1樓", "isHidden": true, "bindAll": false, }, { "checked": false, "children": [{ "checked": false, "field": "3", "title": "裝置3" }], "id": "1-2", "field": "2-floor", "title": "2樓", "isHidden": true, }, { "checked": false, "children": [{ "id": "1-3-4", "checked": true, "field": "4", "title": "裝置4" }], "id": "1-3", "field": "3-floor", "title": "3樓", "isHidden": true, }], "id": "1", "isHidden": true, "bindAll": false, "field": "1-unit", "title": "1單元" }, { "checked": false, "children": [{ "checked": false, "children": [{ "id": "2-1-1", "checked": false, "field": "5", "title": "裝置5" }], "id": "2-1", "field": "1-floor", "title": "1樓", "isHidden": true, }, { "checked": false, "children": [{ "id": "2-2-1", "checked": false, "field": "6", "title": "裝置6" }], "id": "2-2", "field": "2-floor", "title": "2樓", "isHidden": true, }], "bindAll": false, "isHidden": true, "field": "2-unit", "title": "2單元", "id": "2", }], deepList: [], deepListOne: [] }, /** * 生命週期函數--監聽頁面顯示 */ onShow: function () { this.checkForChecked() }, /** * 預設選中是否展開 */ checkForChecked() { var data = this.data.menuTree // 獲取所有被選中的節點 var checkedNodes = this.getDeep(data) // 獲取所有選中節點的父節點 checkedNodes.forEach(element => { var tmp = this.getParentsById(data, element.id) if (tmp != undefined && tmp.length > 0) { // 最後一級選中,預設展開和選中父級選單 tmp.forEach(element => { element.isHidden = false element.checked = true }) } }) this.setData({ menuTree: data }) }, // 遞迴 - 根據id獲取所有父節點 getParentsById(list, id) { for (let i in list) { if (list[i].id == id) { return [list[i]] } if (list[i].children) { let node = this.getParentsById(list[i].children, id); if (node !== undefined) { return node.concat(list[i]) } } } }, // 遞迴 - 根據id獲取當前節點物件 getNodeById(data, id, newNodes = []) { data.forEach(element => { // 匹配到節點 if (element.id === id) { newNodes.push(element) } if (element.children) { this.getNodeById(element.children, id, newNodes) } }) return newNodes; }, // 遞迴 - 根據id獲取所有子節點,(其實就是先獲取當前id的節點物件,然後取當前物件,注意這裡返回的是陣列) getChildrenById(data, id, newNodes = []) { var list = data.children if (list != undefined) { list.forEach(element => { newNodes.push(element) if (element.children) { this.getChildrenById(element, id, newNodes) } }) } return newNodes; }, // 遞迴 - 獲取所有選中節點 getDeep(data, newCheckedNodes = []) { data.forEach(element => { if (element.checked) { newCheckedNodes.push(element) } if (element.children) { this.getDeep(element.children, newCheckedNodes) } }) return newCheckedNodes }, // 遞迴 - 根據節點id獲取兄弟所有節點 getBrotherNodesById(list, id) { // 非頂級節點:獲取節點父節點物件裡的children var parentNodes = this.getParentsById(list, id) if (parentNodes && parentNodes.length >= 2) { return parentNodes[1].children } // 頂級節點:第一級是自己,從原始陣列中遍歷第一層即可 return list }, // 根據當前節點id,獲取及所有的父級兄弟節點的所有父節點 getParentBrotherAllNodesById(list, id) { var result = [] // 1、獲取當前節點id父節點的父節點 var parentNodes = this.getParentsById(list, id) // 小於3表示當前父節點是頂級節點 if (parentNodes.length < 3) { return parentNodes[parentNodes.length - 1] } var testNode = parentNodes[2]; // 2、獲取父節點的父節點所有兄弟節點 var children = testNode.children children.forEach(element => { var parentNodesById = this.getParentsById(list, element.id) if (parentNodesById.length >= 2) { // js 陣列中新增多個元素 簡單的方法 push(...[]) result.push(...(parentNodesById.slice(0, parentNodesById.length - 1))) } }); return result; }, /** * 點選事件 - 左側繫結核取方塊事件 */ checkboxChangeBindAll(e) { var index = e.currentTarget.dataset.index; var index2 = e.currentTarget.dataset.index2; var list = this.data.menuTree if (index2 == undefined) { list[index].bindAll = !list[index].bindAll } if (index2 != undefined) { list[index].children[index2].bindAll = !list[index].children[index2].bindAll } console.log(this.data.menuTree); }, checkboxChange(e) { // console.log(e); console.log('checkbox發生change事件,攜帶value值為:', e.detail.value) const values = e.detail.value }, /** * 點選事件 - 右側核取方塊事件 */ checkboxChangeAll(e) { var id = e.currentTarget.dataset.id; var data = this.data.menuTree var node = this.getNodeById(data, id) var childrenNodes = this.getChildrenById(node[0], id) // 1、子節點點選中狀態-跟隨父節點移動 node[0].checked = !node[0].checked // 節點下面的所有子節點跟隨父節點的選中狀態 childrenNodes.forEach(element => { element.checked = node[0].checked }) // 2、父節點選中狀態,子節點都沒選中,父節點預設不選中,子節點有一個選中,父節點也選中 // 獲取同級兄弟節點 var bortherNodes = this.getBrotherNodesById(data, id) // 3、同級都選中 var allChecked = false bortherNodes.forEach(element => { if (element.checked) { allChecked = true } }) // 獲取節點id所有父節點 var parentNodes = this.getParentsById(data, id) if (parentNodes.length > 1) { if (allChecked) { // 下標index=0的節點是其本身,這裡跳過 for (let index = 1; index < parentNodes.length; index++) { const element = parentNodes[index]; element.checked = true } }else{ parentNodes[1].checked =false } } // 4、同級都未選中 if (!allChecked) { var allNoChecked = false // 根據當前節點id,獲取除去頂級節點的所有的父級兄弟節點的所有父節點 var parentBother = this.getParentBrotherAllNodesById(data, id) console.log(parentBother); if (parentBother.length > 1) { parentBother.forEach(element => { if (element.checked) { allNoChecked = true } }); } console.log(allNoChecked); // console.log(parentBother); if(!allNoChecked){ parentNodes.forEach(element => { element.checked=false }); } } this.setData({ menuTree: data }) // console.log(this.data.menuTree); }, /** * 點選事件 - 點選層級顯示和摺疊事件 */ openAndHide(e) { var id = e.currentTarget.dataset.id; var list = this.data.menuTree console.log(id); // 根據 id 獲取選中節點的物件 var node = this.getNodeById(list, id) // 根據 id 獲取選中節點下的所有子節點 var res = this.getChildrenById(node[0], id) // 包含當前id節點本身 res.push(node[0]) // 遍歷選中節點(及自己)是否展開 res.forEach(element => { element.isHidden = !element.isHidden }) this.setData({ menuTree: list }) } })
2、treeMenu2.JSON
{ "usingComponents": {} }
3、treeMenu2.WXMl
這裡其實寫的有問題,我主要寫java的,前端用的不多,哪個高手指點一下,wxml 檔案怎麼樣能遞迴呢,
我這裡直接最笨的方法,三層for…,
<view class="divcss5-max"> <view class="page-section "> <view style="padding-bottom:10px">裝置選擇列表:{{menuTree.length}}</view> <view class="weui-cells weui-cells_after-title "></view> <view> <!-- 第一層 --> <block class="weui-cell weui-check__label line-center" wx:for="{{menuTree}}" wx:for-index="index" wx:for-item="item" wx:key="id"> <view class="paddingBottom_10 "></view> <view class="paddingLeft_10"> <view class="treeMenuCenter"> <checkbox-group bindchange="checkboxChangeAll" data-index="{{index}}" data-id="{{item.id}}" > <checkbox value="{{item.field}}" checked="{{item.checked}}" /> </checkbox-group> <!-- 箭頭圖示 --> <view class="treeMenuCenter" bindtap="openAndHide" data-id="{{item.id}}" data-index="{{index}}" > <image wx:if="{{item.isHidden == true}}" class="icon-chioce" src="{{menuTreeImgLeft}}"></image> <image wx:if="{{item.isHidden == false}}" class="icon-chioce" src="{{menuTreeImgBottom}}"></image> <text style="color:black" decode="{{true}}"> {{item.title}} </text> </view> <!-- <checkbox-group bindchange="checkboxChangeBindAll" data-index="{{index}}" > <checkbox checked="{{item.bindAll}}" />繫結單元 </checkbox-group> --> </view> </view> <!-- 第二層 --> <view class="" hidden="{{item.isHidden}}" wx:for="{{item.children}}" wx:for-index="index2" wx:for-item="item2" wx:key="id"> <view class="paddingLeft_20 "> <view class="treeMenuCenter"> <!-- <view class="dashedStyleWidth_40"></view> --> <checkbox-group bindchange="checkboxChangeAll" data-id="{{item2.id}}" data-index="{{index}}" data-index2="{{index2}}" > <checkbox value="{{item2.field}}" checked="{{item2.checked}}" /> </checkbox-group> <!-- 箭頭圖示 --> <view class="treeMenuCenter" bindtap="openAndHide" data-id="{{item2.id}}" data-index="{{index}}" data-index2="{{index2}}" > <image wx:if="{{item2.isHidden == true}}" class="icon-chioce" src="{{menuTreeImgLeft}}"></image> <image wx:if="{{item2.isHidden == false}}" class="icon-chioce" src="{{menuTreeImgBottom}}"></image> <text style="color:#0094aa" decode="{{true}}"> {{item2.title}} </text> </view> <!-- <checkbox-group bindchange="checkboxChangeBindAll" data-index="{{index}}" data-index2="{{index2}}" > <checkbox checked="{{item2.bindAll}}" />繫結樓層 </checkbox-group> --> </view> </view> <!-- 第三層 --> <block class="" wx:for="{{item2.children}}" wx:for-item="item3" wx:for-index="index3" wx:key="id"> <view class="paddingLeft_30 " hidden="{{item2.isHidden}}"> <!-- <view class="dashedStyleWidth_80"></view> --> <checkbox-group bindchange="checkboxChangeAll" data-id="{{item3.id}}" data-index="{{index}}" data-index2="{{index2}}" data-index3="{{index3}}" > <checkbox value="{{item3.field}}" checked="{{item3.checked}}" /> {{item3.title}} </checkbox-group> </view> </block> </view> <view class="paddingBottom_10 "></view> <view class="weui-cells weui-cells_after-title "></view> </block> </view> </view> </view>
4、treeMenu2.WXSS
/* pages/biz/treeMenu/treeMenu.wxss */ @import '../../../lib/weui.wxss'; .empty{ padding: 5px 0px; } .paddingLeft_10{ padding-left: 10px; padding-bottom: 5px; } .paddingLeft_20{ padding-left: 40px; padding-bottom: 5px; } .paddingLeft_30{ padding-left: 80px; padding-bottom: 5px; } .paddingBottom_10{ padding-top: 10px; } .line-center{ display: flex; align-items: center; justify-content: center; flex-flow: column; } /** *參考:https://cloud.tencent.com/developer/article/1690869 * / /* 選中後的 背景樣式 (紅色背景 無邊框 可根據UI需求自己修改) */ checkbox .wx-checkbox-input.wx-checkbox-input-checked { background: #0094aa; } /* 選中後的 對勾樣式 (白色對勾 可根據UI需求自己修改) */ checkbox .wx-checkbox-input.wx-checkbox-input-checked::before{ color:#fff; /* 對勾顏色 白色 */ } .treeMenuCenter{ display: flex; align-items: center; } .dashedStyleWidth_80{ margin-left: 10px; margin-right: 5px; width: 80px; height: 0px; border: 0.5px dotted gray; } .dashedStyleWidth_40{ margin-left: 10px; margin-right: 5px; width: 40px; height: 0px; border: 0.5px dotted gray; } .icon-chioce { height: 15px; width: 15px; padding-top: 10px; padding-bottom: 10px; background-color: fff; }
哪個大俠指點一下,wxml如何遞迴就完美了
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援it145.com。
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45