You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue.js如何一键切换区块可见性并滚动到目标区块?

Vue切换区块时滚动需两次点击的问题解决及优化方案

问题原因

Vue的响应式DOM更新是异步的。你修改show2/show3这些显示变量后,Vue不会立刻更新页面DOM,而是把DOM更新任务放进异步队列延后执行。这时候直接调用scrollIntoView,目标元素还处于display: none的隐藏状态,滚动操作找不到可滚动的目标元素,所以第一次点击只有显示状态切换,第二次点击时DOM已经完成更新,元素显示出来,滚动才生效。

快速修复方案

把滚动操作放到this.$nextTick()回调里,等待Vue完成DOM更新后再执行滚动:

修改后的showScrollInto方法:

showScrollInto(from, to) {
  // 隐藏原区块
  switch(from) {
    case "2":
      this.show2 = false
      break
    case "3":
      this.show3 = false
      break
    default:
      this.show1 = true
  }

  // 显示目标区块
  switch(to) {
    case "2":
      this.show2 = true
      break
    case "3":
      this.show3 = true
      break
    default:
      this.show1 = true
  }

  // 等待DOM更新完成后执行滚动
  this.$nextTick(() => {
    this.$refs[to].scrollIntoView({ behavior: 'smooth'})
  })
}

优化实现方案(无需单独show变量、无需传递from参数)

用一个activeSection变量记录当前激活的区块ID,所有区块的显示状态都由这个变量控制,不用维护多个独立的show变量,也不用传递来源区块参数:

完整代码示例:

<template>
  <section id="1" ref="1" v-show="activeSection === '1'" style="margin-bottom: 500px">
    <p>Section 1</p>
    <button @click="switchSection('2')">Goto section 2</button>
    <button @click="switchSection('3')">Goto section 3</button>
  </section>
  <section id="2" ref="2" v-show="activeSection === '2'">
    <p>Section 2</p>
    <button @click="switchSection('1')">Goto home</button>
  </section>
  <section id="3" ref="3" v-show="activeSection === '3'">
    <p>Section 3</p>
    <button @click="switchSection('1')">Goto home</button>
  </section>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      activeSection: '1' // 默认激活第一个区块
    }
  },
  methods: {
    switchSection(targetId) {
      this.activeSection = targetId
      this.$nextTick(() => {
        this.$refs[targetId].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;
}
</style>

这个优化方案的优势:

  • 只用一个变量维护激活状态,代码更简洁,不易出错
  • 方法无需接收来源区块参数,逻辑更清晰
  • 扩展性更强,新增区块时只需添加对应的section和切换按钮,无需修改data和方法逻辑

内容的提问来源于stack exchange,提问作者user1837293

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 02:55:20