如何使用Vue Router跳转到指定元素ID并实现对应章节定位展示
实现方案
1. 修正路由配置
你之前的路由嵌套逻辑有误,因为三个组件是嵌套渲染在同一个页面内,不需要拆分为子路由拆分加载,直接配置单路由携带两个参数即可:
// router/index.js 配置 import Navigation from '@/components/Navigation.vue' const routes = [ { path: "/navigation/:sectionName/:storyName", name: "StoryDetail", component: Navigation } ]
配置后访问路径就会自动匹配你需要的 www.mystorys.com/navigation/sectionBatman/wheresRobin 格式。
2. 导航跳转传参
做侧边导航目录时,直接通过命名路由传递参数即可:
<!-- 导航目录的story点击项示例 --> <router-link :to="{ name: 'StoryDetail', params: { sectionName: section.name, // 对应section的唯一标识名 storyName: story.name // 对应story的唯一标识名 } }" > {{ story.name }} </router-link>
3. 调整组件逻辑匹配参数+滚动定位
注意:你原有的数据集结构有误,navigation.section、currentSection.story 都是对象格式,无法用 v-for 遍历,需要改为数组格式,示例中统一改为 sections、stories 数组字段。
3.1 Navigation 组件修改
<script> export default { data() { return { navigation: { // 修正后的数组格式数据 sections: [ { id: 1, name: 'sectionBatman', stories: [ {id:1, hero: 'Batman', story: '蝙蝠侠故事内容', name: 'Batman story'}, {id:4, hero: 'Robin', story: '罗宾去哪了内容', name: 'wheresRobin'}, // 其余story数据 ] }, { id:2, name: 'Animal Section', stories: [ // 动物类story数据 ] } ] }, targetStoryName: '' } }, mounted() { const { sectionName, storyName } = this.$route.params if(sectionName && storyName) { this.targetStoryName = storyName // 如果需要只展示命中的section,保留下面的过滤逻辑;如果要展示所有section仅滚动定位,删掉即可 this.navigation.sections = this.navigation.sections.filter(sec => sec.name === sectionName) } }, // 监听路由变化,同页面切换story时更新定位目标 watch: { '$route.params'(newParams) { const { sectionName, storyName } = newParams this.targetStoryName = storyName this.navigation.sections = this.navigation.sections.filter(sec => sec.name === sectionName) } } } </script> <template> <div v-for="section in navigation.sections" :key="section.id"> <p> I am Section {{section.name}} </p> <section-component :currentSection="section" :target-story="targetStoryName"></section-component> </div> </template>
3.2 Section 组件修改
<script> export default { props: ['currentSection', 'targetStory'], // 组件渲染完成后触发滚动 updated() { if(this.targetStory) { this.$nextTick(() => { // 找到目标story的dom节点 const targetStoryEl = this.$el.querySelector(`[data-story-name="${this.targetStory}"]`) if(targetStoryEl) { // 平滑滚动到目标位置 targetStoryEl.scrollIntoView({ behavior: 'smooth', block: 'start' }) } }) } } } </script> <template> <div v-for="story in currentSection.stories" :key="story.id" :data-story-name="story.name"> <p> I am the Story about {{story.hero}} </p> <story :content="story"></story> </div> </template>
3.3 Story 组件无需修改,保持原有逻辑即可。
内容的提问来源于stack exchange,提问作者JohnW2Smith
相关产品推荐
相关产品推荐

