El marco frontal Layui realiza el efecto de árbol dinámico (la lista desplegable en el lado izquierdo del sistema de gestión de libros)

Tabla de contenido

I. Introducción

1. ¿Qué es un menú de árbol?

2. Escenarios de uso del menú de árbol

2. Realización de casos

1. Análisis de la demanda

2. Trabajo preparatorio

① Dependencias de importación

②Herramientas

Base Dao (CRUD general)

BuildTree (completa la conversión de datos planos a nivel padre-hijo)

ResponseUtil (convertir datos en formato json para eco)

③ Escribir entidad

escritura de la capa 3.dao

4. escritura de capa de servlet

5. construcción de página jsp

6. Presentación del caso


I. Introducción

Antes de completar el caso, primero comprendamos qué es un menú de árbol

1. ¿Qué es un menú de árbol?

        Un menú de árbol es un patrón de diseño de interfaz de usuario que a menudo se usa para organizar y presentar una jerarquía de grandes cantidades de información. Recibe su nombre del hecho de que el menú presenta una estructura similar a las ramas y nodos de un árbol. Un menú de árbol generalmente consta de un nodo principal y varios nodos secundarios, y cada nodo secundario puede tener sus propios nodos secundarios, formando una estructura jerárquica de relaciones padre-hijo .

        En un menú de árbol, un nodo principal representa una opción o categoría de nivel superior, mientras que los nodos secundarios representan opciones o subcategorías específicas asociadas con el nodo principal. Los usuarios pueden explorar niveles más detallados expandiendo o contrayendo nodos secundarios. Por lo general, el nodo hoja es el nodo inferior y representa la opción o el contenido más específico.

        Los menús de árbol son adecuados para aplicaciones y sitios web que necesitan organizar y presentar datos complejos o directorios de varios niveles. Permiten a los usuarios navegar y seleccionar fácilmente las opciones deseadas, proporcionando una forma limpia e intuitiva de navegar y acceder a la información.

2. Escenarios de uso del menú de árbol

Los menús de árbol se usan ampliamente en varias aplicaciones y sitios web, los siguientes son algunos escenarios de uso común:

  • 1. Administración de recursos de archivos : el menú de árbol se puede usar para buscar y administrar recursos de archivos, especialmente cuando los archivos están organizados en una estructura de directorio de varios niveles. Los usuarios pueden expandir y contraer directorios para acceder a los archivos o carpetas deseados.
  • 2. Estructura organizativa y gestión de personal : La estructura organizativa de una empresa u organización se puede visualizar a través de un menú de árbol. Cada nodo representa un departamento, equipo o individuo, y los usuarios pueden ver niveles e información más detallados al expandir el nodo.
  • 3. Menú de navegación : el menú de navegación principal de un sitio web o aplicación suele utilizar una estructura de árbol para mostrar diferentes páginas u opciones funcionales. Los usuarios pueden expandir o contraer los elementos del menú según sea necesario para ubicar rápidamente la función o el contenido deseado.
  • 4. Categorías de productos y navegación por catálogos : las tiendas en línea o los sitios de comercio electrónico a menudo usan menús de árbol para organizar categorías y categorías de productos. Los usuarios pueden navegar y seleccionar productos expandiendo y contrayendo diferentes categorías.
  • 5. Sistema de administración de contenido : los menús de árbol se usan ampliamente en los sistemas de administración de contenido para organizar y administrar contenido como páginas, artículos, categorías y etiquetas de un sitio web.

En general, los menús de árbol son adecuados para cualquier escenario en el que sea necesario presentar y organizar datos jerárquicos para proporcionar una interfaz de usuario clara y fácil de navegar.

2. Realización de casos

1. Análisis de la demanda

Queremos completar la visualización de la lista en el lado izquierdo de un sistema de gestión de libros. Lo esencial es el diseño de la tabla. El diseño de la tabla está relacionado con la visualización de nuestra página jsp. El siguiente es mi diseño de tabla solo para su referencia .

