在上一章的request.js的里面添加更新用户信息:
import {httpServe} from '@/http/index.js'
/* 登录 */
export const loginPost = (path="",data={})=> httpServe({path:path,method:'post',data:data});
/* 必须以对象方式传递 */
/* 左侧菜单列表 */
export const menusGet = (path="",params={})=> httpServe({path,params});
/* 用户列表 */
export const usersGet = (path="",params={})=> httpServe({path,params});
/* 添加用户 */
export const addusersPost = (path="",data={})=> httpServe({path,method:'post',data});
/* 删除用户 */
export const usersDelete = (path="")=> httpServe({path,method:'delete'});
/* 更新用户信息 */
export const usersPut = (path="",data={})=> httpServe({path,method:'put',data});
在上一章UsersView.vue里添加修改删除功能:
<template>
<div class="users">
<el-row>
<el-input
v-model="queryName"
placeholder="搜索用户名"
@keyup.native.enter="search"
style="width: 200px"
></el-input>
<el-button
icon="el-icon-search"
circle
@click="search"
style="margin-left: 15px"
></el-button>
<el-button type="primary" round @click="drawer = true"
>添加用户</el-button
>
</el-row>
<!-- :wrapperClosable="false" 表示点击遮罩区域不关闭抽屉 true则可以 -->
<el-drawer
title="添加用户"
:visible.sync="drawer"
:direction="direction"
:wrapperClosable="false"
>
<add-users @addok="addok" />
</el-drawer>
<!-- el-table组件 需要给data属性动态传递一个数组对象tableData -->
<el-table :data="tableData">
<!-- el-table-column组件 表格中的数据 是数组对象tableData中的属性date所对应的值
比如 date属性的值对应的2016-05-02 -->
<!-- 表头标题 是由label属性来传递的 width属性是表示表头字段的宽度 不给宽度就自适应表格 -->
<el-table-column label="创建日期">
<template slot-scope="scope">
<div>{{ scope.row.create_time | getDate }}</div>
</template>
</el-table-column>
<el-table-column prop="email" label="电子邮箱"></el-table-column>
<el-table-column prop="mobile" label="手机号"></el-table-column>
<el-table-column prop="role_name" label="角色名称"></el-table-column>
<el-table-column prop="username" label="用户名"></el-table-column>
<!-- fixed="right" 固定操作在右侧 -->
<el-table-column fixed="right" label="操作" width="200">
<template slot-scope="scope">
<el-button type="text" size="small" @click="update(scope.row)"
>修改</el-button
>
<!-- 气泡确认框 -->
<el-popconfirm
confirm-button-text='好的'
cancel-button-text='不用了'
icon="el-icon-info"
icon-color="red"
title="确定删除用户吗?"
@confirm="del(scope.row)"
@cancel="popCancel"
>
<el-button type="text" size="small" slot="reference"
> 删除</el-button
>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<!-- :page-sizes="[5, 10, 15, 20] 这个是用来选择分页的条数的 -->
<!-- :page-size="5" 默认一页显示5条数据 -->
<!-- :total="400" 总条数 -->
<!-- layout="total, sizes, prev, pager, next, jumper" 管理分页展示的样式内容 -->
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="currentPage"
:page-sizes="[5, 10, 15, 20]"
:page-size="pagesize"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
>
</el-pagination>
<!-- 对话框表单 -->
<!-- title是对话框的标题 -->
<el-dialog title="修改用户信息" :visible.sync="dialogFormVisible">
<el-form :model="form">
<el-form-item label="电子邮箱" label-width="120px">
<!-- autocomplete="off" 关闭自动提示之前输入的内容 -->
<el-input v-model="form.email" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="手机号码" label-width="120px">
<el-input v-model="form.mobile" autocomplete="off"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false">取 消</el-button>
<el-button type="primary" @click="submit"
>确 定</el-button
>
</div>
</el-dialog>
</div>
</template>
<script>
import { usersGet , usersDelete, usersPut } from "@/http/request.js";
import AddUsers from "@/components/AddUsers.vue";
export default {
name: "UsersView",
components: {
AddUsers,
},
/* 当组件被激活的时候 , 可以为组件的菜单被点击到的时候触发*/
activated:function(){
console.log('我被点了');
},
/* 当离开组件的时候触发 */
deactivated:function(){
console.log('我离开了');
},
data() {
return {
/* 表格数据 */
tableData: [],
/* 抽屉打开方向从右到左 */
direction: "rtl",
/* 默认抽屉是关闭的 */
drawer: false,
/* 默认打开的是第一页的数据 */
currentPage: 1,
/* 一页默认展示5条 */
pagesize: 5,
/* 默认总条数是0 */
total: 0,
/* 搜索用户名 */
queryName:'',
/* 判断对话框是否打开 true 打开 false 关闭 */
dialogFormVisible: false,
/* 对话框表单中的内容 */
form:{
email:'',
phone:''
}
};
},
/* 局部的过滤器 */
// filters:{
// getDate(v){
// /* 生成当前时间戳的日期对象 */
// let oDate = new Date(v);
// return oDate.getFullYear()+'-'+(oDate.getMonth()+1)+'-'+oDate.getDate();
// }
// },
created() {
/* 一进入页面调用获取用户数据接口 */
this.getTableDate();
console.log(this.$route.meta.keepAlive);
},
methods: {
/* 气泡弹出框点击取消 */
popCancel(){
console.log('气泡弹出框点击取消');
},
/* 修改用户信息 */
update(row) {
/* 把表格一行的内容给到form表单 */
this.form = JSON.parse(JSON.stringify(row))/* 对象不能直接赋值需要深拷贝才能不互相影响 */
console.log(this.row);
/* 点击打开对话框 */
this.dialogFormVisible = true
},
/* 提交用户信息 */
async submit(){
/* 防止请求失败造成里面代码错误所以使用 try catch 捕获异常 */
try{
let res = await usersPut(`users/${this.form.id}`,{
id:this.form.id,
email:this.form.email,
mobile:this.form.mobile
})
let {meta} = res.data;
if(meta.status==200){
this.$message.success(meta.msg);
/* 修改信息成功后刷新表格数据 */
this.getTableDate()
/* 修改成功关闭对话框 */
this.dialogFormVisible = false
}else{
this.$message.error(meta.msg)
}
}catch(err){
this.$message.error(err)
}
},
/* 上面通过作用域插槽把点击的一行的数据已经传过来了 */
async del(row){
console.log(row.id);
try{
let {data:{meta:{msg,status}}} = await usersDelete('users/'+row.id)
if(status==200){
this.$message.success(msg)
/* 删除成功之后刷新列表 */
this.getTableDate()
}else{
this.$message.error(msg)
}
}catch(err){
this.$message.error(err)
}
},
/* 通过用户名搜索 */
search(){
console.log(this.queryName);
/* 点击搜索 因为queryName 的值通过v-model 已经被修改
所以直接调取接口获取数据 */
this.getTableDate()
},
/* 选择一页显示多少条数据 */
handleSizeChange(val) {
console.log(`每页 ${val} 条`);
/* 改变一页显示多少条 */
this.pagesize = val;
/* 重新获取数据渲染表格 */
this.getTableDate();
},
/* 点击具体页数、上一页和下一页以及输入页数 都会触发下面的函数 */
/* 选择当前的是第几页 */
handleCurrentChange(val) {
console.log(`当前页: ${val}`);
/* 改变当前是第几页 */
this.currentPage = val;
/* 重新获取数据渲染表格 */
this.getTableDate();
},
/* 当子组件添加数据成功的时候触发的方法 */
addok() {
/* 重新获取用户数据 */
this.getTableDate();
/* 关闭抽屉 */
setTimeout(() => {
this.drawer = false;
}, 600);
},
getTableDate() {
usersGet("users", {
/* 当前页 */
pagenum: this.currentPage,
/* 一页展示多少条 */
pagesize: this.pagesize,
/* 查询参数 空字符串是查询全部 通过用户名查询的*/
query:this.queryName
})
.then((res) => {
let { data, meta } = res.data;
/* 当状态为200表示数据获取成功 */
if (meta.status == 200) {
/* 把数据给到tableData数组中 */
this.tableData = data.users;
/* 把数据中总条数给到total */
this.total = data.total;
} else {
/* 如果获取数据有误,给出相应提示 */
this.$message.error(meta.msg);
}
})
.catch((err) => {
this.$message.error(err);
});
},
},
};
</script>
在上一章的IndexView.vue里面添加退出登录:
<template>
<el-container style="height: 100vh; border: 1px solid #eee">
<el-aside width="200px" style="background-color: rgb(238, 241, 246)">
<!-- :default-openeds="['1', '3']" 表示默认打开第一个和第三个菜单 -->
<!-- 1 对应了el-submenu index="1"
2 对应了el-submenu index="2" -->
<!-- el-submenu index="1-1 表示把el-submenu当作是第一个导航的第一个子项-->
<!-- :router="true 使用 vue-router 的模式,启用该模式会在激活导航时以 index 作为 path 进行路由跳转 -->
<!-- default-active="/index/users" -->
<!-- ★ :default-openeds 不可以直接使用['1'] 需要使用一个变量openList代替 因为值随时会变 如果写的
是['1'] 那么就永远不会改变 会出现点击二级菜单 一级菜单会缩起来的情况-->
<!-- default-active="/index/users" 表示一进入页面就默认激活/index/user导航菜单
default-active不能直接写死值路径要用变量代替 使用监听器 监听路由解决 -->
<!-- unique-opened 是否只保持一个子菜单的展开 boolean 默认是false-->
<el-menu
:default-openeds="openList"
:router="true"
:default-active="pagepath"
:unique-opened="true"
>
<!-- index接收的字符串类型,(i+1)是数字类型,所以使用toString方法转成字符串 传给index -->
<!-- 因为i是从0开始的 所以需要加1 -->
<el-submenu
:index="(i + 1).toString()"
v-for="(v, i) in navList"
:key="i"
>
<template slot="title"
><i class="el-icon-menu"></i>{{ v.authName }}</template
>
<!-- 子选项需要改成例如:1-1格式 以字符串的形式传给index属性 -->
<!-- 因为子选项也是一个数组所以需要再次循环 -->
<!-- :index="'/index/'+item.path" 路径最前面必须加上/ 否则会出现路径覆盖的问题 -->
<el-menu-item
:index="'/index/' + item.path"
v-for="(item, index) in v.children"
:key="index"
>{{ item.authName }}</el-menu-item
>
</el-submenu>
</el-menu>
</el-aside>
<el-container>
<el-header style="text-align: right; font-size: 12px">
<el-dropdown>
<i class="el-icon-setting" style="margin-right: 15px"></i>
<el-dropdown-menu slot="dropdown">
<!-- 因为是组件所以不支持原生的点击 需要加上.native修饰符来实现 -->
<el-dropdown-item @click.native="quit">退出登录</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<span>{{username}}</span>
</el-header>
<el-main>
<!-- 我们使用el-card组件实现页头和主体的布局 -->
<el-card class="box-card">
<div slot="header" class="clearfix">
<!-- fullPath: "/index/addusers?name=1" 会带上传递的参数 -->
<!-- path: "/index/addusers" 不会带上参数 是纯路径 -->
<!-- 使用面包屑导航实现导航 -->
<!-- separator="/" 表示用/来分隔 -->
<el-breadcrumb separator="/">
<el-breadcrumb-item :to="{ path: $route.path }">{{
$route.meta.title
}}</el-breadcrumb-item>
<el-breadcrumb-item>{{
$route.meta.subTitle
}}</el-breadcrumb-item>
</el-breadcrumb>
</div>
<keep-alive>
<!-- 需要缓存的视图组件 -->
<router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
<!-- 不需要缓存的视图组件 -->
<router-view v-if="!$route.meta.keepAlive"></router-view>
<!-- 在组件切换过程中将状态保留在内存中,防止重复渲染DOM
<keep-alive>
router-view 显示主页面内容
<router-view></router-view>
</keep-alive> -->
</el-card>
</el-main>
</el-container>
</el-container>
</template>
<script>
import { menusGet } from "@/http/request.js";
import createRoute from "@/minixs/createRoute.js";
export default {
mixins: [createRoute],
data() {
return {
navList: [],
openList: ["1"],
pagepath: "/index/users",
};
},
watch: {
/* 当路由发生变化的时候,就把最新的地址给到pagepath变量
作用是为了保持路由菜单栏的高亮显示 以及解决点击不跳转的bug */
$route: {
handler: function (newV) {
this.pagepath = newV.path;
},
immediate: true,
},
},
/* 动态路由添加的菜单 刷新页面的时候不走created 所以每次刷新
都不能添加动态路由,导致刷新白屏 */
created: function () {
this.getNavList();
},
computed:{
/* 不能在模板中使用 localStorage.username */
/* 因为不是VUE实例中的属性,所以需要借助计算属性来实现 */
username:function(){
return localStorage.username
}
},
methods: {
/* 推出登录 */
quit(){
/* 清除所有缓存 */
localStorage.clear();
/* 回到登录页 */
setTimeout(()=>{
this.$router.push({name:'login'})
},500)
},
getNavList: function () {
menusGet("menus")
.then((res) => {
let { data, meta } = res.data;
/* 数据获取成功 */
if (meta.status == 200) {
this.navList = data;
/* 动态添加路由菜单 */
/* 因为第一个路由是默认,所以我们从第二个路由开始动态添加 */
/* slice不会改变原数据 而splice会 */
localStorage.arrRoute = JSON.stringify(this.navList.slice(1));
/* 使用minixs中的添加动态路由的公共方法 */
this.createRouteFn();
} else {
/* 防止数据获取失败,给出相应的后台提示 */
this.$message.error(meta.msg);
}
})
.catch((err) => {
console.log(err);
});
},
},
};
</script>
<style scoped>
.el-header {
background-color: #b3c0d1;
color: #333;
line-height: 60px;
}
.el-aside {
color: #333;
}
</style>