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

目录

一、前言

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,rowsreturn 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);}@Overridepublic 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"><iclass="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:;">navgroups</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:;"> <imgsrc="//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:;"> <iclass="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.hqwc.cn/news/19925.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue el-table的每行操作el-button添加单独的loading效果实现

vue el-table的每行操作el-button添加单独的loading效果实现 效果图&#xff1a;实现代码&#xff1a;结语 效果图&#xff1a; 实现代码&#xff1a; <tamplate><el-table :data"list" ><el-table-column fixed"right" label"操作&q…

java方法的可变参数

Java方法的参数列表可以包含可变参数。可变参数其实就是相同类型的多个参数构成的数组。 可变参数是类型后面跟着省略号&#xff08;…&#xff09;&#xff0c;然后空格&#xff0c;然后跟可变参数的名称。当然&#xff0c;类型和省略号之间可以包含空格&#xff0c;但不建议这…

【Hello mysql】 mysql的约束

Mysql专栏&#xff1a;Mysql 本篇博客简介&#xff1a;介绍mysql的约束 mysql的约束 表的约束空属性默认值列描述zerofill主键自增长唯一键外键总结 表的约束 为什么要有约束&#xff1f; 我们在收集一些数据的时候会要求该数据必须存在 比如说像是国家在登记公民信息的时候身…

ESP32开发板引脚介绍【附有引脚使用实例】

ESP32开发板引脚介绍 文章目录 ESP32开发板引脚介绍&#x1f468;‍&#x1f3eb;内容1&#xff1a;背景&#x1f468;‍⚖️内容2&#xff1a;限制类引脚&#x1f468;‍&#x1f4bb;内容3&#xff1a;ESP32 周边设备&#x1f349;文末备注 &#x1f468;‍&#x1f3eb; &am…

webpack的打包流程

webpack的打包流程 yarn build 开始都走了哪些流程 yarn build 开始都走了哪些流程

ROS中bag的录制、播放和使用

文章目录 前言一、bag录制二、bag信息查看三、bag播放四、bag的使用&#xff08;以A-LOAM为例&#xff09; 前言 传感器获取到的信息&#xff0c;有时我们可能需要实时处理&#xff0c;有时可能只是采集数据&#xff0c;事后分析&#xff0c;比如: 机器人导航实现中&#xff0…

【雕爷学编程】Arduino动手做(138)---64位WS2812点阵屏模块5

37款传感器与执行器的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&am…

openssl源码编译输出库-guidance-傻瓜式教程

目标&#xff1a; 下载openssl源码 编译输出目标版本&#xff0c;例如使用Android NDK编译输出Android使用的32位的库 1、下载源码 git clone https://github.com/openssl/openssl.git -b openssl-3.0.9 2、 请下载Linux版本的Android NDK 请下载Linux版本的Android NDK, 并完…

CUDA11.1、cuDNN8.6.0、Tensorrt8.5.3,ubuntu20.04安装过程记录

CUD11.1 下载地址&#xff1a;CUDA Toolkit Archive | NVIDIA Developer 安装&#xff1a; wget https://developer.download.nvidia.com/compute/cuda/11.1.1/local_installers/cuda_11.1.1_455.32.00_linux.run sudo sh cuda_11.1.1_455.32.00_linux.run 对于不是sudo用户&…

46.声明类关键字 var new funcion let const

目录 1 var 2 new 3 function 4 let 4.1 let不能在同一作用域下重复声明 4.2 let无法进行变量提升 4.3 var的变量会跑出当前作用域&#xff0c;但是let不会 4.4 let与var的循环定时器问题 5 const 5.1 简单值 5.2 复杂值 1 var 使用var只能让函数内部使用…

融合ELO机制的销售能力评估方案

ELO排位赛算法 文章目录 ELO排位赛算法一. ELO机制二. 销售能力抽象为ELO排位赛设计2.1 基础设计2.2 存在问题 三. 优化措施3.1 如何解决新销售存在冷启动问题新老人动态K值调整假设检验衡量赢的程度 3.2 如何解决转化率存在不置信的问题ELO升级为MultiELO 一. ELO机制 ELO等级…

C语言结构体

一、结构体的定义&#xff1a; 结构体&#xff08;Struct&#xff09;是C语言中的一个重要数据类型&#xff0c;它可以用来存储多个不同类型的变量。结构体类似于一个自定义的数据类型&#xff0c;可以包含多个不同类型的成员变量&#xff0c;每个成员变量可以有自己的数据类型…