Vue + ElementUI 编辑/新增页面复用总结

Posted 在奋斗的大道

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue + ElementUI 编辑/新增页面复用总结相关的知识,希望对你有一定的参考价值。

前景需求

最近编写简单crm后台管理类项目,涉及到表单的使用上,有着大量的相同内容的表单,根据使用场景分为新建表单编辑表单

实战:实现一个客户等级管理功能,其中包含客户等级列表,新建客户等级,修改客户等级信息功能。 

客户等级列表:

新建客户等级:

修改客户等级:

从上面图中可以看出,客户等级的编辑表单和删除表单基本一致。 

功能实现

实现方式一:

<style>
</style>
<template>
      <el-card class="full-height full-width">
        <search-table class="full-height full-width"
            :table-loading="loading"
            :tableData="tableData"
            :ref="tableRef"
            :labelWidth="'40px'"
            :row-keys="row => row.id"
            @query="currentPage = 1; query();"
            @reset="doReset"
            @selectionChange="selectionChange">
            <template v-slot:row>
                <el-form-item label="名称">
                    <el-input placeholder="请输入名称" v-model="searchForm.name" clearable></el-input>
                </el-form-item>
                <el-form-item label="标识">
                    <el-select placeholder="请选择" v-model="searchForm.mark" clearable>
                        <el-option :label="'启用'" :value="1"></el-option>
                        <el-option :label="'删除'" :value="2"></el-option>
                    </el-select>
                </el-form-item>
            </template>
            <template v-slot:actions>
                <el-button size="small" type="primary" v-on:click="addLevel()">新 建</el-button>
                <el-button size="small" type="primary" v-on:click="editLevel()">编 辑</el-button>
                <el-button size="small" type="primary" v-on:click="handlerDelete()">删除/批量删除</el-button>
            </template>
            <template >
                <el-table-column :reserve-selection="true" type="selection" width="55" />
                <el-table-column prop="name" label="名称" show-overflow-tooltip />
                <el-table-column prop="mark" label="标识" :formatter="formatMarkType" show-overflow-tooltip />
                <el-table-column prop="introduction" label="描述" show-overflow-tooltip />
            </template>
            <template v-slot:footer>
                <el-pagination
                    background
                    :current-page="currentPage"
                    :page-sizes="pageSizes"
                    :page-size="pageSize"
                    layout="total, sizes, prev, pager, next, jumper"
                    :total="total"
                     @size-change="handleSizeChange"
                     @current-change="handleCurrentChange" />
            </template>
        </search-table>

        <el-dialog title="添加客户等级" :visible.sync="dialogFormAdd" size="tiny">
            <el-form id="#addsForm"  ref="addsForm" :model="level" label-width="80px" >
                    <el-form-item label="等级名称" >
                        <el-col :span="7">
                            <el-input v-model="level.name" auto-complete="off" ></el-input>
                        </el-col>
                    </el-form-item>
                    <el-form-item label="等级标识" >
                        <el-col :span="7">
                            <el-select v-model="level.mark" value-key="id">
                                <el-option v-for="item in markArry"  :key="item.id" :label="item.name" :value="item.id"></el-option>
                            </el-select>
                        </el-col>
                    </el-form-item>
                    <el-form-item label="等级描述" >
                        <el-col :span="7">
                            <el-input v-model="level.introduction" auto-complete="off"></el-input>
                        </el-col>
                    </el-form-item>
            </el-form>
            <div slot="footer" class="dialog-footer">
                        <el-button @click="dialogFormAdd = false">取 消</el-button>
                        <el-button type="primary" @click="add(level)">确 定</el-button>
                    </div>
        </el-dialog>

        <el-dialog title="修改客户等级" :visible.sync="dialogFormEdit" size="tiny">
            <el-form id="#addsForm"  ref="addsForm" :model="level" label-width="80px" >
                    <el-form-item label="等级名称" >
                        <el-col :span="7">
                            <el-input v-model="level.name" auto-complete="off" ></el-input>
                        </el-col>
                    </el-form-item>
                    <el-form-item label="等级标识" >
                        <el-col :span="7">
                            <el-select v-model="level.mark" value-key="id">
                                <el-option v-for="item in markArry"  :key="item.id" :label="item.name" :value="item.id"></el-option>
                            </el-select>
                        </el-col>
                    </el-form-item>
                    <el-form-item label="等级描述" >
                        <el-col :span="7">
                            <el-input v-model="level.introduction" auto-complete="off"></el-input>
                        </el-col>
                    </el-form-item>
            </el-form>
            <div slot="footer" class="dialog-footer">
                        <el-button @click="dialogFormEdit = false">取 消</el-button>
                        <el-button type="primary" @click="edit(level)">确 定</el-button>
                    </div>
        </el-dialog>
      
      
       
      </el-card>

      


