效果展示

创建项目
- 创建项目
| vue create userlist
cd userlist
npm i
npm i axios@0.21.1 -S
npm i element-ui
|
- 设置全局样式
在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>
|
- 封装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'
|
- 封装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;
|
- 解决跨域问题
创建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'
}
}
|
- routerView占位符
在App.vue中:
1 2 3 4 5 6 7 8 9
| <template>
<div>
<router-view></router-view>
</div>
</template>
|
实现UserList组件
- 创建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>
<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(
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 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 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 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 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>
|
- 挂载路由
在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组件
- 详情挂载函数
在UserList.vue中:
1 2 3 4 5 6 7 8 9
| <template>
...
<router-link :to="'/users/' + row.id">详情</router-link>
...
</template>
|
- 挂载路由
在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
}
]
|
- 实现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加载效果