广告位联系
返回顶部
分享到

vue+elementUI封装一个根据后端变化的动态table(完整代码)

JavaScript 来源:互联网 作者:佚名 发布时间:2022-09-01 21:31:45 人浏览
摘要

效果图: 使用组件,启用自动生成 :auto=true 自动生成-编辑 (包括请求已经实现了)新增和删除也是一样 ps:如有额外的按钮可以用插槽实现 查询的时候,只需要多返回下面数据,就可

效果图:

使用组件,启用自动生成 :auto="true"

自动生成-编辑 (包括请求已经实现了)新增和删除也是一样

ps:如有额外的按钮可以用插槽实现

查询的时候,只需要多返回下面数据,就可以自动生成列,和对应操作按钮

目录

table.vue

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

<template>

    <div>

      

      <el-row v-if="auto">

          <el-col :span="4">

           <el-button size="small" type="primary" @click="add(table.buttons.add)">新增</el-button>

           </el-col>

          <el-col :span="20">

            <div style="display: flex;justify-content: flex-end;margin:10px 0 10px 0">

                <slot name="search"></slot>

                <el-button size="small" type="primary" @click="filterData">查询</el-button>

            </div>

          </el-col>

        </el-row>

        <el-row v-else>

          <el-col :span="24" style="padding-top: 30px"> </el-col>

        </el-row>

 

    <el-table v-if="auto" v-loading="table.loading" :data="table.data" style="width: 100%">

        <el-table-column   v-for="(item,index) in table.columns" :key="index" :label="item.label+'-自动生成'" :prop="item.prop"></el-table-column>

          

        <el-table-column label="操作-自动生成">

             <template slot-scope="scope">

                <el-button  size="small" type="button" @click="edit(scope.row,table.buttons.edit)">编辑</el-button>

                <el-button  size="small" type="danger" @click="del(scope.row,table.buttons.del)">删除</el-button>

             </template>

        </el-table-column>

    </el-table>

      

    <el-table v-if="!auto" v-loading="table.loading" :data="table.data" style="width: 100%">

        <slot>

            <el-table-column label="默认列" ></el-table-column>

        </slot>

    </el-table>

    <el-pagination

            background

            :current-page="this.$parent.filters.pageIndex"

            layout="total, sizes, prev, pager, next, jumper"

            :page-size="this.$parent.filters.pageSize"

            style="width: 50%;margin:20px auto 0px auto;text-align: center;"

            :total="total"

            @current-change="handleCurrentChange"

            @size-change="handleSizeChange"

        />

    </div>

</template>

<script>

 

 

export default ({

    name:'table-test',

    props: {

        auto:{

            type:Boolean,

            default:()=>false,

        },

        query: {

            type: Function,

            default: ()=>null,

        },

    },

    created(){

        this.filterData()

    },

   data(){

    return {

       

        table:{

            columns:[],

            buttons:{},

            data:[],

            loading:false,

        },

        total:0

    }

   },

   methods:{

     handleCurrentChange(index) {

        this.$parent.filters.pageIndex = index

        this.filterData()

      },

     handleSizeChange() {},

     filterData(){

        this.table.loading=true

       /* eslint-disable */

        // debugger

        if(this.query){

            this.query().then(res=>{

                this.table.data = res.data

                this.table.columns =res.columns

                this.table.buttons =res.buttons

                this.total=res.totalCount

            }).finally(()=>{

                this.table.loading=false

            })

        }else{

            console.error('table组件未设置query函数')

        }

     },

    del(row,setting){

        // this.table.data.splice(index,1)

        this.$baseConfirm('你确定要删除吗?', null,  () => {

            this.fn(row,setting)

        })

    },

    add(setting){

        // 约定添加、编辑弹窗组件都叫 addIndex或者一个其它统一的名称, 就可以实现通用

        this.$parent.$refs.addIndex.show((form)=>this.fn(form,setting))

    },

    edit(row,setting){

         this.$parent.$refs.addIndex.showEdit(()=>this.fn(row,setting),row)

    },

    fn(row,setting){

        if(!row){

            throw 'fn:row is null'

        }

        Object.keys(setting.data).forEach(x=> {

          setting.data[x] =  row[x]

        })

         Object.keys(setting.param).forEach(x=> {

          setting.param[x] =  row[x]

        })

        this.request({

            url:setting.url,

            mtehod:setting.method,

            param:setting.param,

            data:setting.data

        }).then((res)=>{

            this.$message.success(res.message)

            this.filterData()

        })

    },

    //模拟请求

    request(param){

        console.log('request',param)

        return new Promise((res,rej)=>{

            setTimeout(() => {

                res({code:200,data:null,message:'ok'})

            }, 100);

        })

    }

   }

})

</script>

<style lang="scss" scoped>

  

table button{

    margin-top:10px;

}

::v-deep{

     .el-table .el-table__cell{

        padding:8px 0;

    }

    .el-table__cell .el-button:first-child{

        margin-left: 10px;

    }

}

</style>

index.vue

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

