3-05-案例-用户列表

效果展示

创建项目

  1. 创建项目
1
2
3
4
5
6
7
8
9
vue create userlist //开启router,sass

cd userlist

npm i

npm i axios@0.21.1 -S

npm i element-ui
  1. 设置全局样式

在App.vue中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<style>

:root {

font-size: 12px;

}

body {

padding: 5px;

}

</style>
  1. 封装element-ui库

创建element-ui/index.js:

1
2
3
4
5
6
7
8
9
10
11
import ElementUI from 'element-ui';

import 'element-ui/lib/theme-chalk/index.css';

import Vue from 'vue';

Vue.use(ElementUI);

在main.js中:

import './element-ui'
  1. 封装axios

创建api/index.js:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import axios from 'axios';

import { Loading } from 'element-ui';

axios.defaults.baseURL = 'http://localhost:3000';

let loadingIns = null;

axios.interceptors.request.use(config => {

loadingIns = Loading.service({fullscreen: true});

return config;

});

axios.interceptors.response.use(rsp => {

loadingIns.close();

return rsp;

})

export const MyRequest = axios;

在main.js中:

1
2
3
import { MyRequest } from './api';

Vue.prototype.$http = MyRequest;
  1. 解决跨域问题

创建vue.config.js:

1
2
3
4
5
6
7
8
9
10
11
12
13
module.exports = {

devServer: {

port: 3000,

open: true,

proxy: 'https://www.escook.cn'

}

}
  1. routerView占位符

在App.vue中:

1
2
3
4
5
6
7
8
9
<template>

<div>

<router-view></router-view>

</div>

</template>

实现UserList组件

  1. 创建UserList.vue并渲染主表格:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
<template>

<el-table :data="userList" stripe border style="width: 100%">

<el-table-column label="#" prop="id"></el-table-column >

<el-table-column label="名称" prop="name"></el-table-column >

<el-table-column label="年龄" prop="age"></el-table-column >

<el-table-column label="头衔" prop="position"></el-table-column>

<el-table-column label="创建时间">

<template v-slot="{ row }">

{{ row.addtime | formatDate }}

</template>

</el-table-column >

<el-table-column label="操作">

<template>

<a>详情</a>&nbsp;

<a>删除</a>

</template>

</el-table-column >

</el-table>

</template>

<script>

export default {

data() {

return {

userList: []

}

},

created() {

this.getUserList();

},

methods: {

async getUserList() {

const { data: res } = await this.$http.get('/api/users');

if (res.status !== 0) this.$message.error(res.message);

this.userList = res.data;

}

}

}

</script>

在main.js中增加全局过滤器formatDate:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Vue.filter('formatDate', date => {

const dN = new Date(date);

const y = dN.getFullYear();

const m = (dN.getMonth() + 1).toString().padStart(2, 0);

const d = dN.getDate().toString().padStart(2, 0);

const hh = dN.getHours().toString().padStart(2, 0);

const mm = dN.getMinutes().toString().padStart(2, 0);

const ss = dN.getSeconds().toString().padStart(2, 0);

return `${y}-${m}-${d} ${hh}:${mm}:${ss}`;

});
  1. 添加新用户按钮与界面
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
<template>

<el-button type="primary" @click="dialogVisible =
true">添加新用户</el-button>

<el-dialog title="添加新用户" :visible.sync="dialogVisible"
width="50%" @close="onDlgClose" >

<el-form ref="addForm" :model="form" label-width="60px">

<el-form-item label="用户">

<el-input v-model="name" />

</el-form-item>

<el-form-item label="年龄">

<el-input v-model="age" />

</el-form-item>

<el-form-item label="头衔">

<el-input v-model="position" />

</el-form-item>

</el-form>

<span slot="footer" class="dialog-footer">

<el-button @click="dialogVisible = false">取消</el-button>

<el-button type="primary" @click="dialogVisible =
false">确定</el-button>

</span>

</el-dialog>

</template>

<script>

export default {

data() {
return {

dialogVisible = false,

//用于接收表格数据

form: {

name: '',

age: '',

position: ''

}

}

},

methods: {

onDlgClose() {

this.$refs.addForm.resetFields(); //关闭对话框时清空输入框

}

}

}

</script>

<style>

.el-table {

margin-top: 15px;

}

</style>
  1. 验证表单
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
<template>

...

<el-form ... :rules="formRules">

<el-form-item prop="name"> ...

<el-form-item prop="age"> ...

<el-form-item prop="position">

</el-form>

...

</template>

<script>

export default {

data() {

let checkAge = (rule, value, cb) => {

if (!Number.isInteger(value)) return cb(new Error('必须是整数'));

if (value > 100 || value < 1) return cb(new
Error('年龄必须在1到100之间'));

cb();

}

return {

formRules: {

name: [

{ required: true, message: '姓名是必填项', trigger: 'blur' },

{ min: 1, max: 15, message: '字符个数必须在1到15之间', trigger:
'blur' }

],

age: [

{ required: true, message: '年龄是必填项', trigger: 'blur' },

{ validator: checkAge, trigger: 'blur' }

],

position: [

{ required: true, message: '头衔是必填项', trigger: 'blur' },

{ min: 1, max: 10, message: '字符个数必须在1到10之间', trigger:
'blur' }

]

}

}

},

}

