- <!--spring的依赖-->
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-webmvc</artifactId>
- <version>5.2.15.RELEASE</version>
- </dependency>
- <!--mysql驱动-->
- <dependency>
- <groupId>mysql</groupId>
- <artifactId>mysql-connector-java</artifactId>
- <version>8.0.28</version>
- </dependency>
- <!--mybatis依赖-->
- <dependency>
- <groupId>org.mybatis</groupId>
- <artifactId>mybatis</artifactId>
- <version>3.5.6</version>
- </dependency>
-
- <!--spring和mybatis整合的依赖-->
- <dependency>
- <groupId>org.mybatis</groupId>
- <artifactId>mybatis-spring</artifactId>
- <version>2.0.6</version>
- </dependency>
-
- <!--spring的jdbc依赖-->
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-jdbc</artifactId>
- <version>5.2.15.RELEASE</version>
- </dependency>
-
- <dependency>
- <groupId>com.github.pagehelper</groupId>
- <artifactId>pagehelper</artifactId>
- <version>5.3.0</version>
- </dependency>
- <!--druid连接池: 连接池: C3P0 Druid BoneCP
- 连接池基本的思想是在系统初始化的时候,将数据库连接作为对象存储在内存中,
- 当用户需要访问数据库时,并非建立一个新的连接,而是从连接池中取出一个已建立的空闲连接对象。使用完毕后,用户也并非将连接关闭,而是将连接放回连接池中,
- 以供下一个请求访问使用。而连接的建立、断开都由连接池自身来管理。
- -->
- <dependency>
- <groupId>com.alibaba</groupId>
- <artifactId>druid</artifactId>
- <version>1.2.1</version>
- </dependency>
-
- <!--mybatis-generator-->
- <dependency>
- <groupId>org.mybatis.generator</groupId>
- <artifactId>mybatis-generator-core</artifactId>
- <version>1.4.0</version>
- </dependency>
-
- <!--jackson-->
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-databind</artifactId>
- <version>2.13.2.2</version>
- </dependency>
-
- <dependency>
- <groupId>javax.servlet</groupId>
- <artifactId>javax.servlet-api</artifactId>
- <version>4.0.1</version>
- </dependency>
-
- <dependency>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- <version>1.18.24</version>
- </dependency>
druid连接池: 其他连接池: C3P0 Druid BoneCP
连接池基本的思想是在系统初始化的时候,将数据库连接作为对象存储在内存中,
当用户需要访问数据库时,并非建立一个新的连接,而是从连接池中取出一个已建立的空闲连接对象。使用完毕后,用户也并非将连接关闭,而是将连接放回连接池中,
以供下一个请求访问使用。而连接的建立、断开都由连接池自身来管理。
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:context="http://www.springframework.org/schema/context"
- xmlns:mvc="http://www.springframework.org/schema/mvc"
- xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
-
- <!--包扫描-->
- <context:component-scan base-package="com.wzh"/>
- <!--开启注解驱动-->
- <mvc:annotation-driven/>
- <!--放行静态资源-->
- <mvc:default-servlet-handler/>
-
- <!--spring配置-->
- <bean id="DataSource" class="com.alibaba.druid.pool.DruidDataSource">
- <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
- <property name="url" value="jdbc:mysql://localhost:3306/permissions?serverTimezone=Asia/Shanghai"/>
- <property name="username" value="root"/>
- <property name="password" value="123456"/>
- <property name="maxWait" value="3000"/>
- <property name="maxActive" value="10"/>
- <property name="minIdle" value="5"/>
- <property name="initialSize" value="5"/>
- </bean>
- <!--拦截器-->
- <mvc:interceptors>
- <mvc:interceptor>
- <mvc:mapping path="/**"/>
- <mvc:exclude-mapping path="/css/**"/>
- <mvc:exclude-mapping path="/js/**"/>
- <mvc:exclude-mapping path="/imgs/**"/>
- <mvc:exclude-mapping path="/user/login"/>
- <bean class="com.wzh.interceptor.LoginInterceptor"/>
- </mvc:interceptor>
- </mvc:interceptors>
- <!--
- id的名称必须叫multipartResolver
- -->
- <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
- <!--这里的单位为字节10M*1024K*1024-->
- <property name="maxUploadSize" value="10485760"/>
- </bean>
- <!--sqlSessionFactory 整合mybatis-->
- <bean id="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
- <property name="dataSource" ref="DataSource"/>
- <!--设置mybatis映射文件得路径-->
- <property name="mapperLocations" value="classpath:mapper/*.xml"/>
- <!-- 配置分页插件 -->
- <property name="plugins">
- <array>
- <bean class="com.github.pagehelper.PageInterceptor"></bean>
- </array>
- </property>
- </bean>
-
-
- <!--为dao接口生成代理实现类-->
- <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
- <property name="sqlSessionFactoryBeanName" value="sessionFactory"/>
- <property name="basePackage" value="com.wzh.dao"/>
- </bean>
- </beans>
- <?xml version="1.0" encoding="UTF-8"?>
- <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
- version="4.0">
- <servlet>
- <servlet-name>dispatcherServlet</servlet-name>
- <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
- <init-param>
- <param-name>contextConfigLocation</param-name>
- <param-value>classpath:spring.xml</param-value>
- </init-param>
- <load-on-startup>1</load-on-startup>
- </servlet>
- <servlet-mapping>
- <servlet-name>dispatcherServlet</servlet-name>
- <url-pattern>/</url-pattern>
- </servlet-mapping>
- </web-app>
成品效果图:

选择自己合适的布局容器粘贴过来,我选择的是这个.

- <%@ page contentType="text/html;charset=UTF-8" language="java" %>
- <html>
- <head>
- <title>主页面</title>
- <link type="text/css" rel="stylesheet" href="/css/index.css"/>
- <script type="text/javascript" src="/js/vue.js"></script>
- <script type="text/javascript" src="/js/index.js"></script>
- <script type="text/javascript" src="/js/axios.min.js"></script>
- </head>
- <body>
- <div id="app">
- <el-container>
- <el-header>Header</el-header>
- <el-container>
- <el-aside width="200px">Aside</el-aside>
- <el-main>Main</el-main>
- </el-container>
- <el-footer>Footer</el-footer>
- </el-container>
- </div>
- </body>
- <script>
- var app=new Vue({
- el:"#app",
-
- });
- </script>
-
- <style>
- body,#app{
- margin: 0px;
- padding: 0px;
- font-size: 12px;
- }
- .el-header, .el-footer {
- background-color: #B3C0D1;
- color: #333;
- text-align: center;
- line-height: 60px;
- }
-
- .el-aside {
- background-color: #D3DCE6;
- color: #333;
- text-align: center;
- line-height: 600px;
- }
-
- .el-main {
- background-color: #E9EEF3;
- color: #333;
- text-align: center;
- line-height: 600px;
- }
-
- body > .el-container {
- margin-bottom: 40px;
- }
-
- .el-container:nth-child(5) .el-aside,
- .el-container:nth-child(6) .el-aside {
- line-height: 260px;
- }
-
- .el-container:nth-child(7) .el-aside {
- line-height: 320px;
- }
- </style>
- </html>

- <el-header>
- <span id="logo" style="display: inline-block;width: 50%;height: 100%;float: left" >
- <img src="/imgs/1.png" height="100%" >
- </span>
- <el-dropdown style="float:right;margin-top:10px" @command="handleCommand">
- <span class="el-dropdown-link">
- <el-avatar :src="Info.url"></el-avatar>
- </span>
- <el-dropdown-menu slot="dropdown">
- <el-dropdown-item command="Info">个人资料</el-dropdown-item>
- <el-dropdown-item command="logout">退出登录</el-dropdown-item>
- </el-dropdown-menu>
- </el-dropdown>
- </el-header>


退出功能-----移除session


- <el-aside width="200px">
- <el-menu
- default-active="2"
- class="el-menu-vertical-demo"
- background-color="#545c64"
- text-color="#fff"
- active-text-color="#ffd04b">
- <%--index要求为字符串类型--%>
- <el-submenu :index="menu.menuId+''" v-for="menu in leftMenus">
- <template slot="title">
- <i :class="menu.icon"></i>
- <span>{{menu.menuname}}</span>
- </template>
- <el-menu-item :index="second.menuId+''" v-for="second in menu.children" @click="onSubmit(second.href,second.menuname)">
- <i :class="second.icon"></i>
- <span slot="title">{{second.menuname}}</span>
- </el-menu-item>
- </el-submenu>
- </el-menu>
- </el-aside>
观察仔细的可以看到子菜单右侧多出一个像素的边框。
- .el-aside>.el-menu{
- border: none;
- }