También es necesario tener datos en el diseño de la tabla. Por supuesto, no escriba los datos de la tabla de forma casual, ¡de lo contrario pueden ocurrir errores! !

        Los datos aquí son muy particulares. Los datos que generalmente obtenemos a través de la capa dao son datos planos, que no cumplen con nuestros requisitos. Lo que necesitamos son datos de nivel padre-hijo, entonces, ¿cómo convertir datos planos a qué pasa con nuestros padres? datos del niño? ? En este momento, el diseño de nuestra tabla juega un papel crucial. Podemos ver que los pid de los nodos principales son todos 0, y los pid de sus nodos secundarios corresponden a los id de los nodos principales.

        Se concluye que solo necesitamos dos métodos, uno es consultar todos los métodos (para obtener los datos paralelos), y el otro es realizar dos recorridos en el mismo nivel de datos y agregarlos a la nueva colección (padre-hijo). contenedor). El primero para Agregar los datos cuyo número de pid es el nodo superior, es decir, el nodo padre, al contenedor. El segundo recorrido compara el pid con el id en la nueva colección. Si son iguales, es los niños de la nueva colección.

 

2. Trabajo preparatorio

Nota: Más detalles en la trilogía MVC personalizada que escribí.

① Dependencias de importación

Importe nuestras dependencias requeridas en WebContent➡WEB-INF

Cree un directorio para almacenar js/css y coloque los archivos necesarios en

Paquete de archivos compartidos por varias páginas en archivos públicos

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html ">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title></title>
<!-- 引入layui.css-->
<link rel="stylesheet" href="${pageContext.request.contextPath}/static/js/layui/css/layui.css">

<!-- 引入layui.js-->
<script type="text/javascript" src="${pageContext.request.contextPath}/static/js/layui/layui.js"></script>


</head>

</html>

②Herramientas

Aquí necesitamos usar herramientas

Base Dao (CRUD general)

package com.zking.util;

import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 所有Dao层的父类 BookDao UserDao OrderDao ...
 * 
 * @author Administrator
 *
 * @param <T>
 */
public class BaseDao<T> {

	/**
	 * 适合多表联查的数据返回
	 * @param sql
	 * @param pageBean
	 * @return
	 * @throws SQLException
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 */
	public List<Map<String, Object>> executeQuery(String sql, PageBean pageBean)
			throws SQLException, InstantiationException, IllegalAccessException {

		List<Map<String, Object>> list = new ArrayList<>();
		Connection con = DBAccess.getConnection();
		PreparedStatement pst = null;
		ResultSet rs = null;

		/*
		 * 是否需要分页? 无需分页(项目中的下拉框,查询条件教员下拉框,无须分页) 必须分页(项目中列表类需求、订单列表、商品列表、学生列表...)
		 */
		if (pageBean != null && pageBean.isPagination()) {
			// 必须分页(列表需求)
			String countSQL = getCountSQL(sql);
			pst = con.prepareStatement(countSQL);
			rs = pst.executeQuery();
			if (rs.next()) {
				pageBean.setTotal(String.valueOf(rs.getObject(1)));
			}

			// 挪动到下面,是因为最后才处理返回的结果集
			// -- sql=SELECT * FROM t_mvc_book WHERE bname like '%圣墟%'
			// -- pageSql=sql limit (page-1)*rows,rows 对应某一页的数据
			// -- countSql=select count(1) from (sql) t 符合条件的总记录数
			String pageSQL = getPageSQL(sql, pageBean);// 符合条件的某一页数据
			pst = con.prepareStatement(pageSQL);
			rs = pst.executeQuery();
		} else {
			// 不分页(select需求)
			pst = con.prepareStatement(sql);// 符合条件的所有数据
			rs = pst.executeQuery();
		}

		// 获取源数据
		ResultSetMetaData md = rs.getMetaData();
		int count = md.getColumnCount();
		Map<String, Object> map = null;
		while (rs.next()) {
			map = new HashMap<>();
			for (int i = 1; i <= count; i++) {
//				map.put(md.getColumnName(i), rs.getObject(i));
				map.put(md.getColumnLabel(i), rs.getObject(i));
			}
			list.add(map);
		}
		return list;

	}