</template>
<script>
import SearchTable from '@/components/searchTable'
import { Message} from "element-ui";
import {getLevelPage, batchLevelDelete, levelInsert, levelGetById, levelUpdate} from "@/api/level";
export default{
    name: 'customer',
    components: {
        SearchTable
    },
     data () {
        return {
            tableData: [],
            loading: false,
            tableRef: 'tableRef',
            searchForm: {},
            currentPage: 1,
            pageSizes: [10, 20, 50],
            pageSize: 10,
            total: 0,
            selectionList:[], //定义删除/批量删除
            dialogFormAdd:false,
            dialogFormEdit: false,
            level:{
                id: '',
                name: '',
                introduction: '',
                mark: ''
            },
            markArry:[{
                "id": 1,
                "name": "启用"
            },{
                "id": 2,
                "name": "删除"
            }],

        };
    },
    created() {
      this.query()
    },
    methods: {
        query() {
            // 请求表格数据
        var params ={
          'pageNum': this.currentPage,
          'pageSize': this.pageSize,
          'name':this.searchForm.name,
          'mark':this.searchForm.mark
         }
        getLevelPage(params).then(res => {
                console.log(res)
                // 把请求到的数据给testDatas数组
                this.tableData = res.data.list
                // 当前页数
                this.currentPage = res.data.pageNum
                // 当前页数量
                this.pageSize = res.data.pageSize
                // 分页总数
                this.total = res.data.total
              //   console.log(JSON.stringify(res.data.data.total))
            })
            .catch((error) => {
             console.log(error)
            })

        },
        doReset() {
            // 重置搜索条件
             // 请求表格数据
              this.tableData = [];
              this.restForm();
              this.query();
        

        },
        restForm(){
            this.searchForm.name = ""
            this.searchForm.mark = ""
        },
        selectionChange(val) {
            // 表格选项发生变化
            console.log("触发表格事件")

            this.selectionList = []
		    val.forEach(element => {
		        this.selectionList.push(element.id)
		    });
          
        },
        handlerDelete(){
              // 数组转字符串使用逗号分隔
            let sids =  this.selectionList.join(",")
            var params ={
                'sids': sids
            }
            batchLevelDelete(params).then(res =>{
                Message({
                    message: '批量删除成功',
                    type: 'success',
                    duration: 3 * 1000
                })
                // 重新查询表格
                this.query()
            }).catch((error) => {
             console.log(error)
            })
            
        },
        handleSizeChange(val) {
            // 改变每页条数
            this.pageSize = val
            this.query()
        },
        handleCurrentChange(val) {
            // 切换页码
            this.currentPage = val
            this.query()
        },
        // table 数据转换
        formatMarkType(row, column){
             if(row.mark === 1){
                     return '启用'
                 } else if(row.mark === 2) {
                     return '删除'
                 } else {
                     return ''
                 }
        },
        // 新增客户
        addLevel(){
            this.dialogFormAdd = true
            this.level = {}
        },
        // 修改客户
        editLevel(){
            // console.log('下标', index)
            // console.log('数据', row)
            console.log(this.selectionList)
             console.log(typeof(this.selectionList))
            let id = this.selectionList[0]
             var params = {
                 'id' : id
             }
            levelGetById(params).then(res =>{
                // 
                this.level = {}
                this.level = res.data
                this.dialogFormEdit = true
              
            }).catch((error) => {
                console.log(error)
            })
            
        },
     
        add(level){
            levelInsert(level).then(res =>{
                 Message({
                    message: '客户等级新增成功',
                    type: 'success',
                    duration: 3 * 1000
                })
                // 新增弹出框隐藏
                this.dialogFormAdd = false
                // 重新查询表格
                this.query()
            }).catch((error) => {
             console.log(error)
            })
        },
        edit(level){
             levelUpdate(level.id, level).then(res =>{
                 Message({
                    message: '客户等级修改成功',
                    type: 'success',
                    duration: 3 * 1000
                })
                // 新增弹出框隐藏
                this.dialogFormEdit = false
                // 重新查询表格
                this.query()
            }).catch((error) => {
             console.log(error)
            })
        }
    }
}
</script>

