How can I navigate between sections using child-parent components in Vue 3?

47 Views Asked by At

How can i navigate between sections using child-parent components in Vue 3, Options API, just like when I do not using child components? Moving between components without child components works as intended in this code.

goTo is actually intended to first make that element visible and then scroll it into view and goBack is actually intended to hide element and then scroll back to where you came from but I left that out here for simplicity sake.

See CodeSandbox

Vue.js:

<template>
  <section id="1" ref="1">
    <p>Section 1</p>
    <button @click="goTo('1', '2')">Goto section 2</button>
    <button @click="goTo('1', '3')">Goto section 3</button>
    <button @click="goBack()">Back</button>
  </section>
  <section id="2" ref="2">
    <p>Section 2</p>
    <button @click="goTo('2', '1')">Goto section 1</button>
    <button @click="goTo('2', '3')">Goto section 3</button>
    <button @click="goBack()">Back</button>
  </section>

  <section id="3" ref="3">
    <Section3 :from="from" />
  </section>
</template>

<script>
import Section3 from "./Section3.vue";
export default {
  name: "App",
  data() {
    return {
      from: "",
    };
  },
  components: {
    Section3,
  },
  methods: {
    goTo(from, to) {
      this.from = from;
      this.$refs[to].scrollIntoView({ behavior: "smooth" });
    },
    goBack() {
      this.$refs[this.from].scrollIntoView({ behavior: "smooth" });
    },
  },
};
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
section {
  height: 400px;
  border: solid 1px black;
  margin-bottom: 500px;
}
</style>

Section3:

<template>
  <p>Section 3</p>
  <button @click="goTo('1')">Goto section 1</button>
  <button @click="goTo('2')">Goto section 2</button>
  <button @click="goBack()">Back</button>
</template>

<script>
export default {
  name: "Section3",
  props: {
    from: String
  },
  methods: {
    goTo(to) {
      this.$refs[to].scrollIntoView({ behavior: "smooth" });
    },
    goBack() {
      this.$refs[this.from].scrollIntoView({ behavior: "smooth" });
    }
  }
}
</script>

<style scoped>

</style>

I can pass prop from to the child component and copy the methods inside the child component but this.$refs doesn't contain the refs from the parent component so this.$refs[from].scrollIntoView() won't work.

What is the best way to do that? Should I somehow pass the refs from the parent to the child, and would scrolling parent element into view work?

0

There are 0 best solutions below