Automatic scroll Vue.Js

Asked

Viewed 475 times

0

Clicking on one of the small or large buttons displays the container with the cards (Small Mix and Small Fruit Only). I need the page to scroll down when displaying the footer to cover the cards. I created the function scrollToEnd for this but nothing happens.

inserir a descrição da imagem aqui

<template>
<div class="basket">
    <section class="container has-text-centered">
        <div v-if="errored">
            <h3 class="danger">Pedimos desculpas, não estamos conseguindo recuperar as informações no momento. Por
                favor, tente novamente mais tarde.</h3>
        </div>
        <div v-else>
            <div v-if="loading">
                <h3>Carregando...</h3>
            </div>
            <div class="columns is-mobile">
                <div class="column collum-btn" v-for="(availableSize, key) in availableSizes"
                     :key="availableSize.id">
                    <div class="box-btn-check" v-if="key % 2 === 0">
                        <a class="button basket-btn"
                           @click="selectBasketSize($event, availableSize.id)">{{
                            availableSize.name }} - R$ {{ formatPrice(availableSize.price) }}</a>
                        <img class="check-icon is-hidden" src="../assets/check.png">
                    </div>
                    <div v-else class="box-btn-check">
                        <a class="button basket-btn" @click="selectBasketSize($event, availableSize.id)">{{
                            availableSize.name }} - R$ {{ formatPrice(availableSize.price) }}</a>
                        <img class="check-icon is-hidden" src="../assets/check.png">
                    </div>
                </div>
            </div>
        </div>
    </section>
    <section class="container mt-30 section-baskets">
        <div class="columns is-desktop">
            <div class="column is-half is-offset-one-quarter">
                <div class="card card-basket" v-for="basket in baskets" :key="basket.id">
                    <header class="card-header">
                        <p class="card-header-title">{{ basket.name }}</p>
                        <button class="button button btn-details"
                                @click="toggleCardContent()">
                            Ver
                        </button>
                        <button class="button btn-that"
                                @click="$emit('thisBasket', { stage: 'Cesta ' + basket.name + ' escolhida', progress: 100 })">
                            Quero Essa!
                        </button>
                    </header>
                    <div class="card-content" :class="{ 'is-hidden': isHidden }">
                        <div class="content">
                            <div class="columns is-mobile" v-for="category in basket.categories" :key="category.id">
                                <div class="column">
                                    <img :src="storageUrl + category.image">
                                </div>
                                <div class="column is-two-thirds collumn-text-basket">
                                    <p class="text-options-basket">Escolha {{ category.pivot.quantity }}</p>
                                    <p class="text-options-basket">{{ category.name }}</p>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </section>
</div>
</template>

<script>
import axios from 'axios';

export default {
    name: 'Basket',
    data() {
        return {
            loading: true,
            errored: false,
            availableSizes: [],
            baskets: [],
            isHidden: true,
            activeIcon: false
        }
    },
    computed: {
        storageUrl: function () {
            return process.env.VUE_APP_STORAGE;
        },

        apiUrl: function () {
            return process.env.VUE_APP_ROOT_API;
        }
    },
    props: {},
    methods: {
        selectBasketSize: function (event, size) {
            this.$emit('stage', {
                stage: 'Antes de selecionar os produtos, escolha um tipo de cesta.',
                progress: 0
            });
            if (event.currentTarget.className === 'button basket-btn' && this.$el.querySelector(".basket-btn-selected") === null) {
                this.getSelectedBaskets(size);
                event.currentTarget.nextSibling.className = 'check-icon';
                event.currentTarget.className = 'button basket-btn-selected';
            } else {
                this.getSelectedBaskets(size);
                this.$el.querySelector(".basket-btn-selected").nextSibling.className = 'check-icon is-hidden';
                this.$el.querySelector(".basket-btn-selected").className = 'button basket-btn';
                event.currentTarget.nextSibling.className = 'check-icon';
                event.currentTarget.className = 'button basket-btn-selected';
            }
        },

        formatPrice(value) {
            let val = (value / 1).toFixed(2).replace('.', ',');
            return val.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ".");
        },

        toggleCardContent: function () {
            if (this.isHidden === true) {
                return this.isHidden = false;
            }
            return this.isHidden = true;
        },

        getSelectedBaskets: function (id) {
            axios
                .get(this.apiUrl + '/baskets/' + id + '')
                .then(response => {
                    this.baskets = response.data;
                })
                .catch(error => {
                    this.errored = true;
                    console.log(error);
                })
                .finally(() => this.loading = false)
            this.scrollToEnd();
        },

        scrollToEnd: function () {
            var container = this.$el.querySelector(".section-baskets");
            container.scrollTop = container.scrollHeight;
        },
    },
    mounted() {
        axios
            .get(this.apiUrl + '/available-sizes')
            .then(response => {
                this.availableSizes = response.data;
            })
            .catch(error => {
                this.errored = true;
                console.log(error);
            })
            .finally(() => this.loading = false)
    }
}
</script>

