Layui实现动态树效果(书籍管理系统左侧下拉列表)

news2024/12/23 17:40:13

目录

一、前言

1.什么是树形菜单

2.树形菜单的使用场景

二、案例实现

1.需求分析

2.前期准备工作

①导入依赖

②工具类

BaseDao(通用增删改查)

BuildTree(完成平级数据到父子级的转换)

ResponseUtil(将数据转换成json格式进行回显)

③编写实体

3.dao层编写

4.servlet层编写

5.jsp页面搭建

6.案例演示


一、前言

在完成案例之前我们先来了解一下什么是树形菜单

1.什么是树形菜单

        树形菜单是一种用户界面设计模式,常用于组织和展示大量信息的层次结构。它的名称来自于菜单呈现的结构类似于树的分支和节点。树形菜单通常由主节点和多个子节点组成,每个子节点可以有自己的子节点,形成了父子关系的层级结构

        在树形菜单中,主节点代表顶级选项或类别,而子节点代表与主节点相关联的具体选项或子类别。用户可以通过展开或折叠子节点来浏览更详细的层级。通常,叶子节点是最底层的节点,表示最具体的选项或内容。

        树形菜单适用于需要组织和展示复杂数据或多级目录的应用程序和网站。它们使用户可以方便地导航和选择所需的选项,提供了一种简洁而直观的方式来浏览和访问信息。

2.树形菜单的使用场景

树形菜单在各种应用和网站中被广泛使用,以下是一些常见的使用场景:

  • 1. 文件资源管理:树形菜单可用于浏览和管理文件资源,特别是当文件被组织成多级目录结构时。用户可以展开和折叠目录以访问所需的文件或文件夹。
  • 2. 组织结构和人员管理:企业或组织的组织结构可以通过树形菜单进行可视化展示。每个节点代表一个部门、团队或个人,用户可以通过展开节点查看更详细的层级和信息。
  • 3. 导航菜单:网站或应用程序的主要导航菜单常常使用树形结构,以显示不同的页面或功能选项。用户可以根据需要展开或折叠菜单项,快速定位所需的功能或内容。
  • 4. 产品分类和目录导航:在线商店或电子商务网站通常使用树形菜单来组织产品分类和目录。用户可以通过展开和折叠不同的类别来浏览和选择产品。
  • 5. 内容管理系统:树形菜单在内容管理系统中被广泛使用,用于组织和管理网站的页面、文章、类别和标签等内容。

总而言之,树形菜单适用于任何需要展示和组织层次结构数据的场景,以提供清晰且易于导航的用户界面。

二、案例实现

1.需求分析

我们要完成一个书籍管理系统的左侧列表展示,必不可少的就是表的设计,表设计关乎到我们jsp页面的展示,下面是我的表设计仅供大家参考

表设计有了数据也必不可少,当然表数据也不要随便编写,不然可能会出错哦!!

        这里的数据都是有讲究的,我们平常通过dao层拿到的数据都是平级数据,并不符合我们的要求,我们所需要的是有父子级别的数据,那么怎么从平级数据转换成我们的父子级数据呢?? 这时候我们的表设计就起到了至关重要的作用,我们可以看到父级节点的pid都是0,而他们的子节点的pid对应的都是父级节点的id。

        得出结论我们只需要两个方法,一个查询全部的方法(拿到平级数据),另一个将平级数据进行两次for遍历加到新集合(父子级容器)的方法,第一次for将pid编号是顶级节点也就是父节点的数据加入容器中,第二次遍历将pid与新集合里面的id做比较,如果相同那就是新集合里的children。

 

2.前期准备工作

注意:更多细节在我所编写的自定义MVC三部曲中。

①导入依赖

将我们所需的依赖导入到WebContent➡WEB-INF下

创建一个存放js/css的目录将所需文件放入

将多个页面共用的文件封装成公共文件

<%@ 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>

②工具类

这里我们需要用到工具类

BaseDao(通用增删改查)

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(完成平级数据到父子级的转换)

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(将数据转换成json格式进行回显)

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));
	}
}

③编写实体

Permission(数据表实体)

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 + "]";
}



}

注意:mysql里面的类型bigint在java中是long类型

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));
		
		
	}
}

​

我们可以进行对比两组数据的不同之处:

  • 平级数据
  • 父子级数据

4.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;
	}

}

编写完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.jsp页面搭建

这时候我们就可以去在线Layui网站找一个满意的jsp页面了

Layui 开发使用文档 - 入门指南

