用户列表页实现
1.完成user组件静态布局
页面结构:组件盒子内分五部分,顶级面包屑(全局组件)+ 操作框 + 用户数据列表 + 底部的分页 + 用户增删改弹框(后面写动态交互再添加),都用el-row(饿了吗Layout 布局)包裹
Ⅰ.顶级面包屑的实现:参照前两章
Ⅱ.操纵框:
饿了吗组件 复合型输入框传送们http://element-cn.eleme.io/#/zh-CN/component/input
button按钮 传送门http://element-cn.eleme.io/#/zh-CN/component/button
Ⅲ.用户数据列表:
饿了吗组件 Table表格(固定列表格) 传送门http://element-cn.eleme.io/#/zh-CN/component/table
Switch 开关传送门http://element-cn.eleme.io/#/zh-CN/component/switch
Ⅳ.底部的分页:
饿了吗组件 Pagination 分页(完整功能)传送门http://element-cn.eleme.io/#/zh-CN/component/pagination
示例代码
<template>
<div id="user">
<!-- 顶级面包屑 -->
<el-row>
<el-col :span="24">
<breadcrumb :level2="level2" :level3="level3"></breadcrumb>
</el-col>
</el-row>
<!-- 操纵框 -->
<el-row class="operate">
<el-col :span="4">
<!-- 输入的内容最终是放在搜索里面 -->
<el-input placeholder="请输入内容" v-model="pageData.query">
<template slot="append">
<i class="el-icon-search"></i>
</template>
</el-input>
</el-col>
<el-col :span="20">
<el-button type="success" plain>添加用户</el-button>
</el-col>
</el-row>
<!-- 用户数据 -->
<el-row>
<el-col :sapn="24">
<el-table :data="userList" style="width: 100%" border>
<!-- 返回的数据没有对应的属性名,把prop删掉 -->
<!-- 增加type="index",会设置排序 -->
<el-table-column label="#" width="30" type="index"></el-table-column>
<el-table-column prop="username" label="姓名" width="180"></el-table-column>
<el-table-column prop="email" label="邮箱" width="300"></el-table-column>
<el-table-column prop="mobile" label="电话" width="300"></el-table-column>
<el-table-column prop="mg_state" label="用户状态" width="80">
<!-- slot-scope 废弃,已经被v-slot代替,为插槽传入 prop 的时候使用 -->
<template slot-scope="scope">
<el-switch
v-model="scope.row.mg_state"
active-color="#13ce66"
inactive-color="#ff4949"
></el-switch>
</template>
</el-table-column>
<el-table-column label="操作">
<template slot-scope="scope">
<el-button type="primary" plain size="mini" icon="el-icon-edit"></el-button>
<el-button type="danger" plain size="mini" icon="el-icon-check"></el-button>
<el-button type="warning" plain size="mini" icon="el-icon-delete"></el-button>
</template>
</el-table-column>
</el-table>
</el-col>
</el-row>
<!-- 底部的分页 -->
<el-row>
<el-col :span="24">
<!-- 删掉el-pagination如下的默认事件 -->
<!-- @size-change="handleSizeChange"
@current-change="handleCurrentChange" -->
<el-pagination
:current-page="pageData.pagenum"
:page-sizes="[2, 4, 6, 8, 10]"
:page-size="pageData.pagesize"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
></el-pagination>
</el-col>
</el-row>
</div>
</template>
<script>
export default {
data() {
return {
level2: "用户管理",
level3: "用户列表",
//页码
pageData: {
pagenum: 1,
pagesize: 10,
query: ""
},
//总页数,默认为0
total: 0,
//用户的数据
userList: []
};
},
created() {
//get请求需要通过params属性来传对象
this.$axios.get("users", { params: this.pageData }).then(res => {
console.log(res);
this.userList = res.data.data.users;
this.total = res.data.data.total;
});
}
};
</script>
<style lang="scss">
#user {
.operate {
background-color: #e8edf3;
}
}
</style>
2.完成user组件动态交互
Ⅰ.用户查询
NO. | 题外话:组件中写name的好处 |
---|---|
1 | vue开发者界面语义更明确 |
2 | 可以使用搜索快速定位到组件 |
用户查询步骤:点搜索→发请求→调接口→拿数据
NO. | 用户查询步骤 |
---|---|
1 | 根据input输入的查询字段可以进行模糊搜索,如果input输入为空默认搜索到全部用户 |
2 | 搜索方法和页面刷新created调用的方法一样,可以封装复用 |
Ⅱ.用户添加
饿了吗:Dialog 对话框(自定义内容) 传送门http://element-cn.eleme.io/#/zh-CN/component/dialog
NO. | Dialog对话框 |
---|---|
1 | 和面包屑同级,新增html用户添加的对话框代码 |
1 | 在form上添加:rules="rules"属性,增加表单数据验证 |
2 | 在form上添加:ref="userForm"属性,并将userForm传给提交按钮,增加表单提交验证 |
3 | 表单验证是前端验证可以被绕过,主要防止普通用户的误操作 |
4 | 技术用户可以绕过前端验证,比如用postman直接发送请求,添加用户,就不需要受到前端的限制 |
5 | 所以后端服务器一定会再验证一次 |
//template
<!-- 添加用户的对话框 -->
<el-dialog title="添加用户" :visible.sync="visible">
<!-- label-position控制label名的显示位置,注意要设置label-width才能生效 -->
<!-- 表单数据验证要加form上添加:rules="rules"属性 -->
<!-- 表单提交验证要加ref="userForm"属性,并将userForm传给提交按钮 -->
<el-form :model="form" :rules="rules" ref="userForm" label-position="left" label-width="70px">
<el-form-item label="用户名" prop="username">
<el-input v-model="form.username" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="密码" prop="password">
<!-- 添加type="password"属性,让密码不明文显示 -->
<el-input v-model="form.password" type="password" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="邮箱">
<el-input v-model="form.email" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="手机号">
<el-input v-model="form.mobile" autocomplete="off"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="visible = false">取 消</el-button>
<!-- 记住这边的userForm要加单引号 -->
<el-button type="primary" @click="submitForm('userForm')">确 定</el-button>
</div>
</el-dialog>
//css
<style lang="scss">
#user {
.operate {
background-color: #e8edf3;
}
.el-dialog {
width:30%;
}
}
</style>
//js
<script>
export default {
//写了name方便在Vue Devtools谷歌插件应用内找到对应的组件
name: "user",
data() {
return {
level2: "用户管理",
level3: "用户列表",
//页码
pageData: {
pagenum: 1,
pagesize: 10,
//query是查询的字段
query: ""
},
//总页数,默认为0
total: 0,
//用户的数据
userList: [],
//是否 显示对话框
visible: false,
form: {
username: "",
password: "",
email: "",
mobile: ""
},
//表单验证规则
rules: {
username: [
{ required: true, message: '请输入用户名', trigger: 'blur' },
{ min: 3, max: 20, message: '长度在 3 到 20 个字符', trigger: 'blur' }
],
password: [
{ required: true, message: '请输入密码', trigger: 'blur' },
{ min: 3, max: 20, message: '长度在 3 到 20 个字符', trigger: 'blur' }
]
}
}
},
methods: {
//查询用户方法
async getUsers() {
//get请求需要通过params属性来传对象
//用async/await 同步执行异步代码
let res = await this.$axios.get("users", {
params: this.pageData
});
//赋值
this.userList = res.data.data.users;
this.total = res.data.data.total;
},
//提交增加用户方法
//这边submitForm和validate都要加上async,内部的await才能生效
async submitForm(formName) {
this.$refs[formName].validate(async valid => {
if (valid) {
//验证成功
//调用接口
let res = await this.$axios.post("users",this.form);
console.log(res);
if(res.data.meta.status===201){
//201表示成功请求并创建了新的资源,可以继续执行下一步
//关闭弹框
this.visible=false;
//重新获取数据
this.getUsers();
}
} else {
//验证失败
this.$message.error('请您输入正确的信息')
return false;
}
});
},
},
//生命周期函数,回调函数
async created() {
//get请求需要通过params属性来传对象
// let res = await this.$axios.get("users", { params: this.pageData });
// this.userList = res.data.data.users;
// this.total = res.data.data.total;
//直接调用封装后的代码
this.getUsers();
}
};
</script>
Ⅲ.用户状态(启用跟禁用该用户)
image//template中
<!-- slot-scope 废弃,已经被v-slot代替,为插槽传入table中的userList -->
<template slot-scope="scope">
<el-switch
v-model="scope.row.mg_state"
active-color="#13ce66"
inactive-color="#ff4949"
@change="statusChange(scope.row)">
</el-switch>
</template>
//js的methods中增加如下方法
<script>
async statusChange(data){
console.log(data);
let res = await this.$axios.put(`users/${data.id}/state/${data.mg.state}`);
}
</script>
Ⅳ.用户删除:传入id即可
//在删除按钮增加delOne方法,写在methods内
<script>
delOne(data){
console.log(data);
let id = data.id;
//提示用户
this.$confirm('此操作将永久删除用户,是否继续?',"提示",{
confirmButtonText:"确定",
cancelButtonText:"取消",
type:"danger"
})
.then(async()=>{
//确定
let res = await this.$axios.delete(`users/${id}`);
//console.log(res);
//重新获取用户数据即可
this.getUsers();
})
.catch(()=>{
//取消
})
}
</script>
V.用户编辑:
NO. | 用户编辑 |
---|---|
1 | 进入编辑状态 |
2 | 保存编辑结果 |
进入编辑状态
//template
<!-- 修改用户的对话框 -->
<el-dialog title="修改用户" :visible.sync="editVisible">
<!-- label-position控制label名的显示位置,注意要设置label-width才能生效 -->
<!-- 表单提交验证要加ref="userForm"属性,并将userForm传给提交按钮 -->
<el-form :model="editForm" ref="editForm" label-position="left" label-width="70px">
<el-form-item label="用户名" prop="username">
<!-- 用户名不可改,可以再input内加disabled属性,就能实现禁止修改 -->
<!-- 对于利用vue浏览器插件进行修改的用户,只能说牛逼,暂时没有想到解决方法 -->
<el-input v-model="editForm.username" disabled autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="邮箱">
<el-input v-model="editForm.email" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="手机号">
<el-input v-model="editForm.mobile" autocomplete="off"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="editVisible = false">取 消</el-button>
<!-- 记住这边的userForm要加单引号 -->
<el-button type="primary" @click="submitEdit('editForm')">确 定</el-button>
</div>
</el-dialog>
//js:
<script>
//1.data数据里增加
//编辑框是否可见
editVisible:false,
//编辑框的表单数据
editForm:{
username:'',
email:'',
mobile:''
//增加用户的id,方便后续编辑使用
id:''
}
//2.methods里增加方法
//显示编辑框
showEditDialog(data){
//打印data
console.log(data);
//显示编辑框
this.editVisible = true;
//js的for in方法,遍历editForm的key,将data对应的key赋值给editForm的key
for (const key in this.editForm) {
this.editForm[key] = data[key];
}
//这种方法可能会在vue插件界面被篡改数据,保险点是用id再请求一个接口获取数据
//如果id也被修改了呢?一般不会这么无聊
}
</script>
保存编辑结果
//1.template:增加确定保存按钮
<div slot="footer" class="dialog-footer">
<el-button @click="editVisible = false">取 消</el-button>
<!-- 记住这边的userForm要加单引号 -->
<el-button type="primary" @click="submitEdit()">确 定</el-button>
</div>
//2.js:methods里增加方法
<script>
async submitEdit(){
let res = await this.$axios.put(
`users/${this.editForm.id}`,
this.editForm
);
console.log(res);
if(res.data.meta.status===200){
//关闭编辑框
this.editVisible = false;
//重新获取数据即可
this.getUsers();
}
}
</script>
VI.分配角色
NO. | 分配角色 |
---|---|
1 | 弹出角色框,分配角色 |
2 | 保存分配结果 |
饿了吗组件 Select 选择器
传送门http://element-cn.eleme.io/#/zh-CN/component/select
//template
<!-- 分配角色的对话框 -->
<el-dialog title="分配角色" :visible.sync="roleVisible">
<!-- 就一个下拉框,不需要绑定表单数据:model="editForm",绑定角色数据就行 -->
<el-form label-position="left" label-width="100px">
<el-form-item label="当前用户">
{{selectUser.username}}
</el-form-item>
<el-form-item label="请选择角色">
<el-select v-model="selectUser.role_name" placeholder="请选择">
<el-option
v-for="item in roles"
:key="item.id"
:label="item.roleName"
:value="item.id">
</el-option>
</el-select>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="roleVisible = false">取 消</el-button>
<!-- 记住这边的userForm要加单引号 -->
<el-button type="primary" @click="submitRole">确 定</el-button>
</div>
</el-dialog>
//js
<script>
// data里增加下面数据
//分配角色框是否显示
roleVisible:false,
//当前选中的用户数据
selectUser:'',
//所有的角色数据
roles:''
//methods里增加下面的方法
//显示角色对话框
async showRoleDialog(data){
this.roleVisible = true;
//通过data获取用户的名字,用户的角色
//console.log(data);
//为了方便编码,直接保存当前选择的用户数据
this.selectUser = data;
//获取所有的角色,去数据库获取(角色列表接口)
let res = await this.$axios.get('roles');
console.log(res);
this.roles = res.data.data;
console.log(this.roles);
},
//保存分配结果
async submitRole(){
// 获取用户id,获取角色id
// 调用接口
let res = this.$axios.put(`users/${this.selectUser.id}/role`,{
rid:this.selectUser.role_name
});
console.log(res);
//关闭对话框
this.roleVisible = false;
//提示用户,之前已经有axios拦截器了
}
</script>
V.分页功能实现
饿了吗组件 Pagination 分页的一些属性和方法
属性/方法 | 作用 |
---|---|
1.@size-change="handleSizeChange" | pageSize (每页条数) 改变时会触发,回调参数是新的pageSize |
2.@current-change="handleCurrentChange" | currentPage(当前页)改变时会触发,回调参数是新的currentPage |
3.:page-sizes="[2, 4, 6, 8, 10]" | 这是下拉框可以选择的,每选择一行,要展示多少内容 |
4.:page-size="pageSize" | 显示当前行的条数 |
5.:total="userList.length" | 总共有多少数据 |
6.:data="userList.slice((currentPage-1)pagesize,currentPagepagesize) | userList取第几页的数据,最为重要的一句话 |
//html
<!-- 用户数据 -->
<el-row>
<el-col :sapn="24">
<!-- 如下对数据请求的处理,最为重要的一句话,表示,userList取第几页的数据 -->
<!-- :data="userList.slice((currentPage-1)*pagesize,currentPage*pagesize)" -->
<!-- arrayObject.slice(start,end)方法,参数是指数组对应的下标元素,start参数必选,end参数可选 -->
<el-table style="width: 100%" border
:data="userList.slice((pageData.pagenum-1)*pageData.pagesize,pageData.pagenum*pageData.pagesize)" >
<!-- 返回的数据没有对应的属性名,把prop删掉 -->
<!-- 增加type="index",会设置排序 -->
<el-table-column label="#" width="30" type="index"></el-table-column>
<el-table-column prop="username" label="姓名" width="180"></el-table-column>
<el-table-column prop="email" label="邮箱" width="300"></el-table-column>
<el-table-column prop="mobile" label="电话" width="300"></el-table-column>
<el-table-column prop="mg_state" label="用户状态" width="80">
<!-- slot-scope 废弃,已经被v-slot代替,为插槽传入table中的userList -->
<template slot-scope="scope">
<el-switch
v-model="scope.row.mg_state"
active-color="#13ce66"
inactive-color="#ff4949"
@change="statusChange(scope.row)"
></el-switch>
</template>
</el-table-column>
<el-table-column label="操作">
<template slot-scope="scope">
<el-button type="primary" plain size="mini" @click="showEditDialog(scope.row)" icon="el-icon-edit"></el-button>
<el-button type="danger" plain size="mini" @click="delOne(scope.row)" icon="el-icon-delete"></el-button>
<el-button type="warning" plain size="mini" @click="showRoleDialog(scope.row)" icon="el-icon-check"></el-button>
</template>
</el-table-column>
</el-table>
</el-col>
</el-row>
<!-- 底部的分页 -->
<el-row>
<!-- size-change pageSize(每页条数)改变时会触发的事件 -->
<!-- current-change currentPage(当前页)改变时会触发 -->
<!-- :page-sizes="[2, 4, 6, 8, 10]" 这是下拉框可以选择的,每选择一行,要展示多少内容 -->
<!-- :page-size="pageData.pagesize"显示当前行的条数 -->
<!-- :total="userList.length" 这是总共有多少数据 -->
<el-col :span="24">
<!-- 删掉el-pagination如下的默认事件 -->
<!-- @size-change="handleSizeChange"
@current-change="handleCurrentChange"-->
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="pageData.pagenum"
:page-sizes="[2, 4, 6, 8, 10]"
:page-size="pageData.pagesize"
layout="total, sizes, prev, pager, next, jumper"
:total="userList.length"
></el-pagination>
</el-col>
</el-row>
//js 在methods中加如下方法
<script>
handleSizeChange(size){
this.pageData.pagesize = size;//每页下拉显示数据
// console.log(this.pageData.pagesize);
},
handleCurrentChange(currentPage){
this.pageData.pagenum = currentPage;//点击第几页
// console.log(this.pageData.pagenum);
}
</script>
本文同步发表在我的个人博客:https://www.lubaojun.com/
网友评论