You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Yii2基于Bootstrap实现三级菜单问题求助

Hey there! Let's get that third-level menu working in your Yii2 Bootstrap setup. The root issues right now are:

  1. Your current data-fetching methods only pull up to the second level of menus
  2. The view code doesn't handle rendering nested third-level items

Here's a step-by-step fix:

Step 1: Update the Menu Data Retrieval

First, replace your existing menuList() and subMenuList() methods with a function that fetches full nested menu data (supports up to 3+ levels):

public static function getNestedMenu() {
    // Get top-level menus (parent = 0 or NULL)
    $topMenu = \Yii::$app->db->createCommand("
        SELECT page_id, page_name, focus_areaid, category 
        FROM sas_pages 
        WHERE (parent = 0 OR parent IS NULL) 
          AND display_nav=1 
          AND is_publish=1 
          AND is_active=1
    ")->queryAll();

    // Add second-level menus, then third-level menus
    foreach ($topMenu as &$item) {
        // Fetch second-level children
        $subMenu = \Yii::$app->db->createCommand("
            SELECT page_id, page_name, parent, focus_areaid, category 
            FROM sas_pages 
            WHERE parent = :parent 
              AND is_publish=1 
              AND is_active=1
        ", [':parent' => $item['page_id']])->queryAll();

        // Fetch third-level children for each second-level menu
        foreach ($subMenu as &$subItem) {
            $subSubMenu = \Yii::$app->db->createCommand("
                SELECT page_id, page_name, parent, focus_areaid, category 
                FROM sas_pages 
                WHERE parent = :parent 
                  AND is_publish=1 
                  AND is_active=1
            ", [':parent' => $subItem['page_id']])->queryAll();
            $subItem['children'] = $subSubMenu;
        }

        $item['children'] = $subMenu;
    }

    return $topMenu;
}

In your controller, call this method and pass the data to the view:

$menuList = YourModel::getNestedMenu(); // Replace "YourModel" with your actual model name
return $this->render('your-view-file', ['menuList' => $menuList]);

Step 2: Update the View to Render Third-Level Menus

Replace your existing view code with this, which handles nested third-level items. We'll also add the necessary Bootstrap submenu styling:

First, add this CSS to your layout or view (Bootstrap doesn't support third-level menus by default):

.dropdown-submenu {
    position: relative;
}

.dropdown-submenu > .dropdown-menu {
    top: 0;
    left: 100%;
    margin-top: -6px;
    margin-left: -1px;
    border-radius: 0 6px 6px 6px;
}

.dropdown-submenu:hover > .dropdown-menu {
    display: block;
}

.dropdown-submenu > a:after {
    display: block;
    content: " ";
    float: right;
    width: 0;
    height: 0;
    border-color: transparent;
    border-style: solid;
    border-width: 5px 0 5px 5px;
    border-left-color: #ccc;
    margin-top: 5px;
    margin-right: -10px;
}

.dropdown-submenu:hover > a:after {
    border-left-color: #fff;
}

Then update your menu HTML:

<div class="collapse navbar-collapse">
    <ul class="nav navbar-nav">
        <?php foreach ($menuList as $item): ?>
            <?php
            $pageName = str_replace(' ', '-', $item['page_name']);
            $url = ['society/index', 'PageName' => $pageName];
            $hasSubMenu = !empty($item['children']);
            ?>
            <li class="<?= $hasSubMenu ? 'dropdown' : '' ?>">
                <?php if ($hasSubMenu): ?>
                    <a href="<?= Url::to($url) ?>" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
                        <?= $item['page_name'] ?>
                        <span class="caret"></span>
                    </a>
                    <ul class="dropdown-menu">
                        <?php foreach ($item['children'] as $subItem): ?>
                            <?php
                            $subPageName = str_replace(' ', '-', $subItem['page_name']);
                            $subUrl = ['society/index', 'PageName' => $subPageName];
                            $hasThirdLevel = !empty($subItem['children']);
                            ?>
                            <li class="<?= $hasThirdLevel ? 'dropdown-submenu' : '' ?>">
                                <?php if ($hasThirdLevel): ?>
                                    <a href="<?= Url::to($subUrl) ?>" class="dropdown-toggle" data-toggle="dropdown">
                                        <?= $subItem['page_name'] ?>
                                    </a>
                                    <ul class="dropdown-menu">
                                        <?php foreach ($subItem['children'] as $thirdLevelItem): ?>
                                            <?php $thirdPageName = str_replace(' ', '-', $thirdLevelItem['page_name']); ?>
                                            <li>
                                                <?= Html::a($thirdLevelItem['page_name'], ['society/index', 'PageName' => $thirdPageName]) ?>
                                            </li>
                                        <?php endforeach; ?>
                                    </ul>
                                <?php else: ?>
                                    <?= Html::a($subItem['page_name'], $subUrl) ?>
                                <?php endif; ?>
                            </li>
                        <?php endforeach; ?>
                    </ul>
                <?php else: ?>
                    <a href="<?= Url::to($url) ?>">
                        <?= $item['page_name'] ?>
                    </a>
                <?php endif; ?>
            </li>
        <?php endforeach; ?>
    </ul>
</div>

How This Works

  • The updated getNestedMenu() method first pulls top-level menus, then fetches their direct children (second level), and finally fetches children for each second-level menu (third level)
  • The view code checks for third-level items and uses Bootstrap's dropdown-submenu class (with custom CSS) to display them as nested dropdowns
  • Hovering over a second-level menu with third-level items will show the nested menu to the right

内容的提问来源于stack exchange,提问作者Chandan Kumar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:39:22