	/**
	 * 
	 * @param sql
	 * @param attrs
	 *            map中的key
	 * @param paMap
	 *            jsp向后台传递的参数集合
	 * @return
	 * @throws SQLException
	 * @throws NoSuchFieldException
	 * @throws SecurityException
	 * @throws IllegalArgumentException
	 * @throws IllegalAccessException
	 */
	public int executeUpdate(String sql, String[] attrs, Map<String, String[]> paMap) throws SQLException,
			NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
		Connection con = DBAccess.getConnection();
		PreparedStatement pst = con.prepareStatement(sql);
		for (int i = 0; i < attrs.length; i++) {
			pst.setObject(i + 1, JsonUtils.getParamVal(paMap, attrs[i]));
		}
		return pst.executeUpdate();
	}

	/**
	 * 批处理
	 * @param sqlLst
	 * @return
	 */
	public static int executeUpdateBatch(String[] sqlLst) {
		Connection conn = null;
		PreparedStatement stmt = null;
		try {
			conn = DBAccess.getConnection();
			// 设置不自动提交
			conn.setAutoCommit(false);
			for (String sql : sqlLst) {
				stmt = conn.prepareStatement(sql);
				stmt.executeUpdate();
			}
			conn.commit();
		} catch (Exception e) {
			try {
				conn.rollback();
			} catch (SQLException e1) {
				e1.printStackTrace();
				throw new RuntimeException(e1);
			}
			e.printStackTrace();
			throw new RuntimeException(e);
		} finally {
			DBAccess.close(conn, stmt, null);
		}
		return sqlLst.length;
	}

	/**
	 * 通用的增删改方法
	 * 
	 * @param book
	 * @throws Exception
	 */
	public int executeUpdate(String sql, T t, String[] attrs) throws Exception {
		// String[] attrs = new String[] {"bid", "bname", "price"};
		Connection con = DBAccess.getConnection();
		PreparedStatement pst = con.prepareStatement(sql);
		// pst.setObject(1, book.getBid());
		// pst.setObject(2, book.getBname());
		// pst.setObject(3, book.getPrice());
		/*
		 * 思路: 1.从传进来的t中读取属性值 2.往预定义对象中设置了值
		 * 
		 * t->book f->bid
		 */
		for (int i = 0; i < attrs.length; i++) {
			Field f = t.getClass().getDeclaredField(attrs[i]);
			f.setAccessible(true);
			pst.setObject(i + 1, f.get(t));
		}
		return pst.executeUpdate();
	}

	/**
	 * 通用分页查询
	 * 
	 * @param sql
	 * @param clz
	 * @return
	 * @throws Exception
	 */
	public List<T> executeQuery(String sql, Class<T> clz, PageBean pageBean) throws Exception {
		List<T> list = new ArrayList<T>();
		Connection con = DBAccess.getConnection();
		;
		PreparedStatement pst = null;
		ResultSet rs = null;

		/*
		 * 是否需要分页? 无需分页(项目中的下拉框,查询条件教员下拉框,无须分页) 必须分页(项目中列表类需求、订单列表、商品列表、学生列表...)
		 */
		if (pageBean != null && pageBean.isPagination()) {
			// 必须分页(列表需求)
			String countSQL = getCountSQL(sql);
			pst = con.prepareStatement(countSQL);
			rs = pst.executeQuery();
			if (rs.next()) {
				pageBean.setTotal(String.valueOf(rs.getObject(1)));
			}

			// 挪动到下面,是因为最后才处理返回的结果集
			// -- sql=SELECT * FROM t_mvc_book WHERE bname like '%圣墟%'
			// -- pageSql=sql limit (page-1)*rows,rows 对应某一页的数据
			// -- countSql=select count(1) from (sql) t 符合条件的总记录数
			String pageSQL = getPageSQL(sql, pageBean);// 符合条件的某一页数据
			pst = con.prepareStatement(pageSQL);
			rs = pst.executeQuery();
		} else {
			// 不分页(select需求)
			pst = con.prepareStatement(sql);// 符合条件的所有数据
			rs = pst.executeQuery();
		}

		while (rs.next()) {
			T t = clz.newInstance();
			Field[] fields = clz.getDeclaredFields();
			for (Field f : fields) {
				f.setAccessible(true);
				f.set(t, rs.getObject(f.getName()));
			}
			list.add(t);
		}
		return list;
	}

	/**
	 * 将原生SQL转换成符合条件的总记录数countSQL
	 * 
	 * @param sql
	 * @return
	 */
	private String getCountSQL(String sql) {
		// -- countSql=select count(1) from (sql) t 符合条件的总记录数
		return "select count(1) from (" + sql + ") t";
	}

	/**
	 * 将原生SQL转换成pageSQL
	 * 
	 * @param sql
	 * @param pageBean
	 * @return
	 */
	private String getPageSQL(String sql, PageBean pageBean) {
		// (this.page - 1) * this.rows
		// pageSql=sql limit (page-1)*rows,rows
		return sql + " limit " + pageBean.getStartIndex() + "," + pageBean.getRows();
	}
}