总结:针对客户等级的新建与修改

没有封装,实现一个功能后,另一个功能代码直接复制。开发过程中见过不少人采用这种方式进行开发,这可能是完成功能最快的方式,同时也是带来问题最多的。

  • 不容易维护,复制的代码中如果存在bug,相当于将bug也复制了一份。后续解决bug,或者添加新功能需要花经历修改两处代码。比如:表单需要增加一项出生年月的表单项,需要在添加和编辑的代码中都进行修改。
  • 代码冗余重复率高,常见的代码质量管理的工具中都会包含有重复率一项。
  • … 总之,复制粘贴代码违反了DRY原则:系统的每一个功能都应该有唯一的实现。如果多次遇到同样的问题,就应该抽象出一个共同的解决方法,不要重复开发同样的功能。

方式二:组件封住(封装组件,提取整个弹窗)

定义:客户等级通用表单(levelCommon.vue)

<style>
</style>
<template>
     <el-dialog :title="title" :visible="visible" size="tiny">
             <el-form ref="LevelForm" :model="level" :rules="rules" label-width="80px" >
                    <el-form-item label="等级名称" prop="name" >
                        <el-col :span="7">
                            <el-input v-model="level.name" auto-complete="off" ></el-input>
                        </el-col>
                    </el-form-item>
                    <el-form-item label="等级标识" >
                        <el-col :span="7">
                            <el-select v-model="level.mark" value-key="id" prop="mark">
                                <el-option v-for="item in markArry"  :key="item.id" :label="item.name" :value="item.id"></el-option>
                            </el-select>
                        </el-col>
                    </el-form-item>
                    <el-form-item label="等级描述" >
                        <el-col :span="7">
                            <el-input v-model="level.introduction" prop="introduction" auto-complete="off"></el-input>
                        </el-col>
                    </el-form-item>
            </el-form>
               <template slot="footer" class="dialog-footer">
                        <el-button @click="handleVisibleChange(false)">取 消</el-button>
                        <el-button type="primary" @click="handleSave">确 定</el-button>
                </template>
     </el-dialog>
</template>
 
