* 文章内容很有用,那就5星好评吧!😘
大家好,我是Funion数字营销实战派飞小优,目前在运营网站的过程中,针对多级菜单需求有很强的刚需,具体需要输出到不同的页面中,那如何实现多层级导航菜单系统呢?
多层级导航菜单系统需求描述
实现一个多层级导航菜单系统,要求:
- 支持无限层级嵌套
- 父级菜单与子菜单样式独立控制
- 悬停交互效果(背景色变化+文字颜色变化)
前端HTML的结构
<!-- 一级菜单 -->
<div class="nav-box-cont">
<div class="dropdown-left-nav-box">
<div class="dropdown-left has-children">
<a href="#">
<div class="dropdown-left-nav-cont"> <!-- 影响区 -->
<img class="menu-icon" src="...">
<span class="menu-title">主菜单</span>
</div>
</a>
<!-- 二级菜单容器 -->
<div class="dropdown-left-content">
<div class="submenu">
<!-- 二级菜单项 -->
<div class="dropdown-left-nav-cont"> <!-- 独立区 -->
<!-- 可继续嵌套三级 -->
</div>
</div>
</div>
</div>
</div>
</div>参考前端案例
前端参考的是某宝的这种,当然我们需要在基础结构上做差异化处理

实现方案思路
采用WP的原生Menu Walker类来实现。关于 WordPress 中的 Walker 类,这是一个非常重要的核心概念,专门用于处理层级化数据的遍历和渲染。以下是详细的专业解释:
Walker 类核心定义
Walker 是 WordPress 提供的抽象类(位于 wp-includes/class-wp-walker.php),用于:
- 递归处理层级数据结构(如菜单、分类、页面)
- 提供标准化的遍历接口
- 自定义输出 HTML 的结构
典型应用场景
| 应用场景 | 对应 Walker 类 | 功能说明 |
|---|---|---|
| 导航菜单 | Walker_Nav_Menu | 渲染 wp_nav_menu() 的输出 |
| 分类目录 | Walker_Category | 生成分类列表 |
| 页面列表 | Walker_Page | 生成 hierarchical pages |
| 评论列表 | Walker_Comment | 嵌套评论的渲染 |
具体实现步骤
采用子主题进行不是,直接在子主题functions.php注册,然后写出配套的css来实现。
先注册自定义菜单实例
/**
* 自定义下拉菜单Walker类
*/
class Custom_Dropdown_Walker extends Walker_Nav_Menu {
public function start_lvl(&$output, $depth = 0, $args = null) {
$output .= '<div class="dropdown-left-content"><div class="submenu">';
}
public function end_lvl(&$output, $depth = 0, $args = null) {
$output .= '</div></div>';
}
public function start_el(&$output, $item, $depth = 0, $args = null, $id = 0) {
$classes = empty($item->classes) ? array() : (array) $item->classes;
$class_names = join(' ', apply_filters('nav_menu_css_class', array_filter($classes), $item, $args, $depth));
$class_names .= ' dropdown-left';
if (in_array('menu-item-has-children', $classes)) {
$class_names .= ' has-children';
}
$output .= "<div class='dropdown-left-nav-box'>";
$output .= "<div class='" . esc_attr($class_names) . "'>";
// 菜单项图片逻辑重构
$image_url = get_post_meta($item->ID, '_menu_item_image_url', true);
// 父级菜单结构(depth=0)
if ($depth === 0) {
// 显示可点击的父级菜单图片
$output .= "<a href='" . esc_url($item->url) . "' class='dropdown-left-nav-link'>";
if ($image_url) {
$output .= "<div class='dropdown-left-nav-img'>";
$output .= "<img src='" . esc_url($image_url) . "' alt='" . esc_attr($item->title) . "'>";
$output .= "</div>";
}
$output .= "<div class='dropdown-left-nav-cont'>";
$output .= "<div class='dropdown-left-nav-tit'>" . esc_html($item->title) . "</div>";
if (!empty($item->description)) {
$output .= "<span class='dropdown-left-text-des'>" . esc_html($item->description) . "</span>";
}
$output .= "</div>";
$output .= "</a>";
}
// 子菜单结构(depth>0)
else {
$output .= "<div class='dropdown-left-nav-cont'>";
$output .= "<a href='" . esc_url($item->url) . "' class='submenu-item'>";
// 保留子菜单左侧图片
if ($image_url) {
$output .= "<div class='submenu-item-left'>";
$output .= "<img src='" . esc_url($image_url) . "' alt='" . esc_attr($item->title) . "'>";
$output .= "</div>";
} else {
$output .= "<div class='submenu-item-left'>";
$output .= "<img src='" . esc_url(get_template_directory_uri() . '/images/default-menu-icon.png') . "' alt='默认图标'>";
$output .= "</div>";
}
$output .= "<div class='submenu-item-right'>";
$output .= "<span class='submenu-item-title'>" . esc_html($item->title) . "</span>";
if (!empty($item->description)) {
$output .= "<span class='submenu-item-desc'>" . esc_html($item->description) . "</span>";
}
$output .= "</div>";
$output .= "</a>";
$output .= "</div>";
}
}
public function end_el(&$output, $item, $depth = 0, $args = null) {
$output .= "</div></div>";
}
}撰写对应css文件
css自己去摸索,每个项目不一样,因此就不贴代码,请看截图

另外需要注意一点的是这个菜单并不是直接输出到导航位置,它是针对页面或者指定的地方输出,所以你前期需要考虑是以短码来输出还是其他的技术方式,适合自己的就好,因此你需要把这个短码输出功能也要集成到functions.php或者你的组件化目录中,最后你在以短码结构[XXX menu] 插入页面中(我这里只是讲思路,并不适合直接照搬的)因此你会看到Ui后台中菜单的基本配置,如:


那最后将你的短代码输出到任意页面,比如输出到首页,如

前端验证
最后在前端查看下你的新菜单样式,如


所以这是对多层级导航菜单系统的差异化扩展,主要是针对CSS做了调整,整体架构类似某宝的折叠菜单,总之万变不离其宗,喜欢折腾的大家可以去尝试下!

