Как измерить высоту дочернего списка в виртуальном скроллере? - PullRequest
0 голосов
/ 25 апреля 2020
  • Я пытаюсь создать виртуальный скроллер, используя ЭТО РЕПО
  • Для функции входа virtualScrollDriver требуются следующие аргументы
  • totalItems - общее количество элементов в ваш список
  • minRowHeight - минимальная высота элемента
  • viewportHeight - текущая высота области просмотра (взятие из DOM)
  • scrollTop - текущая позиция прокрутки (взятие из DOM)
  • oldState - предыдущий объект состояния, возвращенный из предыдущего вызова virtualScrollDriver ()
  • getRenderedItemHeight = (itemIndex) => height: эта функция ДОЛЖНА возвращать высоту отображаемого в данный момент элемента или 0, если в данный момент не отображена

Я добавил REF для каждого элемента в списке, но когда я пытаюсь получить его высоту, я получаю неопределенную ошибку

ЗДЕСЬ мой фрагмент кода ПОЛНЫЙ код с ошибкой

new Vue({
    el: "#__nuxt",
    data() {
        return {
            items: new Array(1000).fill().map((_, i) => i + 1),
            oldState: {},
            startIndex: 0,
            endIndex: 999,
            scrollTop: 0,
            totalItems: 1000,
            viewportHeight: 1000,
            minRowHeight: 24,
            topPlaceholderHeight: 0,
            middlePlaceholderHeight: 1000
        };
    },
    computed: {
        subset() {
            return this.items.slice(this.startIndex, this.endIndex);
        },
        topStyle() {
            return { height: this.topPlaceholderHeight + "px" };
        },
        bottomStyle() {
            return { height: this.middlePlaceholderHeight + "px" };
        }
    },
    methods: {
        handleScroll() {
            const { scrollTop } = this.$refs.root;
            this.scrollTop = scrollTop;
            this.$nextTick(() => {
                const params = {
                    totalItems: this.totalItems,
                    minRowHeight: this.minRowHeight,
                    viewportHeight: this.viewportHeight,
                    scrollTop
                };
                this.oldState = virtualScrollDriver(
                    params,
                    this.oldState,
                    this.getRenderHeight
                );
                this.topPlaceholderHeight = this.oldState.topPlaceholderHeight;
                this.middlePlaceholderHeight = this.oldState.middlePlaceholderHeight;
                this.startIndex = this.oldState.firstMiddleItem;
                this.endIndex = this.startIndex + this.oldState.middleItemCount;
                // console.log(
                //  this.scrollTop,
                //  params,
                //  this.startIndex,
                //  this.endIndex,
                //  this.topPlaceholderHeight
                // );
            });
        },
        getRenderHeight(index) {
            // if (typeof this.$refs[index] === "undefined") {
            //  return 24;
            // } else if (typeof this.$refs[index][0] === "undefined") {
            //  return 24;
            // } else {
            //  return this.$refs[index][0].clientHeight;
            // }
            return this.$refs[index][0].clientHeight;
        }
    },
    mounted() {
        this.$refs.root.addEventListener("scroll", this.handleScroll);
        this.$nextTick(() => {
            // console.log('client height', this.$refs['10'][0].clientHeight)
            this.viewportHeight = this.$refs.root.clientHeight;
            this.totalItems = this.items.length;
            const params = {
                totalItems: this.totalItems,
                minRowHeight: this.minRowHeight,
                viewportHeight: this.viewportHeight,
                scrollTop: this.scrollTop
            };
            this.oldState = virtualScrollDriver(
                params,
                this.oldState,
                this.getRenderHeight
            );
            this.topPlaceholderHeight = this.oldState.topPlaceholderHeight;
            this.middlePlaceholderHeight = this.oldState.middlePlaceholderHeight;
            this.startIndex = this.oldState.firstMiddleItem;
            this.endIndex = this.startIndex + this.oldState.middleItemCount;
            console.log(this.oldState);
        });
    },
    destroyed() {
        this.$refs.root.removeEventListener("scroll", this.handleScroll);
    }
});

Может ли кто-нибудь любезно сказать мне, как я могу получить высоту каждого элемента в списке с помощью Vue? Я не хочу жестко задавать высоту, поскольку мой контент динамический c

...