Ad

Scroll To Section From Child Component In Vue.js

I am trying to understand how to emit an event from a child component to the parent that scrolls to the correct section via a ref or id. So for example the navigation menu is a child component with links. when I click a link, the corresponding section in the parent scrolls into view. I am coming from React so I am a bit thrown off. How do I pass parameters up to scroll to correct ref or id? basically the way anchorlinks act.

Here is what I got so far.. I am not sure I should be using links , I might need buttons since i'm not navigating pages.

Navigation.vue (Child)

<template>
  <div class="navigation">
    <img class="logo" alt="Vue logo" src="../assets/logo.png" />
    <nav>
      <ul>
        <li>
          <a @click="goSection" href="/">Contact</a>
        </li>
        <li>
          <a href="/">Projects</a>
        </li>
        <li>
          <a href="/">Skills</a>
        </li>
        <li>
          <a href="/">Education</a>
        </li>
      </ul>
    </nav>
  </div>
</template>

<script>
export default {
  name: "Navigation",
  //I want to emit an event in the parent where the page section scrolls in to view//
  methods: {
    goSection() {
      this.$emit("go-section", this.value);
    },
  },
};
</script>

App.vue (Parent)

<template>
  <div id="app">
    <Navigation @go-section="goToSection" />
    
    <section class="section" ref="projects">
      <p>Projects</p>
    </section>
    <section class="section" ref="skills">
      <p>Skills</p>
    </section>
    <section class="section" ref="contact">
      <p>Contacts</p>
    </section>
  </div>
</template>

<script>
import Navigation from "./components/Navigation.vue";
export default {
  name: "App",
  components: {
    Navigation,
  },
  methods: {
    goToSection(event, value) {
      var element = this.$refs[(event, value)];
      var top = element.offsetTop;
      window.scrollTo(0, top);
    },
  },
};
</script>
Ad

Answer

You can use a tag but prevent default link behavior, and pass ref to your goSection method :

Vue.component('navigation', {
  template: `
    <div class="navigation">
      <img class="logo" alt="Vue logo" src="../assets/logo.png" />
      <nav>
        <ul>
          <li>
            <a @click.prevent="goSection('contact')" target="_blank" rel="nofollow noreferrer" href="/">Contact</a>
          </li>
          <li>
            <a target="_blank" rel="nofollow noreferrer" href="#" @click.prevent="goSection('projects')">Projects</a>
          </li>
          <li>
            <a target="_blank" rel="nofollow noreferrer" href="#" @click.prevent="goSection('skils')">Skills</a>
          </li>
          <li>
            <a target="_blank" rel="nofollow noreferrer" href="#" @click.prevent="goSection('contact')">Education</a>
          </li>
        </ul>
      </nav>
    </div>
  `,
   methods: {
    goSection(val) {
      this.$emit("go-section", val);
    },
  },
})

new Vue({
  el: '#demo',
  methods: {
    goToSection(value) {
      const top = this.$refs[(value)].offsetTop;
      window.scrollTo({
        top: top,
        left: 0,
        behavior: 'smooth'
      });
    },
  },
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="demo">
  <navigation @go-section="goToSection"></navigation>
  <section class="section" ref="projects">
    <p>Projects</p>
  </section>
  <section class="section" ref="skills">
    <p>Skills</p><p>Skills</p><p>Skills</p><p>Skills</p><p>Skills</p><p>Skills</p><p>Skills</p><p>Skills</p><p>Skills</p><p>Skills</p><p>Skills</p><p>Skills</p><p>Skills</p><p>Skills</p><p>Skills</p><p>Skills</p><p>Skills</p>
  </section>
  <section class="section" ref="contact">
    <p>Contacts</p>
  </section>
</div>

Ad
source: stackoverflow.com
Ad