<script>
export default{
    name: "LevelForm",
    props: {
      // 是否显示表单
      visible: {
        type: Boolean,
        default: false
      },
      // 弹窗的title
      title: String,
      // 回显数据
      model: {
        type: Object,
        default: null
      }
    },
     data() {
      return {
        level: {
          id: '',
          mark: '',
          name: '',
          introduction: ''
        },
        rules: {
          name: {required: true, message: '请输入姓名', trigger: 'blur'},
          mark: {required: true, message: '请输入标记', trigger: 'blur'},
          introduction: {required: true, message: '请输入描述', trigger: 'blur'}
        },
        markArry:[
            {
                "id": 1,
                "name": '启用'
            },
            {
                "id": 2,
                "name": '删除'
            }
        ]
      }
    },
    watch: {
      // 监听 编辑时回显表单
      model(levelInfo) {
          this.level = {...levelInfo} // 简单的浅克隆
        }
    },
    methods: {
      handleSave() {
        // 表单验证 返回数据
        this.$refs.LevelForm.validate((valid) => {
          if (valid) {
            this.$emit('save', this.level)
            // 实体对象重置
            this.level ={}
          }
        })
      },
      handleVisibleChange(value) {
        this.$emit('update:visible', value)
      }
    }
}
</script>

 重点备注:父组件,通过props向子组件表单组件传递一些必要的数据(标题、是否显示、model 对象),即实现了新增和编辑功能。

在编辑时,通过传入名为model的props,子组件表单中通过watch的model的变化实现表单的回显。

封住组件调用:

<style>
</style>
<template>
      <el-card class="full-height full-width">
        <search-table class="full-height full-width"
            :table-loading="loading"
            :tableData="tableData"
            :ref="tableRef"
            :labelWidth="'40px'"
            :row-keys="row => row.id"
            @query="currentPage = 1; query();"
            @reset="doReset"
            @selectionChange="selectionChange">
            <template v-slot:row>
                <el-form-item label="名称">
                    <el-input placeholder="请输入名称" v-model="searchForm.name" clearable></el-input>
                </el-form-item>
                <el-form-item label="标识">
                    <el-select placeholder="请选择" v-model="searchForm.mark" clearable>
                        <el-option :label="'启用'" :value="1"></el-option>
                        <el-option :label="'删除'" :value="2"></el-option>
                    </el-select>
                </el-form-item>
            </template>
            <template v-slot:actions>
                <el-button size="small" type="primary" v-on:click="addLevel()">新 建</el-button>
                <el-button size="small" type="primary" v-on:click="editLevel()">编 辑</el-button>
                <el-button size="small" type="primary" v-on:click="handlerDelete()">删除/批量删除</el-button>
            </template>
            <template >
                <el-table-column :reserve-selection="true" type="selection" width="55" />
                <el-table-column prop="name" label="名称" show-overflow-tooltip />
                <el-table-column prop="mark" label="标识" :formatter="formatMarkType" show-overflow-tooltip />
                <el-table-column prop="introduction" label="描述" show-overflow-tooltip />
            </template>
            <template v-slot:footer>
                <el-pagination
                    background
                    :current-page="currentPage"
                    :page-sizes="pageSizes"
                    :page-size="pageSize"
                    layout="total, sizes, prev, pager, next, jumper"
                    :total="total"
                     @size-change="handleSizeChange"
                     @current-change="handleCurrentChange" />
            </template>
        </search-table>

        <levelCommon
             title="新增客户等级"
            :visible.sync="dialogFormAdd"
            @save="add"
        ></levelCommon>

        <levelCommon
            :model="level"
             title="修改客户等级"
            :visible.sync="dialogFormEdit"
            @save="edit"
        ></levelCommon>

      </el-card>

      


