实现效果
设计思路
- 面包屑导航区 breadcrumb
- 卡片区域 card table dialog switch
- 功能
- 获取数据
- 搜索
- 添加用户
- 编辑用户
- 删除用户
具体实现
展示user组件
- 在 components/user/ 创建 User.vue 组件
- 在 router/index.js 中 导入组件、定义 Home 子规则
- Menu 中的 default-active 属性保存左侧的激活状态
const router = new Router({
routes: [
{ path: '/', redirect: '/login' },
{ path: '/login', component: Login },
{
path: '/home',
component: Home,
redirect: '/welcome',
children: [
{ path: '/welcome', component: Welcome },
{ path: '/users', component: Users },
]
}
]
})
Home.vue
<el-menu background-color="#333744" text-color="#fff" active-text-color="#409eff"
unique-opened :collapse="isCollapse" :collapse-transition="false" router
:default-active="this.$route.path">
user组件布局结构
面包屑导航区
<template>
<div>
<!-- 面包屑导航区 -->
<el-breadcrumb separator-class="el-icon-arrow-right">
<el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
<el-breadcrumb-item>用户管理</el-breadcrumb-item>
<el-breadcrumb-item>用户列表</el-breadcrumb-item>
</el-breadcrumb>
.el-breadcrumb {
margin-bottom: 15px;
font-size: 15px;
}
卡片视图区
搜索框及功能实现
- el-input 带搜索框的input Layout布局来控制 span宽度 gutter间隙
- el-button 添加用户按钮
<!-- 卡片视图 -->
<el-card>
<!-- 文本与搜索框 -->
<el-row :gutter="20">
<el-col :span="9">
<el-input placeholder="请输入内容" v-model="queryInfo.query" clearable @clear="getUserList">
<el-button slot="append" icon="el-icon-search" @click="getUserList"></el-button>
</el-input>
</el-col>
<el-col :span="4">
<el-button type="primary" @click="addDialogVisible=true">添加用户</el-button>
</el-col>
</el-row>
- 将文本框和data中的数据做双向绑定,使用 v-model = “queryInfo.query” 绑定
- 为搜索按钮绑定事件,这样点击搜索的时候就可以调用获取用户数据的函数
- 优化,变成可清空的文本框,使用clearable属性即可得到一个可清空的输入框
- 绑定clear事件,点击❌后就可以获取所有的用户数据
获取用户数据
- 在 created 生命周期中发起请求
- 在 methods 中定义函数
- 在 data 中定义请求参数
created() {
this.getUserList();
},
methods: {
getUserList() {
this.$http.get("users", { params: this.queryInfo }).then((res) => {
if (res.data.meta.status == 200) {
this.userList = res.data.data.users;
console.log(this.userList);
this.total = res.data.data.total;
} else {
return this.$message.error("获取用户列表失败!");
}
});
},
return {
queryInfo: {
query: "",
pagenum: 1, // 当前页数
pagesize: 5, // 当前每页显示数据条数
},
userList: [],
total: 0,
渲染用户列表数据
使用el-table
- :data=“tableData” 表格渲染的数据源
- el-table-column 模板列
- prop=“date” 指定渲染的数据项
- label=“日期” 指定标题
- width=“180” 指定宽度
- stripe属性可以创建带斑马纹的表格,隔行变色
- border属性创建有竖直方向的边框的表格
- el-table-column type=“index” 添加索引列
<!-- 用户列表表格 -->
<el-table :data="userList"
stripe border style="width: 100%">
<el-table-column type="index"></el-table-column>
<el-table-column prop="username" label="用户名"> </el-table-column>
<el-table-column prop="mobile" label="手机号"> </el-table-column>
<el-table-column prop="email" label="邮箱"> </el-table-column>
<el-table-column prop="role_name" label="角色"> </el-table-column>
<el-table-column label="状态">
<template slot-scope="scope">
<el-switch v-model="scope.row.mg_state" @change="userStateChanged(scope.row)"></el-switch>
</template>
</el-table-column>
<el-table-column label="操作">
<template slot-scope="scope">
<el-button type="primary" icon="el-icon-edit" size="small" @click="showEditDialog(scope.row.id)"></el-button>
<el-button type="danger" icon="el-icon-delete" size="small" @click="removeUserById(scope.row.id)"></el-button>
<el-tooltip effect="dark" content="分配角色" placement="top-start" :enterable="false">
<el-button type="warning" icon="el-icon-setting" size="small"></el-button>
</el-tooltip>
</template>
</el-table-column>
</el-table>
状态列按需显示
- 作用域插槽接收scope,通过scope.row 获取当前列的数据,scope.row.mg_state就是状态属性
- 新版是 v-slot=“slot”
- el-switch渲染开关,v-model=“scope.row.mg_state” 用来进行数据的双向绑定
- 修改用户状态
- 监听用户状态的修改 change
- 调用接口将修改的信息保存到数据库 users/:uId/state/:type
- 操作失败时要把前端页面显示的状态重置为修改前的状态
<el-table-column label="状态">
<template slot-scope="scope">
<el-switch v-model="scope.row.mg_state" @change="userStateChanged(scope.row)"></el-switch>
</template>
</el-table-column>
userStateChanged(userinfo){
//监听switch开关状态的变化
console.log(userinfo);
this.$http.put(`users/${userinfo.id}/state/${userinfo.mg_state}`).then((res) => {
if (res.data.meta.status == 200) {
this.$message.success("修改用户状态成功!");
} else {
// 因为此时修改失败所以要把前端页面显示的状态重置为修改前的状态
userinfo.mg_state = !userinfo.mg_state
return this.$message.error("修改用户状态失败!");
}
});
},
操作列设计
- type=“primary” 改变颜色
- icon 指定图标
- size指定大小
- el-tooltip 设置文字提示
- enterable 设置鼠标是否可以进入插槽
<el-table-column label="操作">
<template slot-scope="scope">
<el-button type="primary" icon="el-icon-edit" size="small" @click="showEditDialog(scope.row.id)"></el-button>
<el-button type="danger" icon="el-icon-delete" size="small" @click="removeUserById(scope.row.id)"></el-button>
<el-tooltip effect="dark" content="分配角色" placement="top-start" :enterable="false">
<el-button type="warning" icon="el-icon-setting" size="small"></el-button>
</el-tooltip>
</template>
</el-table-column>
分页效果实现
- el-pagination 实现
- @size-change=“handleSizeChange” 监听pageSize的改变,也就是当前每页显示数据条数,然后将新的赋值给pagesize
- @current-change=“handleCurrentChangeD” 监听页码值改变的事件,也就是当前页数,然后将新的赋值给pagenum
- :current-page 当前页 绑定请求参数
- :page-sizes 可选择的每页显示条数
- :page-size 当前显示条数 绑定请求参数
- layout分页布局显示 总条数、选择条数器等等…
- :total 总条数 绑定data数据
<!-- 分页区域 -->
<el-pagination
align="center"
@size-change="handleSizeChange"
@current-change="handleCurrentChangeD"
:current-page="queryInfo.pagenum"
:page-size="queryInfo.pagesize"
:page-sizes="[1, 2, 5, 10]"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
>
</el-pagination>
return {
queryInfo: {
query: "",
pagenum: 1, // 当前页数
pagesize: 5, // 当前每页显示数据条数
},
// 监听pageSize的改变
handleSizeChange(newSize) {
this.queryInfo.pagesize = newSize;
this.getUserList()
},
// 监听页码值改变的事件
handleCurrentChangeD(newPage) {
this.queryInfo.pagenum = newPage;
this.getUserList()
},
添加用户对话框
- title 是对话框的标题提示
- :visible.sync 是对话框的属性绑定,控制对话框的显示与隐藏,需要绑定到布尔值中,在data中定义
- width 是对话框的宽度
- @close 是对话框的事件,是对话框关闭的回调
<!-- 添加用户对话框 -->
<el-dialog
title="添加用户"
:visible.sync="addDialogVisible"
width="50%"
@close="addDialogClose">
<el-form :model="addForm" :rules="addFormRules" ref="addFormRef" label-width="70px">
<el-form-item label="用户名" prop="username">
<el-input v-model="addForm.username"></el-input>
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input v-model="addForm.password"></el-input>
</el-form-item>
<el-form-item label="邮箱" prop="email">
<el-input v-model="addForm.email"></el-input>
</el-form-item>
<el-form-item label="手机" prop="mobile">
<el-input v-model="addForm.mobile"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="addDialogVisible = false">取 消</el-button>
<el-button type="primary" @click="addUser">确 定</el-button>
</span>
</el-dialog>
// 点击确定按钮,添加新用户
addUser() {
this.$refs.addFormRef.validate(valid => {
if (!valid) return
// 发起添加用户的请求
this.$http.post("users", this.addForm).then((res) => {
if (res.data.meta.status !== 201) {
return this.$message.error("添加用户失败!")
}
this.$message.success('添加用户成功!')
// 隐藏添加用户对话框
this.addDialogVisible = false;
// 重新获取用户列表数据
this.getUserList()
});
})
},
form表单组件在 博客中 form组件学习
修改用户、删除用户比较相似就不具体说了
弹框询问
MessageBox 弹框
- .then(() => { 是成功后的操作
- .catch(() => { 是失败后的操作
// 根据id删除用户
removeUserById(id) {
// 弹框询问是否删除
this.$confirm('此操作将永久删除该用户, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
// 发起删除用户的请求
this.$http.delete("users/" + id).then((res) => {
if (res.data.meta.status !== 200) {
return this.$message.error("删除用户失败!")
}
this.$message.success('删除用户成功!')
// 重新获取用户列表数据
this.getUserList()
});
}).catch(() => {
this.$message({
type: 'info',
message: '已取消删除'
});
});
}