JavaScript
主页 > 网络编程 > JavaScript >

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

2022-09-01 | 佚名 | 点击:

效果图:

使用组件,启用自动生成 :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>

原文链接:https://www.cnblogs.com/212s/archive/2022/08/31/16638752.html
相关文章
最新更新