</template>
<script>
import SearchTable from '@/components/searchTable'
import levelCommon from '../levelCommon'
import { Message} from "element-ui";
import {getLevelPage, batchLevelDelete, levelInsert, levelGetById, levelUpdate} from "@/api/level";
export default{
    name: 'customer',
    components: {
        SearchTable,
        levelCommon
    },
     data () {
        return {
            tableData: [],
            loading: false,
            tableRef: 'tableRef',
            searchForm: {},
            currentPage: 1,
            pageSizes: [10, 20, 50],
            pageSize: 10,
            total: 0,
            selectionList:[], //定义删除/批量删除
            dialogFormAdd:false,
            dialogFormEdit: false,
            level:{
                id: '',
                name: '',
                introduction: '',
                mark: ''
            },
            markArry:[{
                "id": 1,
                "name": "启用"
            },{
                "id": 2,
                "name": "删除"
            }],

        };
    },
    created() {
      this.query()
    },
    methods: {
        query() {
            // 请求表格数据
        var params ={
          'pageNum': this.currentPage,
          'pageSize': this.pageSize,
          'name':this.searchForm.name,
          'mark':this.searchForm.mark
         }
        getLevelPage(params).then(res => {
                console.log(res)
                // 把请求到的数据给testDatas数组
                this.tableData = res.data.list
                // 当前页数
                this.currentPage = res.data.pageNum
                // 当前页数量
                this.pageSize = res.data.pageSize
                // 分页总数
                this.total = res.data.total
              //   console.log(JSON.stringify(res.data.data.total))
            })
            .catch((error) => {
             console.log(error)
            })

        },
        doReset() {
            // 重置搜索条件
             // 请求表格数据
              this.tableData = [];
              this.restForm();
              this.query();
        

        },
        restForm(){
            this.searchForm.name = ""
            this.searchForm.mark = ""
        },
        selectionChange(val) {
            // 表格选项发生变化
            console.log("触发表格事件")

            this.selectionList = []
		    val.forEach(element => {
		        this.selectionList.push(element.id)
		    });
          
        },
        handlerDelete(){
              // 数组转字符串使用逗号分隔
            let sids =  this.selectionList.join(",")
            var params ={
                'sids': sids
            }
            batchLevelDelete(params).then(res =>{
                Message({
                    message: '批量删除成功',
                    type: 'success',
                    duration: 3 * 1000
                })
                // 重新查询表格
                this.query()
            }).catch((error) => {
             console.log(error)
            })
            
        },
        handleSizeChange(val) {
            // 改变每页条数
            this.pageSize = val
            this.query()
        },
        handleCurrentChange(val) {
            // 切换页码
            this.currentPage = val
            this.query()
        },
        // table 数据转换
        formatMarkType(row, column){
             if(row.mark === 1){
                     return '启用'
                 } else if(row.mark === 2) {
                     return '删除'
                 } else {
                     return ''
                 }
        },
        // 新增客户
        addLevel(){
            this.dialogFormAdd = true
            this.level = {}
        },
        // 修改客户
        editLevel(){
            let id = this.selectionList[0]
             var params = {
                 'id' : id
             }
            levelGetById(params).then(res =>{
                // 
                this.level = {}
                this.level = res.data
                this.dialogFormEdit = true
              
            }).catch((error) => {
                console.log(error)
            })
            
        },
     
        add(level){
            console.log(level)
            levelInsert(level).then(res =>{
                 Message({
                    message: '客户等级新增成功',
                    type: 'success',
                    duration: 3 * 1000
                })
                // 新增弹出框隐藏
                this.dialogFormAdd = false
                // 重新查询表格
                this.query()
            }).catch((error) => {
             console.log(error)
            })
        },
        edit(level){
             levelUpdate(level.id, level).then(res =>{
                 Message({
                    message: '客户等级修改成功',
                    type: 'success',
                    duration: 3 * 1000
                })
                // 新增弹出框隐藏
                this.dialogFormEdit = false
                // 重新查询表格
                this.query()
            }).catch((error) => {
             console.log(error)
            })
        }
    }
}
</script>

现在,编辑和新建复用了同一个组件。如果需求变更:增加一个出生年月的表单项,之后只需要修改这一个文件,就完成两个功能的修改。

