在 ThinkPHP 開發中,經常需要處理多層級分類數據的顯示,例如三級分類選單。本文將詳細介紹如何結合後端遞歸構建三維陣列,並在前端模板中使用 <volist> 標籤實現三級巢狀循環輸出。
首先在模型中編寫遞歸方法,將資料庫中的分類數據組裝成包含 child(二級)與 grandchild(三級)的多維陣列結構。
// 主遞歸方法:構建前兩級分類
function MakeTree($pid, $level) {
$map['pid'] = $pid;
$map['level'] = $level;
$result = $this->where($map)->order('rank ASC')->findall();
if ($result) {
foreach ($result as $key => $value) {
$title = $value['alias'];
$list[$title]['id'] = $value['id'];
$list[$title]['pid'] = $value['pid'];
$list[$title]['alias'] = $value['alias'];
$list[$title]['title'] = $value['title'];
$list[$title]['level'] = $value['level'];
$list[$title]['state'] = $value['state'];
$list[$title]['rank'] = $value['rank'];
// 當層級小於等於 3 時,遞歸獲取子分類
if ($value['level'] <= 3) {
$list[$title]['child'] = $this->_MakeSonTree($value['id']);
}
}
}
return $list;
}
// 私有方法:構建第二、三級分類
function _MakeSonTree($pid) {
$map['pid'] = $pid;
$result = $this->where($map)->order('rank ASC')->findall();
if ($result) {
foreach ($result as $key => $value) {
$title = $value['alias'];
$list[$title]['id'] = $value['id'];
$list[$title]['pid'] = $value['pid'];
$list[$title]['alias'] = $value['alias'];
$list[$title]['title'] = $value['title'];
$list[$title]['level'] = $value['level'];
$list[$title]['state'] = $value['state'];
$list[$title]['rank'] = $value['rank'];
// 判斷是否存在第三級子分類
if ($this->haschild($value['id'])) {
$list[$title]['grandchild'] = $this->_MakeSonTree($value['id']);
}
}
}
return $list;
}
// 輔助方法:檢測是否存在子分類
function haschild($id) {
$result = D('LearningChannel')->where("pid=" . $id)->find();
return $result ? true : false;
}
在控制器動作中調用模型方法,並將結果分配給模板變數 list。
$result = D('Learning')->MakeTree(0, 1);
$this->assign('list', $result);
在模板文件中,通過巢狀 <volist> 標籤依次遍歷一級、二級、三級分類,並根據傳入的 getid 設置預選狀態。
<select name="category" id="select" class="text mr5">
<volist name="list" id="vo">
<option name="cid" value="{$vo.id}"
<eq name="vo.id" value="getid">selected</eq>
>{$vo.alias}</option>
<volist name="vo['child']" id="child">
<option name="cid" value="{$child.id}"
<eq name="child.id" value="getid">selected</eq>
>--{$child.alias}</option>
<volist name="child['grandchild']" id="grand">
<option name="cid" value="{$grand.id}"
<eq name="grand.id" value="getid">selected</eq>
>---{$grand.alias}</option>
</volist>
</volist>
</volist>
</select>
child(二級)與 grandchild(三級)name 屬性需對應陣列鍵名,如 vo['child']、child['grandchild']<eq> 標籤實現當前選中項的高亮顯示foreach 或組件化渲染掌握這套「後端遞歸構建樹 + 前端巢狀 volist 遍歷」的模式,即可輕鬆應對多級分類、多級選單等常見業務場景。