BuildTree (completa la conversión de datos planos a nivel padre-hijo)

package com.zking.util;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class BuildTree {

	/**
	 * 默认-1为顶级节点
	 * @param nodes
	 * @param <T>
	 * @return
	 */
	public static <T> TreeVo<T> build(List<TreeVo<T>> nodes) {

		if (nodes == null) {
			return null;
		}
		List<TreeVo<T>> topNodes = new ArrayList<TreeVo<T>>();

		for (TreeVo<T> children : nodes) {
			String pid = children.getParentId();
			if (pid == null || "-1".equals(pid)) {
				topNodes.add(children);

				continue;
			}

			for (TreeVo<T> parent : nodes) {
				String id = parent.getId();
				if (id != null && id.equals(pid)) {
					parent.getChildren().add(children);
					children.setHasParent(true);
					parent.setChildren(true);
					continue;
				}
			}

		}

		TreeVo<T> root = new TreeVo<T>();
		if (topNodes.size() == 1) {
			root = topNodes.get(0);
		} else {
			root.setId("000");
			root.setParentId("-1");
			root.setHasParent(false);
			root.setChildren(true);
			root.setChecked(true);
			root.setChildren(topNodes);
			root.setText("顶级节点");
			Map<String, Object> state = new HashMap<>(16);
			state.put("opened", true);
			root.setState(state);
		}

		return root;
	}

	/**
	 * 指定idparam为顶级节点
	 * @param nodes
	 * @param idParam
	 * @param <T>
	 * @return
	 */
	public static <T> List<TreeVo<T>> buildList(List<TreeVo<T>> nodes, String idParam) {
		if (nodes == null) {
			return null;
		}
		List<TreeVo<T>> topNodes = new ArrayList<TreeVo<T>>();

		for (TreeVo<T> children : nodes) {

			String pid = children.getParentId();
			if (pid == null || idParam.equals(pid)) {
				topNodes.add(children);

				continue;
			}

			for (TreeVo<T> parent : nodes) {
				String id = parent.getId();
				if (id != null && id.equals(pid)) {
					parent.getChildren().add(children);
					children.setHasParent(true);
					parent.setChildren(true);

					continue;
				}
			}

		}
		return topNodes;
	}

}

ResponseUtil (convertir datos en formato json para eco)

package com.zking.util;

import java.io.PrintWriter;

import javax.servlet.http.HttpServletResponse;

import com.fasterxml.jackson.databind.ObjectMapper;

public class ResponseUtil {

	public static void write(HttpServletResponse response,Object o)throws Exception{
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out=response.getWriter();
		out.println(o.toString());
		out.flush();
		out.close();
	}
	
	public static void writeJson(HttpServletResponse response,Object o)throws Exception{
		ObjectMapper om = new ObjectMapper();
//		om.writeValueAsString(o)代表了json串
		write(response, om.writeValueAsString(o));
	}
}

