Scroll down when clicked with Vue.js

What I want to do is that when the user clicks on an article, it scrolls down to a sibling section. Code looks something like this.

<template>
    <article @click="handleCardClick" class="text-center mr-8 mb-12 cursor-pointer hover:opacity-50 w-1/5">
        <picture class="flex justify-center items-center mb-4 w-full" style="height: 320px">
            <img :src="source" :alt="imgAlt" class="shadow-md" style="" />
        </picture>
        <h4 class="font-bold mb-1">{{ title }}</h4>
        <h6 class="text-sm text-gray-600">{{ tags.length > 0 ? tags[0].name : '' }}</h6>
    </article>
</template>
<script>
    import { mapActions, mapState } from 'vuex';

    export default {
        props: {
            title: {
                type: String,
                required: true,
            },
        },
        computed: {
            ...mapState({
                previewIndex: state => state.templates.hasTemplate
            }),
        },
        methods: {
            ...mapActions({
                setActiveTemplate: 'templates/setActive',
                setPreview: 'templates/setPreview',
                removePreview: 'templates/removePreview',
            }),
            handleCardClick () {
                this.setActiveTemplate(this.template);
                this.selectTemplate(this.pos);
            },
        }
    }
</script>

And the other file looks like this

<template>
    <section v-if="template" class="flex justify-between w-full pt-10 pl-10 pr-5 pb-12 relative border-b border-t border-black my-4" style="height: 75vh">
        <article class="flex flex-col justify-between" style="width: 25%">
            <button @click="changeSection('invite')" class="h-1/3 pb-4">
                <picture class="h-full w-full flex justify-center items-center bg-gray-100">
                    <img :src="template.url || ''" class="bg-gray-200 shadow-lg" style="min-height: 20px; min-width: 20px; height:80%" alt="Preview de la invitacion">
                </picture>
            </button>
        </article>
    </section>
</template>

I'm a bit new to Vue, so maybe it's really simple and I just can't find how to do it :) Thanks in advance!

Upvotes: 2

Views: 4610

Answers (1)

yuri
yuri

Reputation: 3400

You only need to assign a reference ref to each article and then build a method to go to any of your referenced articles:

<article @click="goto('art1')">Go to article 1</article>

For earch sibiling declare it's reference so you can call them on the goto method

<article ref="art1">
    Article 1
</article>

Declare the goto method, it has a parameter, the reference of where you want to go.

methods: {
    goto(refName) {
        var element = this.$refs[refName];
        var top = element.offsetTop;
        window.scrollTo(0, top);
    }
},

And this is it.


If you have the click action inside a child component then you'll have to use $emit to perform the click action on the parent, here is an example following the above:

Parent

<template>
    <Article @scrollto="goto"></Article>
    <Section ref="art1">
      ...
    </Section>  
</template>
<script>
import Article from "./article";
import Section from "./section";
    export default {
        methods: {
          goto(refName) {
            var element = this.$refs[refName];
            var top = element.offsetTop;
            window.scrollTo(0, top);
          }
        }
     }
</script>

Article.vue

<template>
  <div>
    <button @click="$emit("scrollto", 'art1')">
      Go to the Article!
    </button>
  </div>
</template>

Documentation about vue ref function

Documentation about window.scrollTo function

Upvotes: 4

Related Questions