四、用户列表
添加用户列表组件并配置路由表
- 分别创建下面的四个文件
src/components/user-list/user-list.vue
src/components/user-list/template.html
src/components/user-list/script.js
src/components/user-list/style.css
src/components/user-list/template.html
:
<div>
<p>user-list component</p>
</div>
src/components/user-list/user-list.vue
:
<template src="./template.html"></template>
<script src="./script.js"></script>
<style src="./style.css"></style>
- 配置路由表
src/router/index.js
:
// ... 代码略
const router = new Router({
routes: [
{
path: '/',
component: Home,
// 当渲染 children 组件的时候会先把 Home 组件渲染出来
// Home 组件找到根组件中的 router-view 出口替换渲染
// Home 组件的 children 子路由会渲染到 Home 组件内部的 router-view 出口
// 参考文档:https://router.vuejs.org/zh-cn/essentials/nested-routes.html
children: [
{
path: '/users',
component: UserList
}
]
},
{
path: '/login',
component: Login
}
]
})
// ... 代码略
- 访问
/users
测试。
在用户列表中使用表格组件
参考链接:
src/components/user-list/template.html
:
<div>
<!--
表格组件的使用:
el-table 组件
data 用来绑定表格数据,是一个数组
表格组件会根据 data 自动循环渲染
el-table-column 组件就是表格列
label 属性用来指定列的标题
prop 属性用来指定 data 数组中元素项的某个属性
width 用来设定表格列的宽度,默认单位是 px
-->
<el-table
:data="tableData"
style="width: 100%">
<el-table-column
prop="date"
label="日期"
width="180">
</el-table-column>
<el-table-column
prop="name"
label="姓名"
width="180">
</el-table-column>
<el-table-column
prop="address"
label="地址">
</el-table-column>
</el-table>
</div>
src/components/user-list/script.js
:
export default {
data() {
return {
tableData: [{
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀区金沙江路 1517 弄'
}, {
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1519 弄'
}, {
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀区金沙江路 1516 弄'
}]
}
}
}
在请求头中加入 token 请求用户列表
src/components/user-list/script.js
import axios from 'axios'
export default {
// ... 代码略
created () {
// 1. 除了登陆接口,其它接口都需要 token 认证
// 2. 我们要做的就是按照服务器接口的要求,把 token 放到请求头的 Authorization 字段中
// 3. 对于接口中的查询字符串,我们可以通过 axios 请求的可选参数 params 来指定传递
// params 对象就类似于我们之前使用的 $.ajax 中的 data 选项
// params 对象最终会被转换为 key=value&key=value 的格式字符串然后以 ? 分隔拼接到请求地址后面发起请求
// 这样做的好处就是不需要我们自己去 url 中拼 ?key=value&key=value
// 服务器 API 除了登陆的接口是可以直接请求处理
// 其它所有的接口都必须提供登陆成功交换到的 token 发送给服务器才可以
// 我们这里服务器接口要求必须在请求头中通过一个名字为 Authorization 字段提供 token 令牌
axios.get('http://localhost:8888/api/private/v1/users', {
headers: { // headers 是 axios 的 API,固定的
// 需要授权的 API ,必须在请求头中使用 Authorization 字段提供 token 令牌
// Authorization 是服务器接口的要求,我们不能乱写
// 也就是说如果接口要求在头里面放一个 a 值为 token
// 则我们就要
// a: window.localStorage.getItem('token')
Authorization: window.localStorage.getItem('token')
},
params: { // params 可以用来指定请求的查询字符串
pagenum: 1, // 告诉接口服务器,我要获取第 1 页的数据
pagesize: 5 // 告诉接口服务器,每页5条数据
}
})
.then(res => {
console.log(res.data)
})
}
// ... 代码略
}
将请求得到的数据更新到用户列表表格中
src/components/user-list/template.html
:
<div>
<el-table
:data="tableData"
style="width: 100%">
<el-table-column
prop="username"
label="用户名"
width="180">
</el-table-column>
<el-table-column
prop="email"
label="邮箱"
width="180">
</el-table-column>
<el-table-column
prop="mobile"
label="电话"
width="180">
</el-table-column>
</el-table>
</div>
src/components/user-list/script.js
:
import axios from 'axios'
export default {
created () {
axios.get('http://localhost:8888/api/private/v1/users', {
headers: {
Authorization: window.localStorage.getItem('token')
},
params: {
pagenum: 1,
pagesize: 5
}
})
.then(res => {
const {data, meta} = res.data
if (meta.status === 200) {
this.tableData = data.users
}
})
},
data () {
return {
tableData: []
}
}
}
分页展示用户列表
src/components/user-list/template.html
:
<div>
<!-- 表格列表 -->
... 代码略
<!-- /表格列表 -->
<!-- 数据分页 -->
<el-pagination
background
layout="prev, pager, next"
:page-size="2"
:total="total"
@current-change="handleCurrentChange">
</el-pagination>
<!-- /数据分页 -->
</div>
src/components/user-list/script.js
:
import axios from 'axios'
export default {
created () {
// 页码第一次加载,显示第1页数据
this.loadUsersByPage(1)
},
data () {
return {
tableData: [],
total: 0
}
},
methods: {
handleCurrentChange (page) {
// 在页码改变的时候,请求加载该页码对应的数据
this.loadUsersByPage(page)
},
loadUsersByPage (page) {
axios.get('http://localhost:8888/api/private/v1/users', {
headers: {
Authorization: window.localStorage.getItem('token')
},
params: {
pagenum: page,
pagesize: 2
}
}).then(res => {
const {data, meta} = res.data
if (meta.status === 200) {
this.tableData = data.users
this.total = data.total
}
})
}
}
}
用户列表搜索
src/components/user-list/template.html
:
<div>
<el-row>
<el-col :span="6">
<el-input placeholder="请输入内容" v-model="searchText" class="input-with-select">
<el-button slot="append" icon="el-icon-search" @click="handleSearch"></el-button>
</el-input>
</el-col>
</el-row>
<!-- 表格列表 -->
... 代码略
<!-- /表格列表 -->
<!-- 数据分页 -->
... 代码略
<!-- /数据分页 -->
</div>
src/components/user-list/script.js
:
import axios from 'axios'
export default {
created () {
// 页码第一次加载,显示第1页数据
this.loadUsersByPage(1)
},
data () {
return {
tableData: [],
total: 0,
searchText: ''
}
},
methods: {
handleCurrentChange (page) {
// 在页码改变的时候,请求加载该页码对应的数据
this.loadUsersByPage(page)
},
loadUsersByPage (page) {
axios.get('http://localhost:8888/api/private/v1/users', {
headers: {
Authorization: window.localStorage.getItem('token')
},
params: {
pagenum: page,
pagesize: 2,
query: this.searchText // query 参数可选,用来指定查询的筛选条件,这里的筛选条件是用户名
}
}).then(res => {
const {data, meta} = res.data
if (meta.status === 200) {
this.tableData = data.users
this.total = data.total
}
})
},
/**
* 处理搜索
*/
handleSearch () {
// 点击搜索,调用请求方法加载数据列表
// 请求方法中会去根据输入框中的内容进行搜索
this.loadUsersByPage(1)
}
}
}
添加用户
shop-admin/src/components/user-list/template.html
:
<div>
<!-- 面包屑 -->
... 代码略
<!-- /面包屑 -->
<!-- 搜索 -->
<el-row :gutter="20">
<el-col :span="6">
<el-input placeholder="请输入内容" v-model="searchText">
<el-button slot="append" icon="el-icon-search" @click="handleSearch"></el-button>
</el-input>
</el-col>
<el-col :span="2">
<el-button type="primary" @click="dialogFormVisible = true">添加用户</el-button>
</el-col>
</el-row>
<!-- /搜索 -->
<!-- 表格列表 -->
... 代码略
<!-- /表格列表 -->
<!-- 数据分页 -->
... 代码略
<!-- /数据分页 -->
<!-- 添加用户对话框 -->
<!--
el-dialog 是对话框组件
visible 属性需要绑定一个布尔值,对话框会根据布尔值的真假来决定显示与隐藏
-->
<el-dialog title="添加用户" :visible.sync="dialogFormVisible">
<el-form ref="form" :model="addUserForm" label-position="left" size="small" :rules="formRule">
<el-form-item label="用户名" label-width="80px" prop="username">
<el-input v-model="addUserForm.username" auto-complete="off"></el-input>
</el-form-item>
<el-form-item label="密码" label-width="80px" prop="password">
<el-input v-model="addUserForm.password" auto-complete="off"></el-input>
</el-form-item>
<el-form-item label="邮箱" label-width="80px" prop="email">
<el-input v-model="addUserForm.email" auto-complete="off"></el-input>
</el-form-item>
<el-form-item label="电话" label-width="80px" prop="mobile">
<el-input v-model="addUserForm.mobile" auto-complete="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="handleAddUser">确 定</el-button>
</div>
</el-dialog>
<!-- 添加用户对话框 -->
</div>
src/components/user-list/script.js
:
import axios from 'axios'
export default {
created () {
this.loadUsersByPage(1)
},
data () {
return {
tableData: [],
total: 0,
searchText: '',
dialogFormVisible: false,
addUserForm: {
username: '',
password: '',
email: '',
mobile: ''
},
formRule: {
username: [
{required: true, message: '请输入用户名', trigger: 'blur'}
],
password: [
{required: true, message: '请输入密码', trigger: 'blur'},
{min: 3, max: 16, message: '密码为 3 - 16 位长度', trigger: 'blur'}
],
email: [
{ required: true, message: '请输入用户名', trigger: 'blur' },
{ type: 'email', message: '请输入正确的邮箱', trigger: 'blur' }
],
mobile: [
{ required: true, message: '请输入手机号', trigger: 'blur' }
]
}
}
},
methods: {
// ... 代码略
// ... 代码略
/**
* 添加用户
*/
handleAddUser () {
axios({
method: 'post',
url: 'http://localhost:8888/api/private/v1/users',
data: this.addUserForm,
headers: {
Authorization: window.localStorage.getItem('token')
}
}).then(res => {
if (res.data.meta.status === 201) {
this.$message({
type: 'success',
message: '添加用户成功'
})
// 关闭对话框
this.dialogFormVisible = false
// 清空表单
this.$refs['form'].resetFields()
}
})
}
// ... 代码略
// ... 代码略
}
}