<style scoped lang="scss">
.basket {
    padding-left: 10px;
    padding-right: 10px;
}

.danger {
    color: red;
    font-size: 1.5rem;
}

.collum-btn {
    padding: 10px;
}

.basket-btn {
    position: absolute;
    top: -10%;
    left: 0;
    right: 0;
    background-color: #86cb3c;
    color: #ffffff;
    border: 1px solid #86cb3c;
    border-radius: 15px;
    font-size: 0.9rem;
    &:hover {
        position: absolute;
        top: -10%;
        left: 0;
        right: 0;
        background-color: #86cb3c;
        color: #86cb3c;
        border: 1px solid #86cb3c;
        border-radius: 15px;
    }
}

.basket-btn-selected {
    position: absolute;
    top: -10%;
    left: 0;
    right: 0;
    background-color: #ffffff;
    color: #86cb3c;
    border: 1px solid #ffffff;
    border-radius: 15px;
    font-size: 0.9rem;
    &:hover {
        position: absolute;
        top: -10%;
        left: 0;
        right: 0;
        background-color: #ffffff;
        color: #86cb3c;
        border: 1px solid #ffffff;
        border-radius: 15px;
    }
}

.box-btn-check {
    position: relative;
    margin-bottom: 50px;
}

.check-icon {
    position: absolute;
    top: -32px;
    right: 0;
}

@media(min-width: 992px) {
    .basket-btn {
        background-color: #ffffff;
        font-size: 1.4rem;
        color: #629b30;
        border: 1px solid #629b30;
    }

    .basket-btn:hover {
        background-color: #86cb3c;
        color: #ffffff;
        font-size: 1.4rem;
        border: none;
    }

    .basket-btn-selected {
        background-color: #86cb3c;
        font-size: 1.4rem;
        color: #ffffff;
        border: 1px solid #86cb3c;
    }
}

.card-basket {
    margin: 10px 15px 20px 10px;
    border-radius: 15px;
    box-shadow: none;
}

.card-header {
    p {
        color: #000000;
        font-size: 0.8rem;
    }
}

.btn-details {
    background-color: #629b30;
    color: #ffffff;
    border: none;
    border-radius: 10px;
    margin: 10px 5px 10px 0;
}

.btn-that {
    background-color: #629b30;
    color: #ffffff;
    border: none;
    border-radius: 10px;
    margin: 10px 10px 10px 5px;
}

.collumn-text-basket {
    padding-top: 16px;
}

.text-options-basket {
    margin: 0 !important;
}
</style>

1 answer

0

If there is no impediment for you, I advise installing the package https://www.npmjs.com/package/vue-scrollto and if you want to know how to do the implementation on your own, read the source code to understand how to handle the event.

To solve the problem using the package, just install and configure it inside the main.js file where Vue is instantiated.

Once this is done, just use the directive v-scroll-to="'#idDoElement'" inside the button or link that will execute the scoll action.

  • 2

    It would be great if you put the important parts in the body of the answer, not just the link. I advise you to read the [tour] to learn more about how the site works.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.