实战场景描述
我们在实际开发过程中,增删改查功能是最基础必不可少的,这里就少不了新增和编辑功能,通常都是点击按钮触发弹出框动作。
基本上新增和编辑的表单是一致的,只不过一个是空的,而另一个需要赋原始值。
因此抽出一个组件进行复用,会大大减小代码量。
首先学会点击按钮触发弹出框动作:VUE弹窗加载另一个VUE页面
1、el-table基本设置
ActivityManage.vue全部代码:
<template>
<div class="mycontainer">
<div>
<h2>活动管理</h2>
<el-divider></el-divider>
<el-form :inline="true" :model="formInline" class="demo-form-inline">
<el-form-item label="活动名称">
<el-input size="mini" v-model="formInline.name"></el-input>
</el-form-item>
<el-form-item>
<el-button @click="onQuery" icon="el-icon-search" size="mini" type="primary">查询</el-button>
<el-button @click="onQuery" icon="el-icon-refresh" size="mini" type="danger">重置</el-button>
</el-form-item>
</el-form>
</div>
<div>
<el-button @click="" icon="el-icon-plus" @click="openWindow" size="mini">添加</el-button>
<el-dialog :visible.sync="windowVisible" append-to-body>
<ActivityWindow v-if="windowVisible" ref="popWindow"></ActivityWindow>
<span slot="footer" class="dialog-footer">
<el-button type="primary" @click="onSubmit">提交</el-button>
<el-button @click="windowVisible = false">取消</el-button>
</span>
</el-dialog>
</div>
<div>
<el-divider></el-divider>
<el-table :data="tableData" border stripe style="width: 100%">
<el-table-column label="活动名称" prop="name">
</el-table-column>
<el-table-column label="活动区域" prop="region"></el-table-column>
<el-table-column label="日期" prop="date1"></el-table-column>
<el-table-column label="时间" prop="date2"></el-table-column>
<el-table-column label="是否推广" prop="isAdvertise" :formatter="formatAdvertise"></el-table-column>
<el-table-column label="即时配送" prop="delivery">
<template slot-scope="scope" >
<el-switch
style="display: block;"
v-model="scope.row.delivery"
active-text="是"
inactive-text="否">
</el-switch>
</template>
</el-table-column>
<el-table-column label="活动性质" prop="type"></el-table-column>
<el-table-column label="特殊资源" prop="resource"></el-table-column>
<el-table-column label="活动形式" prop="desc"></el-table-column>
<el-table-column align="center" label="操作" width="180">
<template slot-scope="scope">
<el-button @click="handleEdit(scope.$index, scope.row)" icon="el-icon-edit" size="mini">编辑</el-button>
<el-button @click="handleDelete(scope.$index, scope.row)" icon="el-icon-delete" size="mini">删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
</div>
</template>
<script>
import ActivityWindow from "@/components/views/ActivityWindow";
export default {
name: 'User',
components: {
ActivityWindow
},
data() {
return {
windowVisible: false,
formInline: {
name: ''
},
tableData: [{
name: '活动名称1',
region: '区域一',
date1: '2020-08-09',
date2: '11:40:00',
isAdvertise:'1',
delivery: false,
type: ['地推活动','线下主题活动'],
resource: '线下场地免费',
desc: '这是一个很好的活动'
},
{
name: '活动名称2',
region: '区域二',
date1: '2020-07-09',
date2: '12:00:00',
isAdvertise:'0',
delivery: true,
type: ['美食/餐厅线上活动','单纯品牌曝光'],
resource: '线上品牌商赞助',
desc: '这是一个很不好的活动'
},
{
name: '活动名称3',
region: '区域一',
date1: '2020-09-09',
date2: '11:43:13',
isAdvertise:'0',
delivery: true,
type: ['美食/餐厅线上活动','线下主题活动','单纯品牌曝光'],
resource: '线上品牌商赞助',
desc: '这是一个ok的活动'
}
]
}
},
methods: {
formatAdvertise(row){
return row.isAdvertise === '1' ? '是' : row.isAdvertise === '0' ? '否' : '未知'
},
openWindow(){
this.windowVisible = true;
},
handleEdit(index, row) {
this.windowVisible = true;
},
onQuery() {
},
handleDelete(index, row) {
console.log(index, row);
},
onSubmit(){
}
},
}
</script>
<style>
.mycontainer {
display: flex;
flex-direction: column;
justify-content: space-around
}
</style>
以上代码需要注意的点:
- dialog的引用,为了表单提交方便,我们把“提交”“取消”按钮放到了基础页
- el-switch在el-table中的使用
- 对于某些字段的formatter
2、抽离出弹窗组件
ActivityWindow.vue完整代码:
<!--一个组件多用,添加/编辑弹窗-->
<template>
<div class="mycontainer">
<el-form ref="form" :model="form" label-width="80px">
<el-form-item label="活动名称">
<el-input v-model="form.name"></el-input>
</el-form-item>
<el-form-item label="活动区域">
<el-select v-model="form.region" placeholder="请选择活动区域">
<el-option label="区域一" value="shanghai"></el-option>
<el-option label="区域二" value="beijing"></el-option>
</el-select>
</el-form-item>
<el-form-item label="活动时间">
<el-col :span="11">
<el-date-picker type="date" placeholder="选择日期" v-model="form.date1" style="width: 100%;"></el-date-picker>
</el-col>
<el-col class="line" :span="2">-</el-col>
<el-col :span="11">
<el-time-select placeholder="选择时间" v-model="form.date2" style="width: 100%;"></el-time-select>
</el-col>
</el-form-item>
<el-form-item label="是否推广">
<el-radio-group v-model="form.isAdvertise">
<el-radio label="1">是</el-radio>
<el-radio label="0">否</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="即时配送">
<el-switch v-model="form.delivery" active-text="是" inactive-text="否"></el-switch>
</el-form-item>
<el-form-item label="活动性质">
<el-checkbox-group v-model="form.type">
<el-checkbox label="美食/餐厅线上活动" name="type"></el-checkbox>
<el-checkbox label="地推活动" name="type"></el-checkbox>
<el-checkbox label="线下主题活动" name="type"></el-checkbox>
<el-checkbox label="单纯品牌曝光" name="type"></el-checkbox>
</el-checkbox-group>
</el-form-item>
<el-form-item label="特殊资源">
<el-radio-group v-model="form.resource">
<el-radio label="线上品牌商赞助"></el-radio>
<el-radio label="线下场地免费"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="活动形式">
<el-input type="textarea" v-model="form.desc"></el-input>
</el-form-item>
</el-form>
</div>
</template>
<script>
export default {
name: '',
components: {},
data() {
return {
form: {
name: '',
region: '',
date1: '',
date2: '',
isAdvertise:'',
delivery: false,
type: [],
resource: '',
desc: ''
}
}
},
methods: {
},
}
</script>
<style>
.mycontainer {
display: flex;
flex-direction: column;
justify-content: space-around
}
</style>
至此,我们只是给添加和编辑按钮弹窗动作。
3、编辑时设置form表单初始化
首先点击编辑按钮,会将表格的row数据提取出来,而这个row就是编辑弹窗的初始表单,因此需要有一个表单的传递和接收过程。
在基础页传递参数给弹窗
this.$nextTick(()=>{
this.$refs.popWindow.dataInit(row);
})
弹窗接收参数并复制给form表单
dataInit(data){
if(data){
this.form = data;
}
},
4、表单提交时做添加/编辑状态的区分
因为两个操作共用一个组件,在提交时还需要一个参数做区分,然后根据这个参数状态确定对应的axious
5、最终呈现效果:
6、页面完整代码
ActivityManage.vue完整代码:
<template>
<div class="mycontainer">
<div>
<h2>活动管理</h2>
<el-divider></el-divider>
<el-form :inline="true" :model="formInline" class="demo-form-inline">
<el-form-item label="活动名称">
<el-input size="mini" v-model="formInline.name"></el-input>
</el-form-item>
<el-form-item>
<el-button @click="onQuery" icon="el-icon-search" size="mini" type="primary">查询</el-button>
<el-button @click="onQuery" icon="el-icon-refresh" size="mini" type="danger">重置</el-button>
</el-form-item>
</el-form>
</div>
<div>
<el-button @click="" icon="el-icon-plus" @click="openWindow" size="mini">添加</el-button>
<el-dialog :visible.sync="windowVisible" append-to-body>
<ActivityWindow v-if="windowVisible" ref="popWindow"></ActivityWindow>
<span slot="footer" class="dialog-footer">
<el-button type="primary" @click="onSubmit">提交</el-button>
<el-button @click="windowVisible = false">取消</el-button>
</span>
</el-dialog>
</div>
<div>
<el-divider></el-divider>
<el-table :data="tableData" border stripe style="width: 100%">
<el-table-column label="活动名称" prop="name">
</el-table-column>
<el-table-column label="活动区域" prop="region"></el-table-column>
<el-table-column label="日期" prop="date1"></el-table-column>
<el-table-column label="时间" prop="date2"></el-table-column>
<el-table-column label="是否推广" prop="isAdvertise" :formatter="formatAdvertise"></el-table-column>
<el-table-column label="即时配送" prop="delivery">
<template slot-scope="scope" >
<el-switch
style="display: block;"
v-model="scope.row.delivery"
active-text="是"
inactive-text="否">
</el-switch>
</template>
</el-table-column>
<el-table-column label="活动性质" prop="type"></el-table-column>
<el-table-column label="特殊资源" prop="resource"></el-table-column>
<el-table-column label="活动形式" prop="desc"></el-table-column>
<el-table-column align="center" label="操作" width="180">
<template slot-scope="scope">
<el-button @click="handleEdit(scope.$index, scope.row)" icon="el-icon-edit" size="mini">编辑</el-button>
<el-button @click="handleDelete(scope.$index, scope.row)" icon="el-icon-delete" size="mini">删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
</div>
</template>
<script>
import ActivityWindow from "@/components/views/ActivityWindow";
export default {
name: 'User',
components: {
ActivityWindow
},
data() {
return {
windowVisible: false,
addOperate: undefined,
formInline: {
name: ''
},
tableData: [{
name: '活动名称1',
region: '区域一',
date1: '2020-08-09',
date2: '11:40:00',
isAdvertise:'1',
delivery: false,
type: ['地推活动','线下主题活动'],
resource: '线下场地免费',
desc: '这是一个很好的活动'
},
{
name: '活动名称2',
region: '区域二',
date1: '2020-07-09',
date2: '12:00:00',
isAdvertise:'0',
delivery: true,
type: ['美食/餐厅线上活动','单纯品牌曝光'],
resource: '线上品牌商赞助',
desc: '这是一个很不好的活动'
},
{
name: '活动名称3',
region: '区域一',
date1: '2020-09-09',
date2: '11:43:13',
isAdvertise:'0',
delivery: true,
type: ['美食/餐厅线上活动','线下主题活动','单纯品牌曝光'],
resource: '线上品牌商赞助',
desc: '这是一个ok的活动'
}
]
}
},
methods: {
formatAdvertise(row){
return row.isAdvertise === '1' ? '是' : row.isAdvertise === '0' ? '否' : '未知'
},
openWindow(){
this.windowVisible = true;
this.addOperate = true;
},
handleEdit(index, row) {
this.windowVisible = true;
this.addOperate = false;
this.$nextTick(()=>{
this.$refs.popWindow.dataInit(row);
});
},
onSubmit(){
//需要提交的form表单
var form = this.$refs.popWindow.form;
if (this.addOperate) {
//axious 添加新增
}else{
//axious 编辑修改
}
},
onQuery() {
},
handleDelete(index, row) {
console.log(index, row);
},
},
}
</script>
<style>
.mycontainer {
display: flex;
flex-direction: column;
justify-content: space-around
}
</style>
ActivityWindow.vue完整代码:
<!--一个组件多用,添加/编辑弹窗-->
<template>
<div class="mycontainer">
<el-form ref="form" :model="form" label-width="80px">
<el-form-item label="活动名称">
<el-input v-model="form.name"></el-input>
</el-form-item>
<el-form-item label="活动区域">
<el-select v-model="form.region" placeholder="请选择活动区域">
<el-option label="区域一" value="shanghai"></el-option>
<el-option label="区域二" value="beijing"></el-option>
</el-select>
</el-form-item>
<el-form-item label="活动时间">
<el-col :span="11">
<el-date-picker type="date" placeholder="选择日期" v-model="form.date1" style="width: 100%;"></el-date-picker>
</el-col>
<el-col class="line" :span="2">-</el-col>
<el-col :span="11">
<el-time-select placeholder="选择时间" v-model="form.date2" style="width: 100%;"></el-time-select>
</el-col>
</el-form-item>
<el-form-item label="是否推广">
<el-radio-group v-model="form.isAdvertise">
<el-radio label="1">是</el-radio>
<el-radio label="0">否</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="即时配送">
<el-switch v-model="form.delivery" active-text="是" inactive-text="否"></el-switch>
</el-form-item>
<el-form-item label="活动性质">
<el-checkbox-group v-model="form.type">
<el-checkbox label="美食/餐厅线上活动" name="type"></el-checkbox>
<el-checkbox label="地推活动" name="type"></el-checkbox>
<el-checkbox label="线下主题活动" name="type"></el-checkbox>
<el-checkbox label="单纯品牌曝光" name="type"></el-checkbox>
</el-checkbox-group>
</el-form-item>
<el-form-item label="特殊资源">
<el-radio-group v-model="form.resource">
<el-radio label="线上品牌商赞助"></el-radio>
<el-radio label="线下场地免费"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="活动形式">
<el-input type="textarea" v-model="form.desc"></el-input>
</el-form-item>
</el-form>
</div>
</template>
<script>
export default {
name: '',
components: {},
data() {
return {
form: {
name: '',
region: '',
date1: '',
date2: '',
isAdvertise:'',
delivery: false,
type: [],
resource: '',
desc: ''
}
}
},
methods: {
dataInit(data){
if(data){
this.form = data;
console.info(data);
}
},
},
}
</script>
<style>
.mycontainer {
display: flex;
flex-direction: column;
justify-content: space-around
}
</style>
一点疑问
在给编辑弹窗赋初始值时,遇到一个很费解的小问题,给radio赋初始值,我在其他项目中都是用以下这种形式的:
<el-form-item label="性别">
<el-radio-group v-model="form.sex">
<el-radio :label="1">男</el-radio>
<el-radio :label="0">女</el-radio>
</el-radio-group>
</el-form-item>
但是这个测试项目中如法炮制却不行,没办法默认选中初始值,最后试着用了这样的,没想到可以啦
<el-form-item label="是否推广">
<el-radio-group v-model="form.isAdvertise">
<el-radio label="1">是</el-radio>
<el-radio label="0">否</el-radio>
</el-radio-group>
</el-form-item>
我比较了两个项目中用到的vue和Element-UI的版本都是一致的,想不出是哪里出了问题,在此说明一下,如果有了解的小伙伴欢迎留言指摘。