1 用户登录实现
1.1 用户数据存储
-1. 业务说明
根据登录需求,后台服务器返回SysResult对象,其中data表示 token的记录. 规则: 服务器返回的响应的数据应该采用一种特殊的方式进行保存.否则用户的数据将会丢失
{status: 200, msg: "服务器处理成功", data: "4edf7d1fbe2f4b14bc7227c85b4998b3"}
-2.Session
总结:
- Session 是会话控制
- Session可以用户存储数据
- Session生命周期整个会话 在会话期间数据有效, 如果会话窗口关闭 则数据清除.
- Session数据存储在浏览器的内存中(前端的)
-3.Cookie(了解)
特征:
- Cookie 是一个文本文件
- Cookie 存储的是用户信息 (加密数据 更加安全)
- Cookie 保存到用户的计算机终端中 可以临时/永久的存储信息.
手机银行的用户登录信息?? session 安全性要求较高 购物网站 要求用户七天免密登录?? 使用Cookie进行存储!! 公司的财务系统的登录信息? 建议使用Session 电影: 没有绝对安全的系统 总结: 如果对于数据安全性要求较高 则使用Session. 如果存储一些大量查询的数据(不重要的)一般采用Cookie进行保存.
-4.项目中数据存储
说明: 用户登录之后 将用户信息保存到Session中 login.vue 中的JS代码
if(result.status !== 200) return this.$message.error("用户登录失败")
this.$message.success("用户登陆成功")
//获取用户token信息
let token = result.data
//调用浏览器中的Session机制,存储信息
window.sessionStorage.setItem("token",token)
//用户登录成功之后,跳转到home页面
this.$router.push("/home")
浏览器中的Session 控制: 当会话关闭时,Session数据将会被清空 
2 系统首页跳转
2.1 系统首页跳转说明
-1.JS实现页面跳转
//用户登录成功之后,跳转到home页面
this.$router.push("/home")
2.编辑路由规则
router–index.js 
-3.效果展现

