vue2封装自己的表格组件--(上)

215 阅读1分钟

简单需求

首先生成一个自定义的表头和将接口返回的数据处理成表格的行显示 假设接口返回的数据为简单的json格式

1.用props,watch接数据

props向组件传参,watch监听参数变化,这里我们先举一个简单的例子,header为表头名数组,props为表内数据(接口返回)

props: ["props", "header"],
    data() {
        return {
            propsData: [],
            headerData: [],
            lines: [],
        };
    },
 watch: {
        props: {
            handler(newVal, oldVal) {
                console.log(newVal, "props");
                this.propsData = newVal;
            },
            deep: true,
            immediate: true,
        },
        header: {
            handler(newVal, oldVal) {
                console.log(newVal, "header");
                this.headerData = newVal;
            },
            deep: true,
            immediate: true,
        },
    },

然后在页面内引入我们的chart组件,并模拟传入数据

<template>
    <div class="page-content">
        <div class="showchart">
            <chart :props="props" :header="header"></chart>
        </div>
    </div>
</template>

<script>
import chart from "@/components/chart/chart.vue";
export default {
    data() {
        return {
            props: [
            ],
            header: ["名字", "年龄", "余额"],
        };
    },
    components: {
        chart,
    },
    created() {
        this.getProps();
    },
    methods: {
        //模拟传入数据
        getProps() {
            this.props = [
                { name: "user1", age: 23, money: 10000 },
                { name: "user2", age: 25, money: 8000 },
                { name: "user3", age: 27, money: 9000 },
                { name: "user4", age: 28, money: 10000 },
                { name: "user5", age: 29, money: 11000 },
            ];
        },
    },
    watch: {},
};
</script>

<style scoped lang="scss">
.page-content {
    height: 100%;
    width: 100%;
    display: flex;
    background: #ffffff !important;
    .showchart {
        margin: 10px;
        width: calc(100% - 80px);
        height: 50%;
    }
}
</style>

2.处理传入数据转换成数组的格式方便v-for遍历

因为接口返回的数据大多为json格式,我们这里统一转为json进行处理将value转化为数组内对应的元素

export default {
    props: ["props", "header"],
    data() {
        return {
            propsData: [],
            headerData: [],
            lines: [],
        };
    },
    mounted() {
        this.initChart();
    },
    methods: {
        //初始化表格数据
        initChart() {
            console.log("headerData", this.headerData);
            console.log("propsData", this.propsData);
            this.propsData.forEach((element) => {
                let lineItem = [];
                //将传入数据转为json格式处理
                element = JSON.stringify(element);
                //将json数据转换为列表的行
                JSON.parse(element, (key, value) => {
                    lineItem.push(value.toString());
                });
                //切掉空元素
                lineItem.splice(lineItem.length - 1);
                this.lines.push(lineItem);
            });
            console.log("lines", this.lines);
        },
    },
    watch: {
        props: {
            handler(newVal, oldVal) {
                console.log(newVal, "props");
                this.propsData = newVal;
            },
            deep: true,
            immediate: true,
        },
        header: {
            handler(newVal, oldVal) {
                console.log(newVal, "header");
                this.headerData = newVal;
            },
            deep: true,
            immediate: true,
        },
    },
};
</script>

3.组件中用v-for绘制表格

<template>
    <div class="chart-box">
        <div class="header">
            <div class="header-cell" v-for="(item,index) in headerData" :key="index">
                <p>{{item}}</p>
            </div>
        </div>
        <div class="body">
            <div class="body-line" v-for="(line,index) in lines" :key="index">
                <div class="body-line-cell" v-for="(name,index) in line" :key="index">
                    {{ name}}
                </div>
            </div>
        </div>
    </div>
</template>
<style scoped lang="scss">
.chart-box {
    height: 100%;
    width: 100%;
    display: flex;
    flex-direction: column;
    .header {
        flex: 1;
        width: 100%;
        display: flex;
        .header-cell {
            display: flex;
            flex: 1;
            justify-content: space-around;
            align-items: center;
            border-bottom: solid 1px rgb(0, 0, 0);
            > p {
                color: rgb(0, 0, 0);
                font-size: 26px;
            }
        }
    }
    .body {
        display: flex;
        flex: 5;
        width: 100%;
        flex-direction: column;
        .body-line {
            display: flex;
            flex: 1;
            width: 100%;
            .body-line-cell {
                display: flex;
                flex: 1;
                justify-content: space-around;
                align-items: center;
                border-bottom: solid 1px rgb(0, 0, 0);
                > p {
                    color: rgb(0, 0, 0);
                    font-size: 26px;
                }
            }
        }
    }
}
</style>

本文简单实现基本功能后续继续完善组件