③ Escribir entidad

Permiso (entidad de tabla de datos)

package com.xw.entity;

/**书籍管理系统实体
 * @author 索隆
 *
 */
public class Permission {
private long id;
private String name;
private String description;
private String url;
private long pid;
private int ismenu;
private long displayno;
	
public Permission() {
	// TODO Auto-generated constructor stub
}

public Permission(long id, String name, String description, String url, long pid, int ismenu, long displayno) {
	super();
	this.id = id;
	this.name = name;
	this.description = description;
	this.url = url;
	this.pid = pid;
	this.ismenu = ismenu;
	this.displayno = displayno;
}

public long getId() {
	return id;
}

public void setId(long id) {
	this.id = id;
}

public String getName() {
	return name;
}

public void setName(String name) {
	this.name = name;
}

public String getDescription() {
	return description;
}

public void setDescription(String description) {
	this.description = description;
}

public String getUrl() {
	return url;
}

public void setUrl(String url) {
	this.url = url;
}

public long getPid() {
	return pid;
}

public void setPid(long pid) {
	this.pid = pid;
}

public int getIsmenu() {
	return ismenu;
}

public void setIsmenu(int ismenu) {
	this.ismenu = ismenu;
}

public long getDisplayno() {
	return displayno;
}

public void setDisplayno(long displayno) {
	this.displayno = displayno;
}

@Override
public String toString() {
	return "Permission [id=" + id + ", name=" + name + ", description=" + description + ", url=" + url + ", pid=" + pid
			+ ", ismenu=" + ismenu + ", displayno=" + displayno + "]";
}



}

Nota: el tipo bigint en mysql es de tipo largo en java

escritura de la capa 3.dao

​
package com.xw.dao;

import java.util.ArrayList;
import java.util.List;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.xw.entity.Permission;
import com.zking.util.BaseDao;
import com.zking.util.BuildTree;
import com.zking.util.TreeVo;

/**书记管理
 * @author 索隆
 *
 */
public class PermissionDao extends BaseDao<Permission>{
	
	/**获取书籍管理的所有信息(平级数据)
	 * @return
	 * @throws Exception 
	 */
	public List<Permission> list() throws Exception{
		String sql="select * from t_easyui_permission";
		return  super.executeQuery(sql, Permission.class, null);
	}

	
	/**将平级数据变成我们需要的父子级数据
	 * @return
	 * @throws Exception 
	 */
	public List<TreeVo<Permission>> menu() throws Exception{
		//存放父子级的容器
		List<TreeVo<Permission>> menu=new ArrayList<TreeVo<Permission>>();
		//拿到平级数据
		List<Permission> list = this.list();
		//遍历平级数据
		for (Permission permission : list) {
			//工具类帮助我们完成父子级关系
			TreeVo<Permission> vo=new TreeVo<Permission>();
			vo.setId(permission.getId()+"");
			vo.setParentId(permission.getPid()+"");
			vo.setText(permission.getName());
			menu.add(vo);
		}
		
		//通过工具类筛选父级菜单的儿子,pid为0是父级菜单
		return BuildTree.buildList(menu, "0");
	}
	
	
	
	public static void main(String[] args) throws Exception {
		//测试数据
		PermissionDao d=new PermissionDao();
	 List<TreeVo<Permission>> menu = d.menu();
	 ObjectMapper om =new ObjectMapper();
	 System.out.println(om.writeValueAsString(menu));
		
		
	}
}

​

Podemos comparar las diferencias entre los dos conjuntos de datos:

  • datos planos
  • datos padre-hijo

4. escritura de capa de servlet

package com.xw.web;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.xw.dao.PermissionDao;
import com.xw.entity.Permission;
import com.zking.framework.ActionSupport;
import com.zking.framework.ModelDriver;
import com.zking.util.ResponseUtil;
import com.zking.util.TreeVo;

/**书籍管理的servlet处理
 * @author 索隆
 *
 */
public class PermissionAction extends ActionSupport implements ModelDriver<Permission>{
	private Permission Permission=new Permission();
	private PermissionDao pdao=new PermissionDao();
	
