本博文主要呈现一个NPM脚手架+Vue路由+ElementUI的综合案例,完成本案例需要有一定的Vue基础,请参考以下文章完成项目的构建
第08讲:使用脚手架创建vue项目
第09讲:路由开发
第10讲:vue脚手架集成axios
第11讲:vue脚手架集成ElementUI
案例效果
登录页面
- 具有表单校验功能
首页
- 使用二级路由完成左侧导航和右侧内容展示
- 通用式后台管理系统展示样式(top、left、right)
列表页
- 使用
el-table
完成数据展示 - 使用
el-pagination
完成分页器 - 使用
$message
完成消息的提示 - 实现多选删除
- 实现单选修改
- 使用
el-dialog
实现模态化窗口(添加、修改) - 实现模糊查询
ElementUI常用组件页
el-form
表单的使用el-select
下拉列表的使用及数据渲染el-checkbox
复选框的使用及数据渲染el-radio
单选按钮的使用及数据渲染
一、后端开发
由于是前后端分离的项目,我们提前开发了一个供前端测试的后台项目,具体代码可以联系博主索取
@RestController
@CrossOrigin
public class ArticleController {
@GetMapping("/list")
public Page<Article> findAll(Article article, Long pageNum, Long pageSize){
...
}
@PostMapping("/add")
public HttpResult add(@RequestBody Article article){
...
}
@PostMapping("/edit")
public HttpResult edit(@RequestBody Article article){
...
}
@GetMapping("/get")
public HttpResult getInfo(Long id){
...
}
@PostMapping("/remove")
public HttpResult remove(@RequestParam Long[] ids){
...
}
}
@Data
public class Article {
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
private String title;
private String logo;
private String descn;
private Date createTime;
private Long cid;
}
二、前端开发
2.1、App.vue入口
在入口中只需要添加一个router-view组件即可
<template>
<div>
<router-view/>
</div>
</template>
2.2、main.js
在主控制文件main.js中导入路由、axios、element-ui组件
import Vue from 'vue'
import App from './App.vue'
import router from './router'
//ElementUI相关
import ElementUI from 'element-ui'
//ElementUI相关
import 'element-ui/lib/theme-chalk/index.css'
//ElementUI相关
Vue.use(ElementUI)
//axios相关
import axios from 'axios'
Vue.prototype.$axios = axios
Vue.config.productionTip = false
new Vue({
router,
render: h => h(App)
}).$mount('#app')
2.3、路由配置
页面展示
路由配置:router/index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import Login from '../views/login.vue'
import Home from '../views/main.vue'
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'login',
component: Login
},
{
path: '/home',
name: 'home',
component: Home,
children: [
{
path: 'homea',
name: 'homea',
component: () => import('../views/homea.vue')
},
{
path: 'homeb',
name: 'homeb',
component: () => import('../views/homeb.vue')
}
]
}
]
const router = new VueRouter({
routes
})
export default router
2.4、主页开发
在主页中主要使用el-container
实现通用布局、使用el-menu
实现左侧边栏的导航
<template>
<div>
<el-container>
<el-header style="height:80px; background-color: aliceblue; text-align: center; line-height: 80px; font-size: 24px;">
广告位招商,300万/年
</el-header>
<el-container>
<el-aside style="width:200px; height:700px;">
<h5 style="text-align: center">扬子新闻管理系统</h5>
<el-menu class="el-menu-vertical-demo">
<el-submenu index="1">
<template slot="title">
<i class="el-icon-menu"></i>
<span>新闻管理</span>
</template>
<router-link to="/home/homea">
<el-menu-item index="1-1">管理文章</el-menu-item>
</router-link>
<router-link to="/home/homeb">
<el-menu-item index="1-2">管理栏目</el-menu-item>
</router-link>
</el-submenu>
<router-link to="/home/homeb">
<el-menu-item index="2">
<i class="el-icon-setting"></i>
<span slot="title">系统管理</span>
</el-menu-item>
</router-link>
</el-menu>
</el-aside>
<el-main style="height:700px;">
<router-view/>
</el-main>
</el-container>
</el-container>
</div>
</template>
<style> a:link {
color: black; font-size: 14px; text-decoration: none; } a:hover {
color: #b9b9b9; font-size: 14px; text-decoration: none; } a:visited {
color: black; font-size: 14px; text-decoration: none; } a:active {
color: #b9b9b9; font-size: 14px; text-decoration: none; } </style>
2.5、列表页开发
HTML
<template>
<div>
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="标题" prop="title">
<el-input v-model="queryParams.title" placeholder="请输入标题" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="描述" prop="descn">
<el-input v-model="queryParams.descn" placeholder="请输入描述" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd" >新增
</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="success" plain icon="el-icon-edit" size="mini" :disabled="single" @click="handleUpdate" >修改
</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="danger" plain icon="el-icon-delete" size="mini" :disabled="multiple" @click="handleDelete" >删除
</el-button>
</el-col>
</el-row>
<el-table v-loading="loading" :data="articlelList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center"/>
<el-table-column label="编号" align="center" prop="id"/>
<el-table-column label="标题" align="center" prop="title"/>
<el-table-column label="描述" align="center" prop="descn"/>
<el-table-column label="发布时间" align="center" prop="createTime" width="180">
<!-- <template slot-scope="scope">-->
<!-- <span>{
{ parseTime(scope.row.publishTime, '{y}-{m}-{d}') }}</span>-->
<!-- </template>-->
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" >修改
</el-button>
<el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" >删除
</el-button>
</template>
</el-table-column>
</el-table>
<el-pagination style="margin-top: 20px" v-show="total>0" :total="total" :current-page="queryParams.pageNum" :page-size="queryParams.pageSize" :page-sizes="[5, 15, 20, 50]" layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange" @current-change="handleCurrentChange" />
<!-- 添加或修改栏目对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-form ref="dataForm" :model="form" :rules="rules" label-width="80px">
<el-form-item label="标题" prop="title">
<el-input v-model="form.title" placeholder="请输入标题"/>
</el-form-item>
<el-form-item label="描述" prop="decn">
<el-input v-model="form.decn" placeholder="请输入描述"/>
</el-form-item>
<el-form-item label="发布时间" prop="publishTime">
<el-date-picker clearable v-model="form.publishTime" type="datetime" value-format="yyyy-MM-dd hh:mm:ss" placeholder="请选择发布时间">
</el-date-picker>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm">确 定</el-button>
<el-button @click="cancel">取 消</el-button>
</div>
</el-dialog>
</div>
</template>
业务JavaScript
<script>
export default {
name: "Article",
data() {
return {
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 显示搜索条件
showSearch: true,
// 总条数
total: 0,
// 栏目表格数据
articlelList: [],
// 弹出层标题
title: "",
// 是否显示弹出层
open: false,
// 查询参数
queryParams: {
pageNum: 1,
pageSize: 5,
title: null,
descn: null
},
// 表单参数
form: {
},
// 表单校验
rules: {
title: [
{
required: true, message: '请输入标题', trigger: 'blur' }
],
decn: [
{
required: true, message: '请输入描述', trigger: 'blur' }
],
publishTime: [
{
required: true, message: '请选择发布时间', trigger: 'blur' }
]
}
};
},
created() {
this.getList();
},
methods: {
/** 分页相关*/
handleSizeChange(val) {
console.log(`每页 ${
val} 条`);
this.queryParams.pageSize = val
this.getList()
},
handleCurrentChange(val) {
console.log(`当前页: ${
val}`);
this.queryParams.pageNum = val
this.getList()
},
/** 查询栏目列表 */
getList() {
this.loading = true
this.$axios({
url: 'http://localhost:8070/list',
method: 'get',
params: this.queryParams
}).then(res => {
console.log(res.data)
this.loading = false
this.articlelList = res.data.records
this.total = res.data.total
})
},
// 取消按钮
cancel() {
this.open = false;
this.reset();
},
// 表单重置
reset() {
this.form = {
id: null,
title: null,
descn: null
};
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.$refs["queryForm"].resetFields();
this.handleQuery();
},
// 多选框选中数据
handleSelectionChange(selection) {
//map函数可以返回一个新的数组,数组中的元素为原始数组元素调用函数处理后的值。
this.ids = selection.map(item => item.id)
this.single = selection.length !== 1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加栏目";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const id = row.id || this.ids
console.log("id:"+id)
this.open = true;
this.$axios({
method: 'get',
url: 'http://localhost:8070/get?id='+id,
}).then(res => {
console.log(res.data)
this.form.id = id
this.form.title = res.data.data.title
this.form.decn = res.data.data.descn
this.form.publishTime = res.data.data.createTime
})
},
/** 提交按钮 */
submitForm() {
this.$refs["dataForm"].validate(valid => {
if (valid) {
if (this.form.id != null) {
//修改
this.$axios({
method: 'post',
url: 'http://localhost:8070/edit',
data: {
id: this.form.id,
title: this.form.title,
descn: this.form.decn,
createTime: this.form.publishTime
}
}).then(res => {
if(res.data.code == 200){
this.open = false
this.getList()
} else {
this.$message.error('修改失败')
}
})
} else {
//新增
this.$axios({
method: 'post',
url: 'http://localhost:8070/add',
data: {
title: this.form.title,
descn: this.form.decn
}
}).then(res => {
console.log(res.data)
if(res.data.code == 200){
this.open = false
this.getList()
} else {
this.$message.error('新增失败');
}
})
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids;
this.$confirm('此操作将永久删除该文章, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.$axios({
url: 'http://localhost:8070/remove?ids='+ids,
method: 'post'
}).then(res => {
console.log(res.data)
if(res.data.code == 200){
this.open = false
this.getList()
} else {
this.$message.error('删除失败');
}
})
}).catch(() => {
this.$message({
type: 'info',
message: '已取消删除'
});
});
}
}
};
</script>
2.6、ElementUI常用组件页开发
HTML
<template>
<div>
<el-form ref="myForm" :model="formData" label-width="100px" label-position="left">
<el-form-item label="活动区域:">
<el-select v-model="formData.region" placeholder="请选择活动区域">
<el-option v-for="re in regionList" :label="re.label" :value="re.value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="活动性质:">
<el-checkbox-group v-model="formData.type">
<el-checkbox :label="1">美食/餐厅线上活动</el-checkbox>
<el-checkbox :label="2">地推活动</el-checkbox>
<el-checkbox :label="3">线下主题活动</el-checkbox>
<el-checkbox :label="4">单纯品牌曝光</el-checkbox>
</el-checkbox-group>
</el-form-item>
<el-form-item label="性别:">
<el-radio v-model="formData.sex" :label="1">男</el-radio>
<el-radio v-model="formData.sex" :label="2">女</el-radio>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">立即创建</el-button>
</el-form-item>
</el-form>
</div>
</template>
业务JavaScript
<script>
export default {
data(){
return {
formData: {
region: null,
type: [],
sex: 2
},
regionList: [
{
label : '区域1', value : 'shanghai'},
{
label : '区域2', value : 'beijing'}
]
}
},
methods: {
onSubmit(){
console.log(this.formData.sex)
}
}
}
</script>
文章评论