这种实现方式已经可以满足我们目前的需求,但是还是会存在一些问题

  • 不符合单一职责原则:现在表单组件中既封装了表单中的数据和功能,也有操作按钮,Dialog组件的一些数据及操作(如:visible状态),表单组件中通过定义title、visible等props对Dialog所需的props进行了一次中转,产生了一些额外的代码。
    不仅如此,假设现在需要对保存按钮也进行区分:编辑员工时,保存按钮文案改为编辑,或者在新建员工时增加暂存按钮及功能。我们就需要通过增加表单组件的props,或在组件内部进行判断来实现,这里通过增加按钮或修改文案举例,实际上通过slot插槽或其他方式也可以解决这个问题,真实的业务场景可能更为复杂。目的是想说明这些没有涉及到表单功能的修改,但是我们依然需要修改同一个组件。
  • 组件覆盖的场景比较少,在案例中,我们的添加修改都是弹窗的形式,但是在更复杂的真实业务中,可能需要通过一个页面进行添加员工,编辑通过弹窗实现。或者需要实现批量添加员工这样的功能,因为我们的组件内部也集成了Dialog,就没办法很好的完成。

方式三:组件封住(更进一步,剥离Dialog和按钮)

基于对第二种方式出现问题的思考,我们可以对表单组件与Dialog,操作按钮进行剥离,进一步抽象表单组件。

 定义:客户等级通用表单(levelForm.vue)

<style>
</style>
<template>
             <el-form ref="Form" :model="level" :rules="rules" label-width="80px" >
                    <el-form-item label="等级名称" prop="name" >
                        <el-col :span="7">
                            <el-input v-model="level.name" auto-complete="off" ></el-input>
                        </el-col>
                    </el-form-item>
                    <el-form-item label="等级标识" >
                        <el-col :span="7">
                            <el-select v-model="level.mark" value-key="id" prop="mark">
                                <el-option v-for="item in markArry"  :key="item.id" :label="item.name" :value="item.id"></el-option>
                            </el-select>
                        </el-col>
                    </el-form-item>
                    <el-form-item label="等级描述" >
                        <el-col :span="7">
                            <el-input v-model="level.introduction" prop="introduction" auto-complete="off"></el-input>
                        </el-col>
                    </el-form-item>
            </el-form>
</template>
 
<script>
export default{
    name: "Form",
    props: {
      // 回显数据
      model: {
        type: Object,
        default: null
      }
    },
     data() {
      return {
        level: {
          id: '',
          mark: '',
          name: '',
          introduction: ''
        },
        rules: {
          name: {required: true, message: '请输入姓名', trigger: 'blur'},
          mark: {required: true, message: '请输入标记', trigger: 'blur'},
          introduction: {required: true, message: '请输入描述', trigger: 'blur'}
        },
        markArry:[
            {
                "id": 1,
                "name": '启用'
            },
            {
                "id": 2,
                "name": '删除'
            }
        ]
      }
    },
    watch: {
      // 监听 编辑时回显表单
      model(level) {
          console.log('123456')
          console.log("父组件传递子组件data", level)
          this.level = {...level} // 简单的浅克隆
        }
    },
    methods: {
      // 对外暴露获取数据的方法,内部进行表单的校验,父组件中通过refs调用
      getValue() {
        return new Promise((resolve, reject) => {
          this.$refs.Form.validate((valid) => {
            if (valid) {
              resolve({...this.level})
              
            } else {
              reject('表单校验没通过,可以抛出一个异常')
            }
          })
        })
      }
    }
}
</script>

注意:

由于保存按钮现在不在表单组件中了,没办法通过emit的方式对父组件暴露表单数据,所以改为在methods中注册了一个getValue方法,方法中进行了表单验证,通过返回一个Promise的方式,返回表单数据或异常。父组件在使用这个新的表单组件时,通过ref注册一个表单组件的引用,调用表单组件中的getValue方法获取组件内部的数据

封住组件调用:

