vue-cli3 + express + mongodb小型全栈项目(一)
vue-cli3 + express + mongodb小型全栈项目(二)
1、添加左侧导航
1.1 components文件夹下新建LeftMenu.vue组件
<template>
<el-row class="menu_page">
<el-col>
<el-menu
mode="vertical"
background-color="#324057"
text-color="#fff"
active-text-color="#409eff"
class="el-menu-vertical-demo">
<router-link to="/home">
<el-menu-item index="0">
<i class="fa fa-margin fa-server"></i>
<span slot="title">首页</span>
</el-menu-item>
</router-link>
<template v-for="item in items" >
<el-submenu v-if="item.children" :index="item.path" :key="item.path">
<template slot="title">
<i :class="'fa fa-margin '+item.icon"></i>
<span slot="title">{{item.name}}</span>
</template>
<router-link v-for="(citem,cindex) in item.children"
:to="citem.path" :key="cindex">
<el-menu-item
:index='citem.path'>
<span slot="title">{{citem.name}}</span>
</el-menu-item>
</router-link>
</el-submenu>
</template>
</el-menu>
</el-col>
</el-row>
</template>
<script>
export default {
name: "leftmenu",
data() {
return {
items: [
{
icon: "fa-money",
name: "资金管理",
path: "fund",
children: [{ path: "foundlist", name: "资金流水" }]
},
{
icon: "fa-asterisk",
name: "信息管理",
path: "info",
children: [{ path: "infoshow", name: "个人信息" }]
}
]
};
}
};
</script>
<style scoped>
.menu_page {
position: fixed;
top: 71px;
left: 0;
min-height: 100%;
background-color: #324057;
z-index: 99;
}
.el-menu {
border: none;
}
.fa-margin {
margin-right: 5px;
}
.el-menu-vertical-demo:not(.el-menu--collapse) {
width: 180px;
min-height: 400px;
}
.el-menu-vertical-demo {
width: 35px;
}
.el-submenu .el-menu-item {
min-width: 180px;
}
.hiddenDropdown,
.hiddenDropname {
display: none;
}
a {
text-decoration: none;
}
</style>
1.2 Index.vue修改后如下
<template>
<div class="index">
<HeadNav></HeadNav>
<LeftMenu></LeftMenu>
<div class="rightContainer">
<router-view></router-view>
</div>
</div>
</template>
<script>
import HeadNav from "../components/HeadNav";
import LeftMenu from "../components/LeftMenu";
export default {
name: "index",
components: {
HeadNav,
LeftMenu
}
};
</script>
<style scoped>
.index {
width: 100%;
height: 100%;
overflow: hidden;
}
.rightContainer {
position: relative;
top: 0;
left: 180px;
width: calc(100% - 180px);
height: calc(100% - 71px);
overflow: auto;
}
</style>
2、添加
2.1 views文件夹下新建FundList.vue
<template>
<div class="fillcontain">
<div>
<el-form
:inline="true"
ref="search_data"
:model='search_data' >
<el-form-item label="投标时间筛选:">
<el-date-picker
v-model="search_data.startTime"
type="datetime"
placeholder="选择开始时间">
</el-date-picker> --
<el-date-picker
v-model="search_data.endTime"
type="datetime"
placeholder="选择结束时间">
</el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" size ="small" icon="search" @click='onScreeoutMoney()'>筛选</el-button>
</el-form-item>
<el-form-item class="btnRight">
<el-button type="primary" size ="small" icon="view" @click='onAddMoney()'>添加</el-button>
</el-form-item>
</el-form>
</div>
<div class="table_container">
<el-table
v-if="tableData.length > 0"
:data='tableData'
max-height="450"
border
:default-sort = "{prop: 'date', order: 'descending'}"
style="width: 100%">
<el-table-column
type="index"
label="序号"
align='center'
width="70">
</el-table-column>
<el-table-column
prop="date"
label="创建时间"
align='center'
width="250"
sortable>
<template slot-scope="scope">
<el-icon name="time"></el-icon>
<span style="margin-left: 10px">{{ scope.row.date }}</span>
</template>
</el-table-column>
<el-table-column
prop="type"
label="收支类型"
align='center'
width="150">
</el-table-column>
<el-table-column
prop="describe"
label="收支描述"
align='center'
width="180">
</el-table-column>
<el-table-column
prop="income"
label="收入"
align='center'
width="170">
<template slot-scope="scope">
<span style="color:#00d053">+ {{ scope.row.income }}</span>
</template>
</el-table-column>
<el-table-column
prop="expend"
label="支出"
align='center'
width="170">
<template slot-scope="scope">
<span style="color:#f56767">- {{ scope.row.expend }}</span>
</template>
</el-table-column>
<el-table-column
prop="cash"
label="账户现金"
align='center'
width="170">
<template slot-scope="scope">
<span style="color:#4db3ff">{{ scope.row.cash }}</span>
</template>
</el-table-column>
<el-table-column
prop="remark"
label="备注"
align='center'
width="220">
</el-table-column>
<el-table-column
prop="operation"
align='center'
label="操作"
fixed="right"
width="180">
<template slot-scope='scope'>
<el-button
type="warning"
icon='edit'
size="small"
@click='onEditMoney(scope.row)'
>编辑</el-button>
<el-button
type="danger"
icon='delete'
size="small"
@click='onDeleteMoney(scope.row,scope.$index)'
>删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<el-row>
<el-col :span="24">
<div class="pagination">
<el-pagination
v-if='paginations.total > 0'
:page-sizes="paginations.page_sizes"
:page-size="paginations.page_size"
:layout="paginations.layout"
:total="paginations.total"
:current-page.sync='paginations.page_index'
@current-change='handleCurrentChange'
@size-change='handleSizeChange'>
</el-pagination>
</div>
</el-col>
</el-row>
</div>
<!-- 弹框页面 -->
<DialogFound :dialog='dialog' :form='form' @update="getProfile"></DialogFound>
</div>
</template>
<script>
import DialogFound from "../components/DialogFound";
export default {
name: "fundlist",
data() {
return {
tableData: [],
allTableData: [],
filterTableData: [],
dialog: {
show: false,
title: "",
option: "edit"
},
form: {
type: "",
describe: "",
income: "",
expend: "",
cash: "",
remark: "",
id: ""
},
//需要给分页组件传的信息
paginations: {
page_index: 1, // 当前位于哪页
total: 0, // 总数
page_size: 5, // 1页显示多少条
page_sizes: [5, 10, 15, 20], //每页显示多少条
layout: "total, sizes, prev, pager, next, jumper" // 翻页属性
},
search_data: {
startTime: "",
endTime: ""
}
};
},
components: {
DialogFound
},
created() {
this.getProfile();
},
methods: {
getProfile() {
// 获取表格数据
this.axios("/api/profiles").then(res => {
// this.tableData = res.data;
this.allTableData = res.data;
this.filterTableData = res.data;
// 设置分页数据
this.setPaginations();
});
},
onEditMoney(row) {
// 编辑
this.dialog = {
show: true,
title: "修改资金信息",
option: "edit"
};
this.form = {
type: row.type,
describe: row.describe,
income: row.income,
expend: row.expend,
cash: row.cash,
remark: row.remark,
id: row._id
};
},
onDeleteMoney(row, index) {
// 删除
this.axios.delete(`/api/profiles/delete/${row._id}`).then(res => {
this.$message("删除成功");
this.getProfile();
});
},
onAddMoney() {
// 添加
this.dialog = {
show: true,
title: "添加资金信息",
option: "add"
};
this.form = {
type: "",
describe: "",
income: "",
expend: "",
cash: "",
remark: "",
id: ""
};
},
handleCurrentChange(page) {
// 当前页
let sortnum = this.paginations.page_size * (page - 1);
let table = this.allTableData.filter((item, index) => {
return index >= sortnum;
});
// 设置默认分页数据
this.tableData = table.filter((item, index) => {
return index < this.paginations.page_size;
});
},
handleSizeChange(page_size) {
// 切换size
this.paginations.page_index = 1;
this.paginations.page_size = page_size;
this.tableData = this.allTableData.filter((item, index) => {
return index < page_size;
});
},
setPaginations() {
// 总页数
this.paginations.total = this.allTableData.length;
this.paginations.page_index = 1;
this.paginations.page_size = 5;
// 设置默认分页数据
this.tableData = this.allTableData.filter((item, index) => {
return index < this.paginations.page_size;
});
},
onScreeoutMoney() {
// 筛选
if (!this.search_data.startTime || !this.search_data.endTime) {
this.$message({
type: "warning",
message: "请选择时间区间"
});
this.getProfile();
return;
}
const stime = this.search_data.startTime.getTime();
const etime = this.search_data.endTime.getTime();
this.allTableData = this.filterTableData.filter(item => {
let date = new Date(item.date);
let time = date.getTime();
return time >= stime && time <= etime;
});
// 分页数据
this.setPaginations();
}
}
};
</script>
<style scoped>
.fillcontain {
width: 100%;
height: 100%;
padding: 16px;
box-sizing: border-box;
}
.btnRight {
float: right;
}
.pagination {
text-align: right;
margin-top: 10px;
}
</style>
2.2 components新建DialogFound.vue文件
<template>
<div class="logFund">
<el-dialog
:title="dialog.title"
:visible.sync="dialog.show"
:close-on-click-modal='false'
:close-on-press-escape='false'
:modal-append-to-body="false">
<div class="form">
<el-form
ref="form"
:model="form"
:rules="form_rules"
label-width="120px"
style="margin:10px;width:auto;">
<el-form-item label="收支类型:" >
<el-select v-model="form.type" placeholder="收支类型">
<el-option
v-for="(formtype, index) in format_type_list"
:key="index"
:label="formtype" :value="formtype"
></el-option>
</el-select>
</el-form-item>
<el-form-item prop='describe' label="收支描述:">
<el-input type="describe" v-model="form.describe"></el-input>
</el-form-item>
<el-form-item prop='income' label="收入:">
<el-input type="income" v-model="form.income"></el-input>
</el-form-item>
<el-form-item prop='expend' label="支出:">
<el-input type="expend" v-model="form.expend"></el-input>
</el-form-item>
<el-form-item prop='cash' label="账户现金:">
<el-input type="cash" v-model="form.cash"></el-input>
</el-form-item>
<el-form-item label="备注:">
<el-input type="textarea" v-model="form.remark"></el-input>
</el-form-item>
<el-form-item class="text_right">
<el-button @click="dialog.show = false">取 消</el-button>
<el-button type="primary" @click='onSubmit("form")'>提 交</el-button>
</el-form-item>
</el-form>
</div>
</el-dialog>
</div>
</template>
<script>
export default {
name: "logfound",
props: {
dialog: Object,
form: Object
},
data() {
return {
format_type_list: [
"提现",
"提现手续费",
"充值",
"优惠券",
"充值礼券",
"转账"
],
form_rules: {
describe: [
{ required: true, message: "收支描述不能为空!", trigger: "blur" }
],
income: [
{ required: true, message: "收入不能为空!", trigger: "blur" }
],
expend: [
{ required: true, message: "支出不能为空!", trigger: "blur" }
],
cash: [{ required: true, message: "账户不能为空!", trigger: "blur" }]
}
};
},
methods: {
onSubmit(form) {
this.$refs[form].validate(valid => {
if (valid) {
//表单数据验证完成之后,提交数据;
const url =
this.dialog.option == "add" ? "add" : `edit/${this.form.id}`;
this.axios.post(`/api/profiles/${url}`, this.form).then(res => {
// 操作成功
this.$message({
message: "保存成功!",
type: "success"
});
this.dialog.show = false;
this.$emit("update");
});
}
});
}
}
};
</script>
2.3 路由添加FoundList
import FoundList from './../views/FoundList'
const routes = [
{
path:'/index',
component:Index,
children:[
{
path:'/foundlist',
component:FoundList,
}
]
},
]
完成项目截个图
源码:项目源码