A
A
AleDv2019-11-16 14:27:21
Vue.js
AleDv, 2019-11-16 14:27:21

How to draw the list of components correctly?

Hello. There is a list of users that are initially displayed. Then, on the button, I get another batch of users to display. Newly arrived data is pushed to the main array:

<template>
    <div class="container">

            <div class="text-center" v-if="! this.isUserPrivate && this.isUserAllow && this.friendList">
                <div v-if="! this.isLoading">

                    <div class="row">
                        <friend-item :friend="friend" v-for="friend in this.friendList" :key="friend.id" track-by="id"></friend-item>
                    </div>
                </div>

                <div class="text-center" v-if="this.visibleBtn">
                    <span class="friends" @click="uploadPart">Загрузить ещё</span>
                </div>
            </div>

    </div>
</template>

<script>

    import FriendItem from "../components/FriendItem.vue";

    export default {
        name: "Friends",
        components: {
            FriendItem,
            VLink
        },
        data: function () {
            return {
      
                friendList: [],
                friendListCount: 0,
                friendsShow: 16,
                isLoading: false,

                page: 1,
                visibleBtn: true,
            }
        },
        created() {

            let _that = this;

            connect.subscribe((e) => {
                if (e.detail.hasOwnProperty('type')) {
                    switch (e.detail.type) {

                        case 'VKWebAppCallAPIMethodResult':

                            if (e.detail.data) {

                                _that.friendListCount = e.detail.data.response.count;

                                e.detail.data.response.items.forEach(function (item) {
                                    _that.friendList.push(item);
                                });

                                if (_that.friendListCount <= (_that.page) * _that.friendsShow) {
                                    _that.visibleBtn = false;
                                }

                                _that.isLoading = false;
                            }
                            break;

                      
                        case 'VKWebAppAccessTokenReceived':

            if (e.detail.data) {
                                localStorage.token = e.detail.data.access_token;
                                localStorage.token_scope = e.detail.data.scope;
                            }

                            if (localStorage.token_scope.indexOf('friends') !== -1) {
                                _that.isLoading = true;

                                connect.send("VKWebAppCallAPIMethod", {
                                        "method": "friends.get",
                                        "params": {
                                            "user_id": this.user.id,
                                            "count": _that.friendsShow,
                                            "offset": 0,
                                            "order": "hints",
                                            "fields": "photo_100, bdate",
                                            "v": "5.103",
                                            "access_token": localStorage.token
                                        }
                                    }
                                );
                            } else {
                                _that.isUserAllow = false;
                            }

                            break;

                    }
                }
            });
        },
        methods: {

            uploadPart() {

                let page = parseInt(this.page);
                let nextPage = page + 1;
                let partItemsCount = this.friendsShow;
                let offset = page * partItemsCount;

                this.isLoading = true;

                connect.send("VKWebAppCallAPIMethod", {
                        "method": "friends.get",
                        "params": {
                            "user_id": this.user.id,
                            "count": partItemsCount,
                            "offset": offset,
                            "order": "hints",
                            "fields": "photo_100, bdate",
                            "v": "5.103",
                            "access_token": localStorage.token
                        }
                    }
                );

                this.page = nextPage;

                return null;
            },
           
        }
    }
</script>

As a result, when displaying, when a new batch of data arrives, the entire list is first deleted, then drawn again with the data already added. It turns out such a jump in rendering.
How to achieve the addition of elements to the array and its rendering without such jumps?
UPD . Updated example. First, the VKWebAppAccessTokenReceived event is executed, then when the "load more" button is pressed, the VKWebAppCallAPIMethodResult event is processed

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Andrey Ololoshchenko, 2019-11-17
@AleDv

Because when you click on the button, you set this.isLoading = true; accordingly, all your code inside is redrawn.
Plus, I advise you to look towards ES6 syntax

e.detail.data.response.items.forEach(function (item) {
                                    _that.friendList.push(item);
                                });

and use spread for example and asynchronous promises or async\await
_that.friendList.push(...e.detail.data.response.items);

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question