前后端分离开发之前端Vue工程
-
安装ElementUI局部组件库
npm install element-ui -S
在入口文件main.js中全局导入ElementUI组件库
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);
-
安装Axios (HTTP通信库)
npm install axios -S
Axios是一款HTTP通信的三方库, 作用与jQuery的ajax是一样的, 用于发起http请求后端, 并接受后端返回的响应数据,因为Vue工程中用不到jQuery技术, 因此用不了ajax,改用Axios技术
因为ajax是早期的HTTP通信技术, 因此人们习惯将HTTP通信技术统称为ajax
Axios与ajax是同一种类型的技术
自己手动封装axios模块
在src目录下创建http目录, 在http目录中创建index.js文件
import axios from 'axios'
import {Notification, Loading} from 'element-ui'
axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
const http = axios.create({
baseURL:'http://localhost:8888/api',
timeout: 15 * 1000
})
let loading;
http.interceptors.request.use(config => {
loading = Loading.service({
lock: true,
text: 'Loading',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
})
return config
}, error => {
loading.close()
Notification({
type:'error',
title:'错误',
message:'请检查网络'
})
Promise.reject(error)
})
http.interceptors.response.use(res => {
loading.close();
const code = res.data.code;
const msg = res.data.msg;
if (code !== '000000'){
Notification({
type:'error',
title:code,
message:msg
})
return Promise.reject(res)
}else {
return res.data.data
}
}, error => {
loading.close()
Notification({
type:'error',
title:'错误',
message:'服务器没有响应'
})
return Promise.reject(error)
})
export default http
在入口文件main.js中全局导入基于axios封装的http对象
import http from './http';
Vue.prototype.$http = http
-
从http目录的index.js文件中导入http对象
-
将http对象挂载在Vue原型对象上的$http属性上面
-
这样我们就可以在任意的Vue组件中使用this.$http对象来发起http请求了
-
创建Views组件
在viiews目录中创建user目录, 与User相关的组件创建在这个目录中
-
Login.vue 用户登录组件
-
Register.vue 用户注册组件
-
UserDetail 用户详细信息组件
-
UserModify 编辑用户组件
-
UserView 用户列表组件
-
Home.vue 主页组件
-
Dashboard.vue 主页中的控制面板组件
省略其他组件..........
-
Views组件注册路由
在src/router/index.js路由配置文件中注册Views组件路由
导入需要注册路由的组件
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from "@/views/Home";
import UserView from "@/views/user/UserView";
注册路由
Vue.use(VueRouter)
const routes = [
{
path:'/',
component:Home
},
{
path:'/user',
component:UserView
}
]
-
编写App.vue (设置布局)
<template>
<div id="app">
<el-container style="height: 100%">
<el-header style="height: 6%">
</el-header>
<el-container style="height: 94%">
<el-aside width="200px">
<el-menu
default-active="/dashboard"
class="el-menu-vertical-demo"
text-color="rgba(0,0,0,0.4)"
:router="true">
<el-menu-item index="/dashboard">主页</el-menu-item>
<el-menu-item index="/user">用户管理</el-menu-item>
<el-menu-item index="/product">商品管理</el-menu-item>
<el-menu-item index="/order">订单管理</el-menu-item>
<el-menu-item index="/comment">评论管理</el-menu-item>
<el-menu-item index="/category">分类管理</el-menu-item>
<el-menu-item index="/other">其他管理</el-menu-item>
</el-menu>
</el-aside>
<el-main style="padding: 10px;">
<div class="infinite-list" style="overflow:auto">
<router-view/>
</div>
</el-main>
</el-container>
</el-container>
</div>
</template>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
color: #2c3e50;
height: 100%;
}
.el-header {
background-color: rgba(0,0,0,0.7);
color: white;
}
.el-main {
background-color: rgba(0,0,0,0.1);
}
.el-menu-item {
text-align: center;
font-size: 16px;
}
.infinite-list {
background-color: white;
padding: 10px;
}
</style>
-
在index.html中设置style
为什么在public/index.html里面做整个事情?
因为这个html文件是项目全局唯一的网页文件,也是顶层的html代码
这里做了两件事
-
* 选择器设置了全局所有的内边距和外边距全部为0
-
设置html, body 的宽度和高度为当前设备上视口的100 %
页面的宽度默认就是视口的100 %
但是页面的高度会根据内容拉伸形成长页面, 这里将高度设置为100% , 页面就不会拉伸了
我们可以在页面的局部使用滚动布局, 让局部支持滚动
<style>
* {
padding: 0px;
margin: 0px;
}
html, body{
width: 100%;
height: 100%;
}
</style>
-
编写UserView组件
在data中注册全局变量
data(){
return {
total:100,
current: 1,
size: 10,
username:'',
idCode:'',
mobile:'',
userList:[]
}
}
在template中使用ElementUI提供的组件编写页面模板
-
使用el-card组件作为容器标签
<template>
<el-card class="box-card">
<el-form :inline="true" class="demo-form-inline">
<el-form-item>
<el-input v-model="username" placeholder="请输入用户名"></el-input>
</el-form-item>
<el-form-item>
<el-input v-model="idCode" placeholder="请输入身份证号码"></el-input>
</el-form-item>
<el-form-item>
<el-input v-model="mobile" placeholder="请输入手机号码"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="getUserList">查询</el-button>
</el-form-item>
</el-form>
<el-empty description="暂无数据" v-show="userList == null || userList.length == 0"></el-empty>
<div v-show="userList != null && userList.length > 0">
<div style="margin-bottom: 20px">
<el-button size="mini" @click="toggleSelection(userList)">全选</el-button>
<el-button size="mini" @click="toggleSelection()">取消</el-button>
<el-button size="mini" type="danger" @click="toggleSelection()">批量删除(逻辑)</el-button>
<el-button size="mini" type="danger" @click="toggleSelection()">批量删除(物理)</el-button>
<el-button size="mini" type="primary" @click="toggleSelection()">导出excel</el-button>
</div>
<el-table
ref="multipleTable"
:data="userList"
tooltip-effect="dark"
style="width: 100%"
@selection-change="handleSelectionChange">
<el-table-column
type="selection"
width="55">
</el-table-column>
<el-table-column
label="用户编号"
prop="id"
width="180">
</el-table-column>
<el-table-column
label="用户名"
prop="username"
width="180">
</el-table-column>
<el-table-column
label="性别"
prop="sex"
width="180">
</el-table-column>
<el-table-column
label="手机号码"
prop="mobile"
width="180">
</el-table-column>
<el-table-column
label="身份证号码"
prop="idCode"
width="200">
</el-table-column>
<el-table-column
label="用户名"
prop="username"
width="180">
</el-table-column>
<el-table-column label="操作">
<template v-slot="scope">
<el-button
size="mini"
type="primary"
@click="handleDetail(scope.$index, scope.row)">详情</el-button>
<el-button
size="mini"
@click="handleEdit(scope.$index, scope.row)">编辑</el-button>
<el-button
size="mini"
type="danger"
@click="handleDelete(scope.$index, scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<div style="display: flex; justify-content: center;margin-top: 20px">
<el-pagination
background
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="current"
:page-sizes="[5, 10, 20, 50, 100]"
:page-size="size"
:total="total"
layout="total, sizes, prev, pager, next, jumper">
</el-pagination>
</div>
</div>
</el-card>
</template>
在methods中注册全局函数
methods:{
toggleSelection(rows) {
if (rows) {
rows.forEach(row => {
this.$refs.multipleTable.toggleRowSelection(row);
});
} else {
this.$refs.multipleTable.clearSelection();
}
},
getUserList(){
this.$http.get('/user/list', {
params:{
current: this.current,
size:this.size,
username:this.username,
idCode:this.idCode,
mobile:this.mobile
}
}).then((data) =>{
if( data ){
this.total = data.total;
this.userList = data.records;
}
})
},
handleSelectionChange(val) {
this.multipleSelection = val;
console.log(val)
},
handleSizeChange(val){
this.size = val;
this.getUserList()
},
handleCurrentChange(val){
this.current = val;
this.getUserList()
},
handleDetail(index, row){
},
handleEdit(index, row){
},
handleDelete(index, row){
}
}
编写mounted钩子函数
注意: 钩子函数不是定义i在methods里面的, 而是和methods平级的
mounted(){
this.getUserList();
}