<style>
</style>
<template>
      <el-card class="full-height full-width">
        <search-table class="full-height full-width"
            :table-loading="loading"
            :tableData="tableData"
            :ref="tableRef"
            :labelWidth="'40px'"
            :row-keys="row => row.id"
            @query="currentPage = 1; query();"
            @reset="doReset"
            @selectionChange="selectionChange">
            <template v-slot:row>
                <el-form-item label="名称">
                    <el-input placeholder="请输入名称" v-model="searchForm.name" clearable></el-input>
                </el-form-item>
                <el-form-item label="标识">
                    <el-select placeholder="请选择" v-model="searchForm.mark" clearable>
                        <el-option :label="'启用'" :value="1"></el-option>
                        <el-option :label="'删除'" :value="2"></el-option>
                    </el-select>
                </el-form-item>
            </template>
            <template v-slot:actions>
                <el-button size="small" type="primary" v-on:click="addLevel()">新 建</el-button>
                <el-button size="small" type="primary" v-on:click="editLevel()">编 辑</el-button>
                <el-button size="small" type="primary" v-on:click="handlerDelete()">删除/批量删除</el-button>
            </template>
            <template >
                <el-table-column :reserve-selection="true" type="selection" width="55" />
                <el-table-column prop="name" label="名称" show-overflow-tooltip />
                <el-table-column prop="mark" label="标识" :formatter="formatMarkType" show-overflow-tooltip />
                <el-table-column prop="introduction" label="描述" show-overflow-tooltip />
            </template>
            <template v-slot:footer>
                <el-pagination
                    background
                    :current-page="currentPage"
                    :page-sizes="pageSizes"
                    :page-size="pageSize"
                    layout="total, sizes, prev, pager, next, jumper"
                    :total="total"
                     @size-change="handleSizeChange"
                     @current-change="handleCurrentChange" />
            </template>
        </search-table>

        <!--
        <levelCommon
             title="新增客户等级"
            :visible.sync="dialogFormAdd"
            @save="add"
        ></levelCommon>-->

         <!--<levelCommon
            :model="level"
             title="修改客户等级"
            :visible.sync="dialogFormEdit"
            @save="edit"
        ></levelCommon>-->

        <el-dialog title="添加客户等级" :visible.sync="dialogFormAdd" size="tiny">
                 <levelForm ref="addLevelForm"/>
                  <template slot="footer" class="dialog-footer">
                        <el-button @click="dialogFormAdd = false">取 消</el-button>
                        <el-button type="primary" @click="add">确 定</el-button>
                </template>
        </el-dialog>

        <el-dialog title="修改客户等级" :visible.sync="dialogFormEdit" size="tiny">
                 <levelForm ref="editLevelForm" :model ="level" />
                  <template slot="footer" class="dialog-footer">
                        <el-button @click="dialogFormEdit = false">取 消</el-button>
                        <el-button type="primary" @click="edit">确 定</el-button>
                </template>
        </el-dialog>

      </el-card>

      