<%@ 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>

小贴士:

 element.render()的用处:

假设你正在使用某个具体的前端框架或库,其中的`element`是对应的组件或对象,调用`render()`方法。一般而言,`render()`方法用于将组件或元素渲染到网页中的具体位置。具体作用如下:

  • 1. 渲染组件:`render()`方法用于将特定的组件渲染到页面上。它会将组件的内容和样式解析生成对应的 HTML 结构,并使其在浏览器中可见。
  • 2. 更新页面:如果已经存在该组件或元素并在页面上显示,再次调用`render()`可以触发页面的更新。这在需要根据数据的变化进行页面更新时很有用。
  • 3. 绑定事件:在渲染组件时,`render()`方法通常会将组件的事件绑定到相应的 DOM 元素上。这样可以确保用户与组件进行交互时,组件能够响应相应的操作。
  • 需要注意的是,`render()`方法的具体实现和用法取决于所使用的前端框架或库,可能会有额外的参数和选项。要确切了解`render()`方法的作用,请参考相应框架或库的文档和使用指南。

6.案例演示

到这里我的分享就结束了,欢迎到评论区探讨交流!!

如果觉得有用的话还请点个赞吧爱心 ♥  ♥

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/744801.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

1、Kubernetes 概述和架构

目录 一、基本介绍 二、kubernetes功能和架构 2.1、 概述 2.2 、功能 &#xff08;1&#xff09;自动装箱 &#xff08;2&#xff09;自我修复(自愈能力) &#xff08;3&#xff09;水平扩展 &#xff08;4&#xff09;服务发现 &#xff08;5&#xff09;滚动更新 &a…

磷铁环压脱机液压站比例阀放大器

冷轧热镀锌线液压系统比例阀放大器 热轧带钢步进梁式加热炉液压系统比例阀放大器 热轧带钢液压系统比例阀放大器 板坏连铸液压系统比例阀放大器 钢包精炼炉液压系统比例阀放大器 磷铁环压脱机液压站比例阀放大器 热轧带钢液压系统是一种用于热轧带钢生产的液压系统。它的…

校招失败后,在小公司熬了 2 年终于进了华为,竭尽全力....

其实两年前校招的时候就往华为投了一次简历&#xff0c;结果很明显凉了&#xff0c;随后这个理想就被暂时放下了&#xff0c;但是这个种子一直埋在心里这两年除了工作以外&#xff0c;也会坚持写博客&#xff0c;也因此结识了很多优秀的小伙伴&#xff0c;从他们身上学到了特别…

LiveGBS流媒体平台GB/T28181功能-支持UDP、TCP被动、TCP主动模式流传输模式之间有什么区别?

LiveGBS流媒体平台-国标流媒体服务几种流传输模式UDP、TCP被动、TCP主动模式区别是什么 1、背景1、GB28181流传输模式1.1、UDP1.2、TCP 被动1.3、TCP 主动 2、切换流传输模式2.1、编辑2.2、下拉切换 3、搭建GB28181视频直播平台 1、背景 国标GB28181协议中&#xff0c;视频流到…

什么是人工智能中的数据标注?

人工智能数据标注是对文本、视频、图像等元数据进行标注的过程&#xff0c;标记好的数据将用于训练机器学习的模型。常见的数据标注类型有文本标注、语义分割和图像视频标注。这些经标注的训练数据集可用于训练自动驾驶、聊天机器人、翻译系统、智能客服和搜索引擎等人工智能应…

LeetCode[239]滑动窗口最大值

难度&#xff1a;Hard 题目&#xff1a; 给你一个整数数组 nums&#xff0c;有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。 返回 滑动窗口中的最大值 。 示例 1&#xff1a; 输入&#xf…

强化学习课程笔记一

强化学习基础概念及MDP算法&#xff0c;如图1所示 这张ppt上就展现了一节课全部的内容&#xff1a; Sets中有表示状态的S、有表示动作的A(s)、有表示奖励的R(s,a)&#xff0c;如图二所示 也介绍了概率分布&#xff08;Probability distribution&#xff09; 其中State transi…

2D组态:智慧生物质发电厂组态监控系统

进入21世纪以来&#xff0c;我国面临的能源安全和环境生态保护问题日趋严峻&#xff0c;可再生能源已经成为能源发展战略的重要组成部分以及能源转型的重要发展方向。根据可再生能源应用的不同领域&#xff0c;电力系统建设正在发生结构性转变&#xff0c;可再生能源发电已开始…