<template>

    <div id="app" style="width:1000px;background-color:cornsilk;margin:0 auto;padding:20px">

       <div style="margin-top: 150px"></div>

  

       

        <!-- 由后端接口返回的好处:

        接口参数有任何变化,接口名称变更,后端直接更新即可,不用前端修改 ,减少了来回沟通的成本

        组件提供了标准化,完整的基础功能,省去人为复制代码出现bug后修改的时间成本

        省去的基础功能实现的细节,减少了功能细节缺胳膊少腿后期修补的时间成本 -->

        <!-- 使用 auto="true" 根据接口返回的配置【自动生成列,按钮,增删改查调用】不用再写任何代码 -->

        <myTable ref="table" :auto="true" :query="tableQuery">

            <template slot="search">

                <el-form :inline="true" label-width="50px" style="height: 40px">

                    <el-form-item label="id">

                        <el-input v-model="filters.id" placeholder="" style="width:200px"></el-input>

                    </el-form-item>

                    <el-form-item label="名称">

                        <el-input v-model="filters.name" placeholder="" style="width:200px"></el-input>

                    </el-form-item>

                </el-form>

            </template>

        </myTable>

        <!-- 使用 auto="false" 需要自己定义列和增删改查函数  -->

        <myTable ref="table" :auto="false" :query="tableQuery">

            <el-table-column label="id-插槽"  prop="id"> </el-table-column>

            <el-table-column label="内容列-插槽" prop="name"></el-table-column>

            <el-table-column label="操作-插槽" >

                <template slot-scope="scope">

                    <el-button  size="small" type="button" @click="edit(scope)">编辑</el-button>

                    <el-button  size="small" type="button" @click="edit(scope)">编辑</el-button>

                    <el-button  size="small" type="button" @click="edit(scope)">编辑</el-button>

                    <el-button  size="small" type="button" @click="edit(scope)">编辑</el-button>

                    <el-button  size="small" type="button" @click="edit(scope)">编辑</el-button>

                    <el-button  size="small" type="button" @click="edit(scope)">编辑</el-button>

                    <el-button  size="small" type="button" @click="edit(scope)">编辑</el-button>

                     

                    <el-button  size="small" type="danger" @click="del(scope.$index)">删除</el-button>

                </template>

            </el-table-column>

        </myTable>

        <addIndex ref="addIndex"></addIndex>

    </div>

</template>

<script>

 import addIndex from '@/views/components/add.vue'

export default ({

   name:'indexTest',

   components:{addIndex},

   data(){

    return {

       filters:{

        pageIndex:1,

        pageSize:5

       }

    }

   },

   methods:{

    //模拟请求返回

    tableQuery(){

        console.log('filters',this.filters)

          var p = new Promise((res,rej)=>{

            console.log(rej)

            setTimeout(() => {

                var value ={

                    columns:[{label:'序号',prop:'id'},{label:'名称',prop:'name'}],

                    buttons: {

                        add:{ url:'/controller/add',method:'post',data:{id:'',name:''},param:{}},

                        edit:{ url:'/controller/update',method:'post',data:{id:'',name:''},param:{}},

                        del:{url:'/controller/delete',method:'delete', data:{ },param:{id:''}}

                    },

                    data: [

                        {id:1,name:'测试1004' },

                        {id:2,name:'测试1009'},

                        // {id:3,name:'测试1009'},

                        // {id:4,name:'测试1009'},

                        // {id:5,name:'测试1009'},

                        // {id:6,name:'测试1009'},

                        // {id:7,name:'测试1009'},

                        // {id:8,name:'测试1009'},

                        // {id:9,name:'测试1009'},

                        // {id:10,name:'测试1009'},

                    ],

                    totalCount:200};

                     

                    value.data =value.data.filter(x=>this.where(x))

                res(value)

            }, 1000);

        })

        return p

    },

    where(x){

        var a = this.filters.id ? x.id == this.filters.id : true 

        var b = this.filters.name ? x.name.indexOf( this.filters.name)>-1 : true

        var r = a && b

        return r

    },

    edit(){},

    del(){}

   }

})

</script>

<style lang="scss" scoped>

table button{

    margin-top:10px;

}

</style>

add.vue

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

<template>

      

        <el-dialog :title="title"

        width="30%"

        :close-on-click-modal="false"

        :visible.sync="visible">

            <el-form  ref="form" :model="form" :rules="rules"  :label-width="'120px'">

              <el-form-item label="id" prop="id">

                <el-input v-model="form.id" placeholder=""></el-input>

              </el-form-item>

              <el-form-item label="名称" prop="name">

                <el-input v-model="form.name" placeholder=""></el-input>

              </el-form-item>

            </el-form>

            <div slot="footer" class="dialog-footer">

                <el-button @click="visible = false">取 消</el-button>

                <el-button type="primary" @click="add()">确 定</el-button>

            </div>

        </el-dialog>

    

</template>

 

<script>

 

export default ({

     name:'addTest',

     data(){

        return {

          title:'新增',

          visible:false,

          form:{},

          rules:{},

          save:null,

        }

     },

     methods:{

        show(save,form){

            this.visible=true

            this.save=save

            this.form =form?form:{}

        },

        showEdit(save,form){

          this.title='编辑'

          this.show(save,form)

        },

        add(){

          if(this.save!=null){

            this.save(this.form)

          }

          else{

            this.$message.success('ok2')

          }

          this.visible=false

        }

     }

})

</script>


版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。
原文链接 : https://www.cnblogs.com/212s/archive/2022/08/31/16638752.html
相关文章
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计