封装可编辑表格

2019-12-29  本文已影响0人  幻影翔

效果

点击编辑。修改列的内容,点击保存,更新列的值

可编辑表格.png

edit-table.vue

<template>
    <Table :columns="insideColumns" :data="value"></Table>
</template>
<script>
    import clonedeep from 'clonedeep'
    export default {
        name: 'EditTable',
        data () {
            return {
                edittingId: '',
                edittingContent: '',
                insideColumns: [],
            }
        },
        props: {
            columns: {
                type: Array,
                default: () => []
            },
            value: {
                type: Array,
                default: () => []
            }
        },
        watch: {
            columns () {
                this.handleColumns()
            }
        },
        methods: {
            handleClick ({row, index, column}){
                if(this.edittingId === `${column.key}_${index}`) {
                    let tableData = clonedeep(this.value)
                    tableData[index][column.key] = this.edittingContent
                    this.$emit('input',tableData)
                    this.$emit('on-edit',{ row, index, column, newValue: this.edittingContent})
                    this.edittingId = ''
                    this.edittingContent = ''
                } else {
                    this.edittingId = `${column.key}_${index}`
                }
            },
            handleInput (newValue) {
                this.edittingContent = newValue
            },
            handleColumns () {
                const insideColumns = this.columns.map(item => {
                    if (!item.render && item.editable){
                        item.render = (h, { row, index, column}) => {
                            const isEditting = this.edittingId === `${column.key}_${index}`
                            return (
                                <div>
                                    { isEditting ? <i-input value={row[column.key]} style="width:100px;" on-input={this.handleInput}></i-input> : <span>{row[column.key]}</span>}
                                    <i-button on-click={this.handleClick.bind(this,{ row, index, column })} >{isEditting ? '保存' : '编辑'}</i-button>
                                </div>
                            )
                        }
                        return item
                    } else return item
                })
                this.insideColumns = insideColumns
            }
        },
        mounted () {
            this.handleColumns()
        }
    }
</script>

table.vue

<template>
    <div>
        <edit-table :columns="columns" v-model="tableData" @on-edit="handleEdit"></edit-table>
    </div>
</template>
<script>
    import { getTableData } from '@/api/data'
    import EditTable from '_c/edit-table'
    export  default {
        components: {
            EditTable
        },
        data () {
            return {
                tableData: [],
                columns: [
                    {key: 'name', title: '姓名'},
                    {key: 'age', title: '年龄', editable: true},
                    {key: 'email', title: '邮箱', editable: true},
                ]
            }
        },
        methods: {
            handleEdit ({ row, index, column, newValue }) {
                console.log({ row, index, column, newValue})
            }
        },
        mounted () {
            getTableData().then( res => {
                this.tableData = res;  // 根据返回的格式进行调整
            })
        }
    }
</script>

Mock模拟getTableData的请求

api/data.js

import axios from './index'

export const getTableData = () => {
    return axios.request({
        url: '/getTableData',
        method: 'get'
    })
}

api/index.js 引入axios

import HttpRequest from '@/lib/axios'
const axios = new HttpRequest()
export default axios

mock/index.js 代理请求获取数据

import Mock from 'mockjs'
import { getTableData } from './response/data'

Mock.mock('/getTableData',getTableData)

mock/response/data.js 定义mock请求

import { doCustomTimes } from '@/lib/tools'
import Mock from 'mockjs'

export const getTableData = () => {
    const template = {
        name: '@name',
        'age|18-25': 0,
        email: '@email'
    };
    let arr = [];
    doCustomTimes(5, () => {
        arr.push(Mock.mock(template))
    });
    return arr;
};

lib/util.js 多次调用

export const doCustomTimes = (times, callback) => {
    let i = -1
    while (++i < times) {
        callback()
    }
}

main.js中引入mock

if(process.env.NODE_ENV === 'development')  require('./mock')
上一篇下一篇

猜你喜欢

热点阅读