【技能实训】DMS数据挖掘项目-Day06

文章目录 任务6【任务6.5】编写物流数据分析类【任务6.6】创建物流数据分析测试类&#xff0c;测试任务6.5-6.6中的程序&#xff0c;演示物流信息的采集、分析及打印输出 任务6 【任务6.1】创建数据分析接口 在com.qst.dms.gather 下创建接口IDataAnalyse.java 【任务6.2】创…

【多线程进阶】多线程进阶学习(高并发、线程池、多线程使用场景)

文章目录 1、线程基础知识1.1、线程和进程线程和进程的区别&#xff1f; 1.2、并行与并发并行与并发有什么区别&#xff1f; 1.3、线程的创建方式创建线程的方式有哪些&#xff1f;刚才你说过&#xff0c;使用runnable和callable都可以创建线程&#xff0c;它们有什么区别呢&am…

MySQL数值

1.整数类型 TINYINT&#xff1a;非常小的整数&#xff0c;存储空间为1字节&#xff0c; 取值范围&#xff1a;有符号&#xff1a;-128---127&#xff0c;无符号&#xff1a;0---255 SMALLINT&#xff1a;小整数&#xff0c;存储空间为2字节 取值范围&#xff1a;有符号&#…

岩土工程振动在线监测:以道路桥梁基础为例

岩土工程振动在线监测&#xff1a;以道路桥梁基础为例 使用振弦传感器、采集仪和在线监测系统进行岩土工程监测&#xff1a;以道路桥梁基础振动监测为例 一个应用振弦传感器、振弦采集仪和在线监测系统构成的岩土工程监测案例是道路桥梁基础的振动监测。 在道路桥梁基础的振动…

力扣 455. 分发饼干

题目来源&#xff1a;https://leetcode.cn/problems/assign-cookies/description/ C题解1&#xff1a;将大饼干优先大胃口的孩子。 class Solution { public:int findContentChildren(vector<int>& g, vector<int>& s) {sort(g.begin(), g.end());sort(s.…

代码随想录二刷 day50 | 动态规划 之 123.买卖股票的最佳时机III 188.买卖股票的最佳时机IV

day50 123.买卖股票的最佳时机III1.确定dp数组以及下标的含义2.确定递推公式3.dp数组如何初始化4.确定遍历顺序5.举例推导dp数组 188.买卖股票的最佳时机IV1.确定dp数组以及下标的含义2.确定递推公式4.dp数组如何初始化4.确定遍历顺序5.举例推导dp数组 123.买卖股票的最佳时机I…

java.lang.UnsatisfiedLinkError: no opencv_java410 in java.library.path

-Djava.library.pathhome/zwf/eclipse-workspace/DIPS_YTPC/lib/opencv-410/x64/

Element el-table 列表自定义样式

效果图 页面代码块 <el-tableref"multipleTable":data"tableData"tooltip-effect"dark"style"width: 100%"selection-change"handleSelectionChange"><el-table-columntype"selection"width"55&qu…

设计模式【行为型】-- 模板方法模式

模板方法模式&#xff08;Template method pattern&#xff09; 模板方法模式是一种行为型设计模式&#xff0c;它定义了一个操作中的算法骨架&#xff0c;将一些步骤的具体实现延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下&#xff0c;重新定义算法中的某些步…

hydra详解(仅供学习参考)

一、概述。 Hydra是一款非常强大的渗透工具&#xff0c;由著名的黑客组织THC开发的一款开源工具。 二、使用方法。 hybra基础语法&#xff1a; hydra 参数 IP 服务 参数&#xff1a; -l login 小写&#xff0c;指定用户名进行破解 -L file 大写&#xff0c;指定用户的用户名…

uniapp uni实人认证

uni实人认证依赖 目前仅支持App平台。 h5端活体人脸检测&#xff0c;使用的是百度云的h5人脸实名认证 使用要求 1、app端 在使用前&#xff0c;请确保您已注册DCloud账号&#xff0c;并已完成实名认证。 然后需要按文档开通服务 业务开通 | uni-app官网 2、h5端 在使用前…

工程系统管理 工程项目管理系统源码 工程项目各模块及其功能点清单

工程项目各模块及其功能点清单 一、系统管理 1、数据字典&#xff1a;实现对数据字典标签的增删改查操作 2、编码管理&#xff1a;实现对系统编码的增删改查操作 3、用户管理&#xff1a;管理和查看用户角色 4、菜单管理&#xff1a;实现对系统菜单的增删改查操…