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>
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')" href="/">Contact</a>
</li>
<li>
<a href="#" @click.prevent="goSection('projects')">Projects</a>
</li>
<li>
<a href="#" @click.prevent="goSection('skils')">Skills</a>
</li>
<li>
<a 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>