VUE+Element-ui实战之新增弹出框和编辑弹出框共用一个组件

16 篇文章 10 订阅

实战场景描述

我们在实际开发过程中,增删改查功能是最基础必不可少的,这里就少不了新增和编辑功能,通常都是点击按钮触发弹出框动作。

基本上新增和编辑的表单是一致的,只不过一个是空的,而另一个需要赋原始值。

因此抽出一个组件进行复用,会大大减小代码量。

首先学会点击按钮触发弹出框动作: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>

以上代码需要注意的点:

  1. dialog的引用,为了表单提交方便,我们把“提交”“取消”按钮放到了基础页
  2. el-switch在el-table中的使用
  3. 对于某些字段的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的版本都是一致的,想不出是哪里出了问题,在此说明一下,如果有了解的小伙伴欢迎留言指摘。

  • 17
    点赞
  • 96
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

菜鸟茜

随多随少随你心意^-^

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值