vue大数据量性能优化

2020-01-05  本文已影响0人  幻影翔

当数据量庞大的时候,组件的渲染会变得很慢,这时我们需要进行性能优化,根据可视区域的大小渲染组件

select和checkbox动态组件优化

使用vue-virtual-scroll-list进行组件遍历

<template>
    <div >
        <CheckboxGroup v-model="checkedArr">
            <virtual-list :size="30" :remain="10">
                <p v-for="item in list " :key="`${item.value}`" style="height:30px;">
                    <Checkbox label="item.value">
                        <Icon type="logo-twitter"></Icon>
                        <span>{{ item.label }}</span>
                    </Checkbox>
                </p>
            </virtual-list>
        </CheckboxGroup>
    </div>
</template>
<script>
    import { doCustomTimes } from "@/lib/tools";
    import VirtualList from 'vue-virtual-scroll-list'
    export default {
        component: {
            VirtualList
        },
        data () {
            return {
                list: [],
                selectData: 0,
                checkedArr: []
            }
        },
        mounted () {
            let list = [];
            doCustomTimes(15000,(index) => {
                list.push({
                    value: index,
                    label: `select${index}`
                })
            })
            this.list = list
        }
    }
</script>

// 工具方法
export const doCustomTimes = (times, callback) => {
    let i = -1
    while (++i < times) {
        callback(i)
    }
}

大型列表优化

封装一个form-single 进行遍历

组件form.single.vue

<template>
    <Form ref="form"
                v-if="Object.keys(valueList).length"
                :label-width="labelWidth"
                :model="valueList"
                :rules="rules">
        <FormItem
            v-for="(item, index) in list"
            :label="item.label"
            label-position="left"
            :prop="item.name"
            :error="errorStore[item.name]"
            :key="`${_uid}_${index}`"
            @click.native="handleFocus[item.name]"
        >
        <component :is="item.type"
                             :range="item.range"
                             :placeholder="item.placeholder"
                             :icon="item.icon"
                             v-model="valueList[item.name]">
            <template v-if="item.children">
                <component
                    v-for="(child, i) in item.children.list"
                    :is="item.children.type"
                    :key="`${_uid}_${index}_${i}`"
                    :label="child.label"
                    :value="child.value">{{ child.title }}</component>
            </template>
        </component>
        </FormItem>
        <FormItem>
            <Button @click="handleSubmit" type="primary">提交</Button>
            <Button @click="handleReset">重置</Button>
        </FormItem>
    </Form>
</template>

<script>
    import { sendFormData } from "@/api/data";
    import clonedeep from 'clonedeep'
    export default {
    name: "FormGroup",
    data () {
        return {
            initValueList: [], //初始化数据
            rules: {},
            valueList: {},  // form填的值
            errorStore: {}   // 校验的错误对象
        }
    },
    props: {
        list: {
            type: Array,
            default: () => []
        },
        labelWidth: {
            type: Number,
            default: 100
        },
        url: {
            type: String,
            required: true
        }
    },
    watch: {
        // 监听list变化
        list () {
            this.setInitValue();
        }
    },
    methods: {
        setInitValue () {
            let rules = {};
            let valueList = {};
            let initValueList = {};
            let errorStore = {};
            this.list.forEach(item => {
                rules[item.name] = item.rule;
                valueList[item.name] = item.value;
                initValueList[item.name] = item.value;
                errorStore[item.name] = '';
            })
            this.rules = rules;
            this.valueList = valueList;
            this.initValueList = initValueList;
            this.errorStore = errorStore
        },
        handleSubmit () {
            this.$refs.form.validate(valid => {
                if (valid) {
                    sendFormData({
                        url: this.url,
                        data: this.valueList
                    }).then(res => {
                        this.$emit('on-submit-success',res);
                    }).catch(err => {
                        this.$emit('on-submit-error',err);
                        for (let key in err ) {
                            this.errorStore[key] = err[key];
                        }
                    })
                }
            })
        },
        handleReset () {
            this.valueList = clonedeep(this.initValueList);
        },
        handleFocus (name) {
            this.errorStore[name] = '';
        }
    },
    mounted () {
        this.setInitValue();
    }
}
</script>

视图调用

<template>
    <div class="form-wrapper">
        <Button @click="handleSubmit" type="primary">提交</Button>
        <Button @click="handleReset">重置</Button>
        <form-single
            ref="formSingle"
            v-for="(item, index) in formList"
            :key="`form_${index}`"
            :config="item"
            :value-data="valueData"
            :rule-data="ruleData"
            :error-store="errorStore"
        ></form-single>
    </div>
</template>
<script>
    import FormGroup from "_c/form-group/form-group";
    import formData from "@/mock/response/form-data"
    import FormSingle from '_c/form-single'
    import {sendFormData} from "@/api/data";
    import clonedeep from "clonedeep";
    export default {
        components: {
            FormGroup,
            FormSingle
        },
        data () {
            return {
                url: '/api/file/user/setFormData',
                formList:formData,
                valueData: {},
                ruleData: {},
                errorStore: {},
                initValueData: {}
            }
        },
        methods: {
            handleSubmit () {
                let isValid = true;
                this.$refs.formSingle.forEach(item => {
                    item.validate(valid => {
                        if (!valid) isValid = false;
                    })
                });
                if (isValid) {
                    sendFormData({
                        url: this.url,
                        data: this.valueData
                    }).then(res => {
                        this.$emit('on-submit-success',res);
                    }).catch(err => {
                        this.$emit('on-submit-error',err);
                        for (let key in err ) {
                            this.errorStore[key] = err[key];
                        }
                    })
                }
            },
            handleReset () {
                this.valueData = clonedeep(this.initValueData);
            }
        },
        mounted () {
            let valueData = {};
            let ruleData = {};
            let errorStore = {};
            let initValueData = {};
            formData.forEach(item => {
                valueData[item.name] = item.value;
                ruleData[item.name] = item.rule;
                errorStore[item.name] = '';
                initValueData[item.name] = item.value;
            });
            this.valueData = valueData;
            this.ruleData = ruleData;
            this.errorStore = errorStore;
            this.initValueData = initValueData;
        }
    }
</script>
<style lang="less">
    .form-wrapper{
        padding: 20px;
    }
</style>

上一篇 下一篇

猜你喜欢

热点阅读