	/**初始化书籍管理系统的动态树
	 * @param req
	 * @param resp
	 * @throws Exception
	 */
	public void listmenu(HttpServletRequest req, HttpServletResponse resp) throws Exception {
		//查询父子级数据
		List<TreeVo<Permission>> menu = pdao.menu();
		//将集合转换成json格式进行回显
		ResponseUtil.writeJson(resp, menu);
	}

	@Override
	public Permission getModel() {
		return Permission;
	}

}

No olvide escribir el archivo de configuración después de escribir el servlet

<?xml version="1.0" encoding="UTF-8"?>
<config>
	<action path="/blog" type="com.zking.web.BlogAction">
		<forward name="list" path="/blogList.jsp" redirect="false" />
		<forward name="toList" path="/blog.action?methodName=list"
			redirect="true" />
		<forward name="toEdit" path="/blogEdit.jsp" redirect="false" />
	</action>
	

	<!--用户-->
	<action path="/user" type="com.xw.web.Useraction">
	</action>

	<!-- 书籍管理——树 -->
	<action path="/Permission" type="com.xw.web.PermissionAction">
	</action>





</config>

5. construcción de página jsp

En este momento, podemos ir al sitio web en línea de Layui para encontrar una página jsp satisfactoria

Documentación de desarrollo y uso de Layui - Guía de inicio

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE>
<html>
<head>
<%@ include file="common/static.jsp"%>
<script type="text/javascript" src="js/index.js"></script>
</head>
<body>
	<div class="layui-layout layui-layout-admin">
		<div class="layui-header">
			<div class="layui-logo layui-hide-xs layui-bg-black">书籍管理系统</div>
			<!-- 头部区域(可配合layui 已有的水平导航) -->
			<ul class="layui-nav layui-layout-left">
				<!-- 移动端显示 -->
				<li class="layui-nav-item layui-show-xs-inline-block layui-hide-sm"
					lay-header-event="menuLeft"><i
					class="layui-icon layui-icon-spread-left"></i></li>
				<!-- Top导航栏 -->
				<li class="layui-nav-item layui-hide-xs"><a href="">nav 1</a></li>
				<li class="layui-nav-item layui-hide-xs"><a href="">nav 2</a></li>
				<li class="layui-nav-item layui-hide-xs"><a href="">nav 3</a></li>
				<li class="layui-nav-item"><a href="javascript:;">nav
						groups</a>
					<dl class="layui-nav-child">
						<dd>
							<a href="">menu 11</a>
						</dd>
						<dd>
							<a href="">menu 22</a>
						</dd>
						<dd>
							<a href="">menu 33</a>
						</dd>
					</dl></li>
			</ul>
			<!-- 个人头像及账号操作 -->
			<ul class="layui-nav layui-layout-right">
				<li class="layui-nav-item layui-hide layui-show-md-inline-block">
					<a href="javascript:;"> <img
						src="//tva1.sinaimg.cn/crop.0.0.118.118.180/5db11ff4gw1e77d3nqrv8j203b03cweg.jpg"
						class="layui-nav-img"> tester
				</a>
					<dl class="layui-nav-child">
						<dd>
							<a href="">Your Profile</a>
						</dd>
						<dd>
							<a href="">Settings</a>
						</dd>
						<dd>
							<a href="login.jsp">Sign out</a>
						</dd>
					</dl>
				</li>
				<li class="layui-nav-item" lay-header-event="menuRight" lay-unselect>
					<a href="javascript:;"> <i
						class="layui-icon layui-icon-more-vertical"></i>
				</a>
				</li>
			</ul>
		</div>

		<div class="layui-side layui-bg-black">
			<div class="layui-side-scroll">
				<!-- 左侧导航区域(可配合layui已有的垂直导航) -->
				<ul id="menu" class="layui-nav layui-nav-tree" lay-filter="menu">
					<!-- <li class="layui-nav-item layui-nav-itemed">
          <a class="" href="javascript:;">menu group 1</a>
          <dl class="layui-nav-child">
            <dd><a href="javascript:;">menu 1</a></dd>
            <dd><a href="javascript:;">menu 2</a></dd>
            <dd><a href="javascript:;">menu 3</a></dd>
            <dd><a href="">the links</a></dd>
          </dl>
        </li>
        <li class="layui-nav-item">
          <a href="javascript:;">menu group 2</a>
          <dl class="layui-nav-child">
            <dd><a href="javascript:;">list 1</a></dd>
            <dd><a href="javascript:;">list 2</a></dd>
            <dd><a href="">超链接</a></dd>
          </dl>
        </li>
        <li class="layui-nav-item"><a href="javascript:;">click menu item</a></li>
        <li class="layui-nav-item"><a href="">the links</a></li> -->
				</ul>
			</div>
		</div>

		<div class="layui-body">
			<!-- 内容主体区域 -->
			<div style="padding: 15px;">内容主体区域。记得修改 layui.css 和 js 的路径</div>
		</div>

		<div class="layui-footer">
			<!-- 底部固定区域 -->
			底部固定区域
		</div>
	</div>
	<script>