</script>

注意:规则名要跟变量名保持一致

  1. 实现添加新用户功能
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<template>

...

<el-button @click="onAddUser">确定</el-button>

...

</template>

<script>

export default {

methods: {

onAddUser() {

this.$refs.addForm.validate(async valid => {

if(!valid) return this.$message.error('验证失败');

const { data: res } = await this.$http.post('/api/users', this.form);

if (res.status !== 0) return this.$message.error(res.message);

this.$message.success('添加成功');

this.dialogVisible = false;

this.getUserList();

})

}

}

}

</script>
  1. 删除用户
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
<template>

...

<template v-slot="{ row }">

...

<a href="#" @click.prevent="onRemove(row)" />

</template>

...

</template>

<script>

export default {

methods: {

async onRemove(row) {

const confirmResult =
this.$confirm(`即将永久删除用户"${row.name}",是否继续?`,
'提示', {

confirmButtonText: '确定',

cancelButtonText: '取消',

type: 'warning'

}).catch(err => err);

if(confirmResult != 'confirm') return
this.$message.info('取消删除操作');

const { data: res } = await this.$http.delete('/api/users/' +
row.id);

if (res.status !== 0) return this.$message.error(res.message);

this.$message.success('删除成功!');

this.getUserList();

}

}

}

</script>
  1. 挂载路由

在router/index.js中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import UserList from './components/UserList.vue';

...

const routes = [

{

path: '/',

redirect: '/users'

},

{

path: '/users',

component: UserList

}

]

...

实现UserDetail组件

  1. 详情挂载函数

在UserList.vue中:

1
2
3
4
5
6
7
8
9
<template>

...

<router-link :to="'/users/' + row.id">详情</router-link>

...

</template>
  1. 挂载路由

在router/index.js中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import UserDetail from './components/UserDetail.vue';

...

const routes: [

...

{

path: '/users/:id',

component: UserDetail,

props: true

}

]
  1. 实现UserDetail组件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
<template>

<el-card class="box-card">

<div slot="header" class="clearfix">

<span>用户详情</span>

<el-button type="text" style="float: right; padding: 3px 0;"
@click="goBack">返回</el-button>

</div>

<div class="text item">

<p>姓名:{{ userdetail.name }}</p>

<p>年龄:{{ userdetail.age }}</p>

<p>头衔:{{ userdetail.position }}</p>

</div>

</el-card>

</template>

<script>

export default {

data() {

return {

userdetail: []

}

},

props: {

id: {

required: true,

type: [Number, String]

}

},

created() {

this.getUserDetail();

}

methods: {

async getUserDetail() {

const { data: res } = await this.$http.get('/api/users/' + this.id);

if (res.status !== 0) return this.$message.error(res.message);

this.userdetail = res.data;

},

goBack() {

this.$router.go(-1);

}

}

}

</script>

参考:

Vue3.0-18.综合案例 -
案例效果展示

Vue3.0-19.综合案例 -
初始化项目

Vue3.0-20.综合案例 -
初始化路由

Vue3.0-21.综合案例 -
使用路由渲染UserList组件

Vue3.0-22.综合案例 -
安装和配置axios

Vue3.0-23.综合案例 -
请求用户列表的数据并解决接口跨域问题

Vue3.0-24.综合案例 -
安装并配置element-ui组件库

Vue3.0-25.综合案例 -
了解Table组件的基本使用

Vue3.0-26.综合案例 -
通过作用域插槽自定义创建时间的渲染格式

Vue3.0-27.综合案例 -
通过插槽渲染操作列的模板结构

Vue3.0-28.综合案例 -
点击按钮展示添加用户的Dialog组件

Vue3.0-29.综合案例 -
渲染添加新用户的Form表单

Vue3.0-30.综合案例 -
实现Form表单的数据验证

Vue3.0-31.综合案例 -
自定义Form表单的验证规则

Vue3.0-32.综合案例 -
在对话框关闭时重置Form表单

Vue3.0-33.综合案例 -
实现添加用户前的表单预验证

Vue3.0-34.综合案例 -
发起请求实现添加用户的功能

Vue3.0-35.综合案例 -
使用Message组件优化消息的展示效果

Vue3.0-36.综合案例 -
使用MessageBox组件询问用户是否删除

Vue3.0-37.综合案例 -
发起请求实现用户删除的功能

Vue3.0-38.综合案例 -
通过声明式导航跳转到用户详情页

Vue3.0-39.综合案例 -
获取并渲染用户列表数据

Vue3.0-40.综合案例 -
通过axios拦截器实现Loading加载效果


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!