vue实现跨页面定位锚点区域

实际企业项目开发中,如何基于Vue2,利用锚点实现元素区域滚动定位

实际企业项目开发中,如何基于Vue2,利用锚点实现元素区域滚动定位。

项目需求

  • 点击左菜单,实现右边内容区域滚动定位;
  • 管理页,可以预览该页,并根据预览内容的id定位到滚动区域;

需求分析并实现

需求一:点击左菜单,实现右边内容区域滚动定位

1、如果你使用的是ant-design Vue UI库,是可以使用自带的锚点组件的

<template>
  <!-- 左边菜单区 -->
  <a-anchor :affix="false" :get-current-anchor="getCurrentAnchor">
  	<!-- 一级锚点 -->
    <a-anchor-link href="#menu1" title="菜单一">   
      <!-- 二级锚点 -->
      <a-anchor-link href="#menu2" title="菜单二" />
    </a-anchor-link>
  </a-anchor>
   <!-- 右边内容滚动区 -->
   <div id="menu1">菜单一的详细内容</div>
   <div id="menu2">菜单二的详细内容</div>
</template>
<script>
export default {
  methods: {
    // 默认高亮的锚点
    getCurrentAnchor() {
      return '#menu1';
    },
  },
};
</script>

优点:
1、已经封装好的,方便使用
缺点:
1、a-anchor组件,原理是类似:a标签的href属性值(href=“#menu”)和内容区域id属性值(<div id=‘menu’>)一致,实现锚点定位,但是,同时浏览器URL地址会拼接#id,对于Vue开发的项目来说, 如果当前页面地址是 http://localhost:8080/#/since, 你点击锚点:菜单一,路径就会变成: http://localhost:8080/#/menu1, 此时刷新页面页面跳转失败,页面内容丢失
2、缺点二就是无法实现 需求二,无法满足在其他页面 打开该页面,根据内容id实现,内容区域滚动

2、如果使用的是 Element UI, 该UI库对于Vue2,来说是没有锚点相关的组件的,所以需要借助第三方插件 vue-scrollto

1、 npm install --save vue-scrollto
2、 在需要使用锚点的组件中:
var VueScrollTo = require('vue-scrollto');
3、给锚点添加点击事件
var options = {
    container: '#container',
    easing: 'ease-in',
    lazy: false,
    offset: -60,
    force: true,
    cancelable: true,
    onStart: function(element) {
      // scrolling started
    },
    onDone: function(element) {
      // scrolling is done
    },
    onCancel: function() {
      // scrolling has been interrupted
    },
    x: false,
    y: true
}
VueScrollTo.scrollTo(element, duration, options)

gitHubvue-scrollto插件地址

缺点:
亲测无效,无法实现,点击左边菜单,右侧内容滚动

看了好多博主,有的需要在router.js路由文件处理,有的需要在组件实例中watch路由(router),好像都没用

需求最终实现:

利用scrollIntoView方法,同时实现需求一和需求二

  1. 实现需求一:点击左菜单,实现右边内容区域滚动定位(监听路由)
// 1、在左菜单点击事件中,实现如下代码
点击左菜单 当前页面路由拼接 search参数(菜单对应的右边内容id)
// 2、在锚点页面,监听路由变化
监听路由变化,获取search参数,

// 3、设置document.body.scrollTop    (document 和 this.$el 都可以)
document.body.scrollTop = this.$el.querySelector('#'+search参数).scrollIntoView()

// 最终代码
 watch: {
    // 点击左菜单路由可以监听到 但是点击栏目预览  需要走mounted()
   $route(newRoute) {
     if (!newRoute.query.programId) return;
     // 点击锚点  路由监听不到
     // console.log(newRoute.params.programId,'newRoute.params.programId')
     let id = "program" + this.$route.query.programId;
     this.$nextTick(()=>{
       if(this.$el.querySelector(`#${id}`)) {
         // scrollIntoView  不能随便添加参数  建议不要加任何参数
         document.body.scrollTop = this.$el.querySelector(`#${id}`).scrollIntoView();
       }
     });
     this.saveCurrentProgramId = newRoute.query.programId;
   },
 },
  1. 管理页,可以预览该页,并根据预览内容的id定位到滚动区域;(mounted()钩子中实现)
// 1、在锚点页面,mounted()钩子中,获取search参数id
this.$router.query.id
监听路由变化,获取search参数,
// 2、设置document.body.scrollTop
// document 和 this.$el 都可以
document.body.scrollTop = this.$el.querySelector('#'+search参数).scrollIntoView()

// 最终代码
mounted() {
  let that = this;
  // id选择器不能以数字开头 不能包含 / 等特殊字符
  setTimeout(function() {
    if(that.$route.query.programId) {
      let id = "program" + that.$route.query.programId;
      if(that.$el.querySelector(`#${id}`)) {
        // scrollIntoView  不能随便添加参数  建议不要加任何参数
        document.body.scrollTop = that.$el.querySelector(`#${id}`).scrollIntoView();
      }
    }
  },1000)
}

scrollIntoView()方法文档

注意:

  • scrollIntoView()方法最好不要添加任何参数,加了参数有可能失效
  • id选择器千万不能以数字开头,且不能包括 \ 等特殊字符(我为了拼接原先页面的路径和id,将内容区域id熟悉写成:id=‘since/123’),此时会报错:选择器无效
  • this.$el后面不能使用getElementId类似方法,只能使用querySelector类似的方法
  • 元素渲染时期问题,需要添加定时器和this.$nextTick(()=>()),来操作元素
  • 核心代码:document.body.scrollTop = this.$el.querySelector(‘#’+search参数).scrollIntoView()

缺点
在Vue项目中,使用了document对象,虽然需求实现了,但是并不是最好的。如果你们有较好的方法可以评论区回复

题外话:
有的博主写的是:

document.body.scrollTop = this.$el.querySelector(selector).offsetTop

亲测无效

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
Vue实现页面跳转锚点有两种方法。第一种是非页面锚点跳转,可以在标签中使用JavaScript方法实现。例如,在组件A中,可以使用以下代码实现跳转到组件B的指定位置的锚点: ```html <div class="content"> <a href="javascript:void(0)" @click="goAnchor()">gotoOther</a> </div> ``` 然后,在组件A的methods中添加goAnchor方法: ```javascript methods: { goAnchor() { var anchor = this.$el.querySelector("#锚点的id或name值") document.body.scrollTop = anchor.offsetTop } } ``` 第二种方法是页面锚点跳转,可以使用路由来实现。在组件A中,可以使用以下代码实现跳转到组件B的指定位置的锚点: ```html <div class="content"> <a href="/b组件路由#锚点的id或name值">gotoOther</a> </div> ``` 需要注意的是,需要将跳转目标的路由和锚点的id或name值组合在一起。 在组件B中,需要设置对应的锚点位置。例如: ```html <div class="content-modal" id="c"> // 设置id ccc </div> <div class="content-modal" id="d"> // 设置id ddd </div> <div class="content-modal" id="e"> // 设置id eee </div> <div class="content-modal" id="f"> // 设置id fff </div> ``` 为了在组件B加载时自动滚动到指定的锚点位置,可以在mounted钩子函数中添加以下代码: ```javascript mounted() { if (window.location.hash) { this.goAnchor(window.location.hash) } }, methods: { goAnchor(selector) { setTimeout(() => { // 获取锚点元素 const anchor = this.$el.querySelector(selector) anchor.scrollIntoView() }, 500) } } ``` 这样,在组件B加载时,如果URL中包含锚点信息,页面会自动滚动到对应的锚点位置。 请根据你的需求选择合适的方法来实现Vue页面跳转锚点。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [vue 实现页面锚点跳转](https://blog.csdn.net/yimaode/article/details/104649672)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [VUE页面锚点(nuxt同样适用)](https://blog.csdn.net/Poppy_LYT/article/details/119995904)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

原谅我很悲

不要打赏哦,加个好友一起学习呗

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值