//JS 
layui.use(['element', 'layer', 'util'], function(){
  var element = layui.element
  ,layer = layui.layer
  ,util = layui.util
  ,$ = layui.$;
  

  	$.ajax({
  		url: "${pageContext.request.contextPath}/Permission.action?methodName=listmenu",
  		type: 'post',
  		dataType: 'json',
  		success: function(data) {
  			//定义一个变量将回显的数据进行拼接,最终追加到指定标签上
  			var str='';
  			$.each(data,function(i,n){
  				str+='<li class="layui-nav-item layui-nav-itemed">';
  				str+=' <a class="" href="javascript:;">'+n.text+'</a>';
  				//判断有无children节点有就遍历
  				if(n.hasChildren){
  					//有children节点拿到children节点
  					var children=n.children;
  						str+='<dl class="layui-nav-child">';
  					$.each(children,function(idx,node){
  						str+='<dd><a href="javascript:;">'+node.text+'</a></dd>';
  		  			})
  		  				str+='</dl>';
  				}
  				
  				str+='</li>';
  				
  			})
  			//将拼接内容追加到指定ul标签
  			$("#menu").html(str);
  			
  			element.render('menu');
  			
  		}
  	})
  
  
});
</script>
</body>
</html>

Consejos:

 La utilidad de element.render():

Supongamos que está utilizando una biblioteca o un marco de trabajo front-end específico, donde `elemento` es el componente u objeto correspondiente, llame al método `render()`. En términos generales, el método `render()` se utiliza para representar componentes o elementos en posiciones específicas de la página web. Las funciones específicas son las siguientes:

  • 1. Representación de componentes: el método `render()` se utiliza para representar componentes específicos en la página. Analizará el contenido y el estilo del componente para generar la estructura HTML correspondiente y hacerlo visible en el navegador.
  • 2. Actualice la página: si el componente o elemento ya existe y se muestra en la página, volver a llamar a `render()` puede desencadenar la actualización de la página. Esto es útil cuando necesita actualizar la página en función de los cambios en los datos.
  • 3. Vinculación de eventos: al renderizar un componente, el método `render()` suele vincular el evento del componente al elemento DOM correspondiente. Esto asegura que cuando el usuario interactúe con el componente, el componente responda apropiadamente.
  • Debe tenerse en cuenta que la implementación y el uso específicos del método `render()` dependen del marco o la biblioteca de front-end utilizados, y puede haber parámetros y opciones adicionales. Para comprender exactamente lo que hace el método `render()`, consulte la documentación y la guía de uso del marco o biblioteca correspondiente.

6. Presentación del caso

Mi intercambio está aquí, ¡bienvenido al área de comentarios para discutir y comunicarnos! !

Si lo encuentras útil, por favor dale me gusta, amor ♥ ♥

Supongo que te gusta

Origin blog.csdn.net/weixin_74318097/article/details/131677155
Recomendado
Clasificación