2.2 路由导航守卫
需求: 如果用户没有登录,则不允许访问其他的页面,只允许访问login登录页面. 实现:
- 前端实现: VUE中提供了路由导航守卫!!!
- 单点登录策略 第四阶段进行讲解
//配置路由对象
const router = new VueRouter({
routes
})
/*配置路由导航守卫router.beforeEach()
1.to 跳转到哪里
2.from 从哪里来
3.next 回调函数 放行,跳转
*/
router.beforeEach((to,from,next)=>{
//如果访问/login 请求应该放行, ===判断类型+数据
if(to.path === '/login') return next()
//校验是否登录, 检查是否有token
let token = window.sessionStorage.getItem('token')
if(token!==null && token.length>0) return next()
//没有token应该跳转到登录页面"/login"
return next("/login")
//将所有请求放行 next()
})
3. 左侧菜单获取
3.1项目介绍
-1 表设计说明
说明: 如果查询所有的一级菜单 则parent_id = 0 如果查询二级菜单信息 则parent_id = 1级菜单的ID 如果查询三级菜单信息 则parent_id= 2级菜单的ID 
-2. 编辑Rights的POJO
package com.jt.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.List;
/**
* @author 刘昱江
* 时间 2021/2/18
*/
@TableName("rights")//标识对象与表映射关系 必须编辑linux系统严格区分大小写
@Data
@Accessors(chain = true)
public class Rights extends BasePojo{
@TableId(type = IdType.AUTO)
private Integer id;
private String name;
private Integer parentId;
private String path;
private Integer level;
@TableField(exist = false)
private List<Rights> children; //不是表格固有属性
}
-3. 构建层级代码结构
编辑Mapper----Service-----Controller 层级代码 方便后续业务调用 
-4.RightsMapper
package com.jt.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.jt.pojo.Rights;
public interface RightsMapper extends BaseMapper<Rights> {
}
-5.RightsServiceImpl
package com.jt.service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jt.mapper.RightsMapper;
import com.jt.pojo.Rights;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class RightsServiceImpl implements RightsService {
@Autowired
private RightsMapper rightsMapper;
@Override
public List<Rights> getAll() {
return rightsMapper.selectList(null);
}
/**需求:查询2级菜单结构
*步骤:
* 1.查询一级菜单信息 parent_id = 0
* 2.查询二级菜单信息 parent_id = 一级菜单ID
* 3.将二级菜单封装到一级菜单中.
*查询方式:
* 1.利用java循环实现2级封装.
* 2.利用Mybatis的封装的方式实现查询 resultMap 自己练习
* @return
*/
@Override
public List<Rights> getRightsList() {
QueryWrapper queryWrapper = new QueryWrapper();
queryWrapper.eq("parent_id", 0);
List<Rights> oneList = rightsMapper.selectList(queryWrapper);
//分析:1级和2级有各自对应的关系,拿到当前的
for(Rights one : oneList){
//应该先清空原有条件
queryWrapper.clear();
//根据一级id 查询二级信息
queryWrapper.eq("parent_id",one.getId());
List<Rights> twoList = rightsMapper.selectList(queryWrapper);
//实现父子关系的封装
one.setChildren(twoList);
}
return oneList;
}
}
-6.RightsController层
@RestController
@CrossOrigin
@RequestMapping("/rights")
public class RightsController {
@Autowired
private RightsService rightsService;
//获取全部列表信息
@GetMapping("/getAll")
public List <Rights> getAll(){
return rightsService.getAll();
}
/**需求:查询2级菜单结构,并且封装为List集合
* URL: /rights/getRightsList
* 参数:
* 请求类型: get
* 返回值:SysResult对象(list集合)
*/
@GetMapping("/getRightsList")
public SysResult getRightList(){
List<Rights> rightsList = rightsService.getRightsList();
return SysResult.success(rightsList);
}
}
-7.端口号说明
8000端口: VUE UI vue客户端管理器所有占用的端口. 8080端口: jtadmin 脚手架项目启动时占用的端口号 8091端口: 后台SpringBoot业务系统的端口号
3.2.前端展现左侧菜单
Home.vue -JS代码
async getMenuList() {
const {data: result} = await this.$http.get('/rights/getRightsList')
if(result.status !== 200) return this.$message.error("左侧菜单查询失败")
this.menuList = result.data
},
-2 接口文档说明
说明: 左侧菜单需要获取2级菜单信息. 二级菜单封装到一级菜单的children属性中. 
-3.关于层级表设计的说明
案例: 有一个业务逻辑 父子关系有3级 问:表如何设计? 业务关系: 爷爷—父亲—儿子-----孙子------重孙子 想法1: 定义三张表 爷爷表(id)—父亲表(parent_id–爷爷)—儿子表(parent_id—父亲) 数据结构复杂!!! 不便于扩展!!!
想法2: 定义一张表(id-----parent_id) 要求: 每个ID都应该有自己的parent_id
总结: 如果有父子关系,则一遍采用parent_id的方式进行封装. 自关联的方式
3.3 左侧菜单的跳转说明
-1 .关于左侧菜单路径说明
说明: 用户点击2级菜单时,跳转的路径 是由数据表中的path字段进行控制 
-2 左侧菜单路由机制
1.定义路由占位符 在Home组件中 在中间定义了路由占位符.
<!-- 定义主页面结构-->
<el-main>
<!-- 定义路由展现页面-->
<router-view></router-view>
</el-main>
2.编辑路由机制 根据路由嵌套的规则,通过children属性 实现组件嵌套.
//引入指定的路由组件
import Login from '../components/Login.vue'
import ElementUI from '../components/ElementUI.vue'
import Home from '../components/Home.vue'
import User from '../components/user/user.vue'
import Item from '../components/items/Item.vue'
import ItCat from '../components/items/ItemCat.vue'
import Welcome from '../components/Welcome.vue'
//路由机制
Vue.use(VueRouter)
const routes = [
{path: '/', redirect: '/login'},
{path: '/login', component: Login},
//http://localhost:8080/
{path:'/elementUI', component: ElementUI},
//http://localhost:8080/
// redirect: '/welcome',当用户默认跳转到home时,应该默认展现 Welcome的组件 关键语法:重定向机制
{path: '/home', component: Home, redirect: '/welcome', children:[
{path: '/user', component: User},
{path: '/item', component: Item},
{path: '/itemCat', component: ItCat},
{path: '/welcome', component: Welcome}
]}
4 ElementUI 基本用法
<template>
<div>
<h1>elementUI 入门案例 方便大家后续学习</h1>
<!-- 1.面包屑导航
elementUI 提供的组件 Breadcrumb
BreadcrumbItem
2.引入组件 element.js import Vue.use
-->
<el-breadcrumb separator-class="el-icon-arrow-right">
<el-breadcrumb-item :to="{ path: '/elementUI' }">UI页面</el-breadcrumb-item>
<el-breadcrumb-item>ElementUI工具API</el-breadcrumb-item>
<el-breadcrumb-item>入门案例</el-breadcrumb-item>
</el-breadcrumb>
<!-- 2. 定义卡片视图 -->
<el-card class="box-card hwCard">
<!-- 4. 栅格: 将一行固定划分为24块 可以调整每块所占的大小 -->
<el-row gutter="15">
<el-col :span="8">
<!-- 3.引入input框 -->
<el-input placeholder="请输入内容" v-model="input3" class="input-with-select">
<el-button slot="append" icon="el-icon-search"></el-button>
</el-input>
</el-col>
<el-col :span="4">
<el-button type="primary" round @click="showDialog" >点击按钮</el-button>
</el-col>
</el-row>
<!-- 5.弹出框操作
title="弹出框的标题元素"
:visible.sync="dialogVisible" 控制弹出框是否展现 true/false
-->
<el-dialog
title="弹出框效果展现"
:visible.sync="dialogVisible"
width="70%">
<!-- 6.表单提交 ref="为表单定义一个ID"
model 是elementUI中特定的属性 负责绑定数据
-->
<el-form ref="form" :model="addUser" label-width="80px">
<el-form-item label="用户名">
<el-input v-model="addUser.username"></el-input>
</el-form-item>
<el-form-item label="密码">
<el-input v-model="addUser.password" type="password"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">取 消</el-button>
<el-button type="primary" @click="dialogVisible = false">确 定</el-button>
</span>
</el-dialog>
</el-card>
</div>
</template>
<script>
//对外声明 当前组件的属性export default 将组件交给VUE对象管理
export default {
data(){
return {
dialogVisible: false,
//form表单中的数据有多个所以采用对象
addUser: {
username: '',
password: ''
}
}
},
methods: {
//添加点击事件
showDialog(){
//点击展现弹出框???
this.dialogVisible = true
}
}
}
</script>
<style lang="less" scoped>
.hwCard {
width: 100%;
height: 500px;
}
</style>
|