滚动到 Vue.js 中子组件的部分

Scroll to section from child component in Vue.js

我正在尝试了解如何从子组件向父组件发出事件,该事件通过 ref 或 id 滚动到正确的部分。因此,例如导航菜单是一个带有 link 的子组件。当我单击 link 时,父级中的相应部分将滚动到视图中。我来自 React,所以我有点被抛弃了。如何向上传递参数以滚动到正确的 ref 或 id?基本上锚link的行为方式。

这是我到目前为止得到的。我不确定我应该使用 links ,我可能需要按钮,因为我没有浏览页面。

Navigation.vue(儿童)

<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(父级)

<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>

您可以在子组件中发出带有参数(例如部分 ref)的事件:

<a @click="$emit('go-section', 'contact')" href="/">Contact</a>
<a @click="$emit('go-section', 'projects')" href="/">Projects</a>

然后在parent的监听方法中使用这个参数

// template
<Navigation @go-section="goToSection" />

// js
goToSection(sectionRef) {
  var element = this.$refs[sectionRef];
  var top = element.offsetTop;
  window.scrollTo(0, top);
},

您可以使用 a 标记但阻止默认 link 行为,并将 ref 传递给您的 goSection 方法:

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>