VUE项目-第二天
01-反馈
姓名 意见或建议
*** 1.从谏如流而不是在每次看到反馈意见之后先推脱,再勉强接受,大家写出来的建议只是为了更方便快速的学习,别无他意(更不涉及怪不怪谁的问); 2.保证笔记的完整性和条理性应该算是最基本要完成的工作,在互动性比较高的工作中应该多考虑怎么利他; 3.待续
*** 单页面应用开发可以移动端吗???单页面主要做些什么项目啊??
*** 刚哥
*** 老师,为什么会出现莫名其妙丢包的情况呢
*** 老师, 爱你 么么哒
*** 希望老师注释能够更详细些~
02-回顾
- element-ui
- 基于vue的UI框架
- Vue.use(ElementUI,{全局配置})
- token原理
- 知识点:session持久化 express-mysql-session 中间件
- 用户登录:服务端 内存存储 key--用户信息 , 通过加密的方式把这个key加密后返回给客户端,响应主体
- 客户端:把 主体数据中的 token 信息保存,使用sessionStorage保存
- 需要在请求头中携带token信息
- 导航守卫
- vue-router 提供 在跳转路由器前 干些事情
- 判断是否登录(sessionStorage是否存token) 如果登录放行 如果没登录 拦截login
- 情况:后台可能去清除时间过久的token,无效token证明你的登录过期
- axios拦截器
- 需求:所有的响应成功后 做判断token是否失效 服务器才知道token是否失效 status:401
- axios.interceptors.response.use()
- 需要 : 在请求头中携带token信息
- axios.interceptors.requset.use()
03-首页-动态导航菜单
视图区:
<!--一级菜单-->
<!-- 注意: 一级菜单 index 和 二级菜单 index 是有从属关系的 -->
<!-- 一级菜单的索引 id 二级菜单的索引 item.id-lastItem.id -->
<el-submenu :index="item.id" v-for="(item,i) in menus" :key="item.id">
<template slot="title">
<i class="el-icon-location"></i>
<span>{{item.authName}}</span>
</template>
<!--二级菜单-->
<el-menu-item :index="item.id+'-'+lastItem.id" v-for="lastItem in item.children" :key="lastItem.id">
{{lastItem.authName}}
</el-menu-item>
</el-submenu>
js区域:
async getData () {
// 获取数据
const {data: {data, meta}} = await this.$http.get('menus')
// 判断获取是否成功 注意:添加操作 201 其他操作 200
if (meta.status !== 200) return this.$message.error('获取菜单失败')
// 已经成功 修改data中的菜单数据
this.menus = data
// 更新视图 前提是视图用了该数据
// 去视图 用户指令 渲染出来
}
04-首页-导航菜单细节
- 子菜单 没有图标 用方块图标 固定
-
<i class="el-icon-menu"></i> <span>{{lastItem.authName}}</span>
-
-
父菜单 没有图标 用五个不同的图标
<span class="iconfont icon-user-fill"></span> <span class="iconfont icon-cog"></span> <span class="iconfont icon-shoppingcart"></span> <span class="iconfont icon-file"></span> <span class="iconfont icon-chart-area"></span>- html
- js iconArr: ['icon-user-fill', 'icon-cog', 'icon-shoppingcart', 'icon-file', 'icon-chart-area']
- 打开子菜单时 允许只打开一个 其他关闭
- unique-opened 可以设置为 true 即可
- 由于权限问题 点击菜单的时候按照后台给的路径跳转
- 根据子菜单的 path: "users" 字段跳转
- router 属性可以开启 跳转模式
- el-submenu :index="item.id.toString()"
- el-menu-item :index="lastItem.path"
- 当你f5刷新页面 丢失当前选中的菜单
- 稍后实现
05-首页-欢迎组件
路由:
// 二级路由配置 将会在home组件下使用
children: [
{path: '/welcome', name: 'welcome', component: Welcome}
]
组件:
<template>
<div class="welcome_container">
<h3>欢迎来到品优购后台关系系统</h3>
<img src="../assets/images/welcome.jpg" alt="">
</div>
</template>
<script>
export default {
name: 'Welcome'
}
</script>
<style scoped>
.welcome_container{
text-align: center;
}
</style>
指定视图显示的位置:
<el-main class="home_main">
<router-view></router-view>
</el-main>
当你到首页时 默认显示的是欢迎组件
redirect: '/welcome',
为了演示 实现退出
// Home.vue
logout () {
// 思考: 清除token 就是退出 但是跳转登录页
sessionStorage.removeItem('token')
this.$router.push('/login')
}
06-用户管理-路由和组件骨架
配置路由:
{path: '/users', name: 'users', component: Users}
组件骨架:
<template>
<div class="users_container">
用户列表
</div>
</template>
<script>
export default {
name: 'Users'
}
</script>
<style scoped>
</style>
新建分支切切换: git checkout -b users
07-用户管理-用户列表
- 面包屑 首页 用户管理 用户列表
- 卡片 添加用户
- 表格参照文档中的模版 动态渲染
- 获取数据 : userList
- 发现接口传参:reqParams
- get请求怎么传参:get('url',{params:{具体参数}})
- 渲染表格:el-table-column 属性 prop 的值指定为 列表数据的每一项的字段即可
- 发现:有不是显示字段对应的值的列 有些列的内容需要自定义
- 自定义列
- 实现分页
<el-pagination @current-change="changePager" :page-size="reqParams.pagesize" :current-page="reqParams.pagenum" background layout="prev, pager, next" :total="total">
分页js功能 changePager (newPage) { // 进行分页查询 需求:当前页码 // 获取数据 前 要使用当前页码 this.reqParams.pagenum = newPage this.getData() } - 搜索功能 <el-button @click="search()" slot="append" icon="el-icon-search"> 查询 search () { // 根据当前搜索关键字 去查询第一页的数据 this.reqParams.pagenum = 1 this.getData() }
08-用户管理-用户添加
-
分析dialog组件的结构,修改成我们需要的结构
-
点击添加 显示对话框
<el-button type="primary" @click="dialogFormVisible = true" plain>添加用户
-
指定数据
// 标识当前对话框是否显示 dialogFormVisible: false, // 添加用户表单对象数据 addForm: { username: '', password: '', email: '', mobile: '' }
-
校验表单
- 自定义校验规则 //1. 定义校验函数 必须在定义数据之前 const checkMobile = (rule, value, callback) => { // rule 规则信息 value 验证的输入框的值 callback回调函数 (成功 失败) // 1开头 3456789 后面9数字 // callback回调函数 (成功 不传任何 失败 传失败信息 错误对象) if (!/^1[3456789]\d{9}$/.test(value)) return callback(new Error('手机号不对')) callback() } // 2. 在rules 校验数据中指定 校验函数 mobile: [ {required: true, message: '手机号必填', trigger: 'blur'}, // 手机号必须自定义校验规则 通过自己的函数来校验 (rule,value,callback) {validator: checkMobile, trigger: 'blur'} ]
-
提交数据 addSubmit () { // 输入的时候进行数据的验证 // 请求前点击提交的时候 还要验证一次 this.
http.post('users', this.addForm) if (meta.status !== 201) return this.$message.error('添加失败') // 添加成功后 this.dialogFormVisible = false // 更新列表 this.getData() } }) },
-
添加表单的细节
showDialogForm () { // 注意: 只有先渲染 找到dom // 显示添加对话框 this.dialogFormVisible = true // 重置表单 内容 验证 this.$refs.addForm.resetFields() }
09-用户管理-用户删除
改列表的按钮这一列 改成可以传数据的
<template slot-scope="scope">
<el-button-group>
<el-button icon="el-icon-edit" round></el-button>
<el-button icon="el-icon-delete" @click="delUsers(scope.row.id)" round></el-button>
<el-button icon="el-icon-setting" round></el-button>
</el-button-group>
</template>
定义一个删除函数
delUsers (id) {
// 删除用户 ID
this.$confirm('是否删除该数据?', '温馨提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(async () => {
// 点击了确认 发请求
const {data: {meta}} = await this.$http.delete(`users/${id}`)
if (meta.status !== 200) return this.$message.error('删除失败')
this.$message.success('删除成功')
this.getData()
}).catch(() => {})
}
10-用户管理-用户编辑
- 和添加功能99%相似
11-用户管理-修改状态
绑定值修改事件 change
<el-switch
@change="updateState(scope.row.id,scope.row.mg_state)"
v-model="scope.row.mg_state"
active-color="#13ce66"
inactive-color="#ccc">
</el-switch>
请求后台
async updateState (id, newState) {
// id 用户的ID newState 已改变的状态
// console.log(id, newState)
const {data: {meta}} = await this.$http.put(`users/${id}/state/${newState}`)
if (meta.status !== 200) return this.$message.error('修改状态失败')
this.$message.success('修改状态成功')
this.getData()
}
12-用户管理-分配角色
第一步:画分配角色的对话框
<!--分配角色-->
<el-dialog width="400px" title="分配角色" :visible.sync="roleDialogFormVisible">
<el-form label-width="100px" autocomplete="off">
<el-form-item label="当前用户:">
admin
</el-form-item>
<el-form-item label="当前用户:">
超级管理员
</el-form-item>
<el-form-item label="分配角色:">
<el-select v-model="roleValue" placeholder="请选择">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false">取 消</el-button>
<el-button type="primary" @click="addSubmit()">确 定</el-button>
</div>
</el-dialog>
第二步:动态渲染下拉框 角色
<el-select v-model="roleValue" placeholder="请选择">
<el-option
v-for="item in options"
:key="item.id"
:label="item.roleName"
:value="item.id">
</el-option>
</el-select>
数据:
async showRoleDialogFormVisible () {
// 打开对话框
this.roleDialogFormVisible = true
// 渲染下拉菜单
const {data: {data, meta}} = await this.$http.get('roles')
if (meta.status !== 200) return this.$message.error('获取角色失败')
this.options = data
console.log(data)
}
第三步:获取当前用户的信息在对话框显示
<el-form-item label="当前用户:">
{{roleUserName}}
</el-form-item>
<el-form-item label="当前用户:">
{{roleUserRoleName}}
// 当前用户的 用户名
roleUserName: '',
// 当前用户的 角色
roleUserRoleName: '',
this.roleUserName = row.username
this.roleUserRoleName = row.role_name
第四步:提交角色
<el-button type="primary" @click="changeRole()">确 定</el-button>
async changeRole () {
const {data: {meta}} = await this.$http.put(`users/${this.roleUserId}/role`, {
rid: this.roleValue
})
if (meta.status !== 200) return this.$message.error('分配角色失败')
this.$message.success('分配角色成功')
this.roleDialogFormVisible = false
this.getData()
}