</template>
<script>
import SearchTable from '@/components/searchTable'
//import levelCommon from '../levelCommon'
import levelForm from '../levelForm'
import { Message} from "element-ui";
import {getLevelPage, batchLevelDelete, levelInsert, levelGetById, levelUpdate} from "@/api/level";
export default{
    name: 'customer',
    components: {
        SearchTable,
        //levelCommon,
        levelForm
    },
     data () {
        return {
            tableData: [],
            loading: false,
            tableRef: 'tableRef',
            searchForm: {},
            currentPage: 1,
            pageSizes: [10, 20, 50],
            pageSize: 10,
            total: 0,
            selectionList:[], //定义删除/批量删除
            dialogFormAdd:false,
            dialogFormEdit: false,
            level:{
                id: '',
                name: '',
                introduction: '',
                mark: ''
            },
            markArry:[{
                "id": 1,
                "name": "启用"
            },{
                "id": 2,
                "name": "删除"
            }],

        };
    },
    created() {
      this.query()
    },
    methods: {
        query() {
            // 请求表格数据
        var params ={
          'pageNum': this.currentPage,
          'pageSize': this.pageSize,
          'name':this.searchForm.name,
          'mark':this.searchForm.mark
         }
        getLevelPage(params).then(res => {
                console.log(res)
                // 把请求到的数据给testDatas数组
                this.tableData = res.data.list
                // 当前页数
                this.currentPage = res.data.pageNum
                // 当前页数量
                this.pageSize = res.data.pageSize
                // 分页总数
                this.total = res.data.total
              //   console.log(JSON.stringify(res.data.data.total))
            })
            .catch((error) => {
             console.log(error)
            })

        },
        doReset() {
            // 重置搜索条件
             // 请求表格数据
              this.tableData = [];
              this.restForm();
              this.query();
        

        },
        restForm(){
            this.searchForm.name = ""
            this.searchForm.mark = ""
        },
        selectionChange(val) {
            // 表格选项发生变化
            console.log("触发表格事件")

            this.selectionList = []
		    val.forEach(element => {
		        this.selectionList.push(element.id)
		    });
          
        },
        handlerDelete(){
              // 数组转字符串使用逗号分隔
            let sids =  this.selectionList.join(",")
            var params ={
                'sids': sids
            }
            batchLevelDelete(params).then(res =>{
                Message({
                    message: '批量删除成功',
                    type: 'success',
                    duration: 3 * 1000
                })
                // 重新查询表格
                this.query()
            }).catch((error) => {
             console.log(error)
            })
            
        },
        handleSizeChange(val) {
            // 改变每页条数
            this.pageSize = val
            this.query()
        },
        handleCurrentChange(val) {
            // 切换页码
            this.currentPage = val
            this.query()
        },
        // table 数据转换
        formatMarkType(row, column){
             if(row.mark === 1){
                     return '启用'
                 } else if(row.mark === 2) {
                     return '删除'
                 } else {
                     return ''
                 }
        },
        // 新增客户
        addLevel(){
            this.dialogFormAdd = true
            this.level = {}
        },
        // 修改客户
        editLevel(){
            let id = this.selectionList[0]
             var params = {
                 'id' : id
             }
            levelGetById(params).then(res =>{
                // 
                this.level = {}
                this.level = res.data
                this.dialogFormEdit = true
                console.log('查询到的数据', this.level)
              
            }).catch((error) => {
                console.log(error)
            })
            
        },
     
        add(){ 
        this.$refs.addLevelForm.getValue()
          .then((level) => {
            // 调用添加接口
             console.log("请求参数",level)
              levelInsert(level).then(res =>{
                 Message({
                    message: '客户等级新增成功',
                    type: 'success',
                    duration: 3 * 1000
                })
                // 新增弹出框隐藏
                this.dialogFormAdd = false
                // 重新查询表格
                this.query()
            }).catch((error) => {
             console.log(error)
            })
          })
          .catch((error) => {
            // 处理表单验证失败
            console.log(error)
          })

           
           
        },
        edit(){
             this.$refs.editLevelForm.getValue()
          .then((level) => {
            // 调用编辑接口
            levelUpdate(level.id, level).then(res =>{
                 Message({
                    message: '客户等级修改成功',
                    type: 'success',
                    duration: 3 * 1000
                })
                // 新增弹出框隐藏
                this.dialogFormEdit = false
                // 重新查询表格
                this.query()
            }).catch((error) => {
             console.log(error)
            })
          })
          .catch((error) => {
            // 处理表单验证失败
             console.log(error)
          })

             
        }
    }
}
</script>

通过这样封装,当我们需要修改Dialog或者操作按钮,直接在父组件中修改即可。

以上是关于Vue + ElementUI 编辑/新增页面复用总结的主要内容,如果未能解决你的问题,请参考以下文章

element-ui 表单编辑之后再新增表单数据无法清空问题(已解决)

一起学Vue:UI框架(element-ui)

vue+elementUi开发一个可拖拽的和拉伸编辑的画板

vue判断elementui中el-form是否更新变化,变化就提示是否保存,没变就直接离开

element 表单restFields不生效的问题

element 一个页面两个table显隐相互影响