controller:
- @RestController
- @RequestMapping("/menu")
- public class MenuController {
- @Autowired
- private IMenuService menuService;
-
- @RequestMapping("/leftMenus")
- public CommonResult leftMenus(){
- CommonResult commonResult = menuService.selectMenuByRoleId();
- return commonResult;
- }
-
- }
service:

获取当前登录者所拥有的左侧菜单,
- @Service
- public class MenuServiceImpl implements IMenuService {
- @Autowired
- private MenuMapper menuMapper;
-
- public CommonResult selectMenuByRoleId() {
- User user = (User) WebUtils.getSession().getAttribute("user");
- System.out.println(user.getRoleid());
- List<Menu> leftMenus = menuMapper.findLeftMenuByRoleId(user.getRoleid());
-
- //1.查询所有一级菜单
- List<Menu> firstMenus = new ArrayList<Menu>();
-
- for(Menu menu: leftMenus){
- if(menu.getPid()==0){
- firstMenus.add(menu);
- }
- }
-
- //2.查询所有一级菜单下的子菜单
- for(Menu f : firstMenus){
- List<Menu> children = new ArrayList<Menu>();
- for(Menu b : leftMenus){
- if(b.getPid().equals(f.getMenuId())){
- children.add(b);
- }
- }
- f.setChildren(children);
- }
- return new CommonResult(2000,"查询左侧菜单成功",firstMenus);
- }
-
- }
mapper:
- /**
- * 方法描述
- * 根据当前用户具有的角色查询对应的菜单信息
- * @param roleId
- * @return:
- */
- public List<Menu> findLeftMenuByRoleId(Integer roleId);
MenuMapper.xml:
- <!--根据当前用户具有的角色查询对应的菜单信息-->
- <select id="findLeftMenuByRoleId" resultMap="BaseResultMap">
- select <include refid="Base_Column_List"/> from tbl_menu m
- join tbl_rolemenu rm on m.menu_id = rm.menuId
- join tbl_user u on u.roleId = rm.roleId where u.roleId = #{roleId}
- </select>
1.引入elementui中tabs标签页
- <el-main>
- <!--标签页
- v-model:表示当前活跃的tab
- tab-remove:移除tab标签
- -->
- <el-tabs v-model="editableTabsValue" type="card" closable @tab-remove="removeTab">
- <el-tab-pane
- <%--v-for:循环所有的tab标签--%>
- v-for="(item, index) in editableTabs"
- :key="item.name"
- :label="item.title"
- :name="item.name"
- >
- <%--{{item.content}}--%>
- <iframe :src="item.url" frameborder="0" width="100%" height="100%"></iframe>
- </el-tab-pane>
- </el-tabs>
- </el-main>
左侧菜单添加点击事件

方法:
- onSubmit(url,name){
- this.addTab(url,name);
- },
- //添加tab标签的方法
- addTab(url,menuname){
- let newTabName = ++this.tabIndex+'';
- //判断是否存在该tab
- var isHaveTab = false;
-
- var tabs = this.editableTabs;
-
- //遍历所有的tab标签
- tabs.forEach((tab,index)=>{
- if(tab.title==menuname){
- isHaveTab=true;
- newTabName=tab.name;
- }
- })
- //往所有tab数组中添加新的tab标签
- if(isHaveTab==false){
- this.editableTabs.push({
- title:menuname,
- name:newTabName,
- url:url
- });
- }
- this.editableTabsValue = newTabName;
- },
- //移除标签页
- removeTab(targetName) {
- let tabs = this.editableTabs;
- let activeName = this.editableTabsValue;
- if (activeName === targetName) {
- tabs.forEach((tab, index) => {
- if (tab.name === targetName) {
- let nextTab = tabs[index + 1] || tabs[index - 1];
- if (nextTab) {
- activeName = nextTab.name;
- }
- }
- });
- }
- this.editableTabsValue = activeName;
- this.editableTabs = tabs.filter(tab => tab.name !== targetName);
- },