vue實(shí)現(xiàn)跨頁面定位錨點(diǎn)區(qū)域方式
實(shí)際企業(yè)項(xiàng)目開發(fā)中,如何基于Vue2,利用錨點(diǎn)實(shí)現(xiàn)元素區(qū)域滾動(dòng)定位
項(xiàng)目需求
- 點(diǎn)擊左菜單,實(shí)現(xiàn)右邊內(nèi)容區(qū)域滾動(dòng)定位;
- 管理頁,可以預(yù)覽該頁,并根據(jù)預(yù)覽內(nèi)容的id定位到滾動(dòng)區(qū)域;
需求分析并實(shí)現(xiàn)
需求一
點(diǎn)擊左菜單,實(shí)現(xiàn)右邊內(nèi)容區(qū)域滾動(dòng)定位
1、如果你使用的是ant-design Vue UI庫,是可以使用自帶的錨點(diǎn)組件的
<template>
<!-- 左邊菜單區(qū) -->
<a-anchor :affix="false" :get-current-anchor="getCurrentAnchor">
<!-- 一級(jí)錨點(diǎn) -->
<a-anchor-link href="#menu1" rel="external nofollow" title="菜單一">
<!-- 二級(jí)錨點(diǎn) -->
<a-anchor-link href="#menu2" rel="external nofollow" title="菜單二" />
</a-anchor-link>
</a-anchor>
<!-- 右邊內(nèi)容滾動(dòng)區(qū) -->
<div id="menu1">菜單一的詳細(xì)內(nèi)容</div>
<div id="menu2">菜單二的詳細(xì)內(nèi)容</div>
</template>
<script>
export default {
methods: {
// 默認(rèn)高亮的錨點(diǎn)
getCurrentAnchor() {
return '#menu1';
},
},
};
</script>優(yōu)點(diǎn):
1、已經(jīng)封裝好的,方便使用
缺點(diǎn):
1、a-anchor組件,原理是類似:a標(biāo)簽的href屬性值(href=“#menu”)和內(nèi)容區(qū)域id屬性值(<div id=‘menu’>)一致,實(shí)現(xiàn)錨點(diǎn)定位,但是,同時(shí)瀏覽器URL地址會(huì)拼接#id,對(duì)于Vue開發(fā)的項(xiàng)目來說, 如果當(dāng)前頁面地址是 http://localhost:8080/#/since, 你點(diǎn)擊錨點(diǎn):菜單一,路徑就會(huì)變成: http://localhost:8080/#/menu1, 此時(shí)刷新頁面頁面跳轉(zhuǎn)失敗,頁面內(nèi)容丟失
2、缺點(diǎn)二就是無法實(shí)現(xiàn) 需求二,無法滿足在其他頁面 打開該頁面,根據(jù)內(nèi)容id實(shí)現(xiàn),內(nèi)容區(qū)域滾動(dòng)
2、如果使用的是 Element UI, 該UI庫對(duì)于Vue2,來說是沒有錨點(diǎn)相關(guān)的組件的,所以需要借助第三方插件 vue-scrollto
1、 npm install --save vue-scrollto
2、 在需要使用錨點(diǎn)的組件中:
var VueScrollTo = require('vue-scrollto');
3、給錨點(diǎn)添加點(diǎn)擊事件
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)缺點(diǎn):
親測(cè)無效,無法實(shí)現(xiàn),點(diǎn)擊左邊菜單,右側(cè)內(nèi)容滾動(dòng)
看了好多博主,有的需要在router.js路由文件處理,有的需要在組件實(shí)例中watch路由(router),好像都沒用
需求最終實(shí)現(xiàn)
利用scrollIntoView方法,同時(shí)實(shí)現(xiàn)需求一和需求二
1.實(shí)現(xiàn)需求一:點(diǎn)擊左菜單,實(shí)現(xiàn)右邊內(nèi)容區(qū)域滾動(dòng)定位(監(jiān)聽路由)
// 1、在左菜單點(diǎn)擊事件中,實(shí)現(xiàn)如下代碼
點(diǎn)擊左菜單 當(dāng)前頁面路由拼接 search參數(shù)(菜單對(duì)應(yīng)的右邊內(nèi)容id)
// 2、在錨點(diǎn)頁面,監(jiān)聽路由變化
監(jiān)聽路由變化,獲取search參數(shù),
// 3、設(shè)置document.body.scrollTop (document 和 this.$el 都可以)
document.body.scrollTop = this.$el.querySelector('#'+search參數(shù)).scrollIntoView()
// 最終代碼
watch: {
// 點(diǎn)擊左菜單路由可以監(jiān)聽到 但是點(diǎn)擊欄目預(yù)覽 需要走mounted()
$route(newRoute) {
if (!newRoute.query.programId) return;
// 點(diǎn)擊錨點(diǎn) 路由監(jiān)聽不到
// console.log(newRoute.params.programId,'newRoute.params.programId')
let id = "program" + this.$route.query.programId;
this.$nextTick(()=>{
if(this.$el.querySelector(`#${id}`)) {
// scrollIntoView 不能隨便添加參數(shù) 建議不要加任何參數(shù)
document.body.scrollTop = this.$el.querySelector(`#${id}`).scrollIntoView();
}
});
this.saveCurrentProgramId = newRoute.query.programId;
},
},2.管理頁,可以預(yù)覽該頁,并根據(jù)預(yù)覽內(nèi)容的id定位到滾動(dòng)區(qū)域;(mounted()鉤子中實(shí)現(xiàn))
// 1、在錨點(diǎn)頁面,mounted()鉤子中,獲取search參數(shù)id
this.$router.query.id
監(jiān)聽路由變化,獲取search參數(shù),
// 2、設(shè)置document.body.scrollTop
// document 和 this.$el 都可以
document.body.scrollTop = this.$el.querySelector('#'+search參數(shù)).scrollIntoView()
// 最終代碼
mounted() {
let that = this;
// id選擇器不能以數(shù)字開頭 不能包含 / 等特殊字符
setTimeout(function() {
if(that.$route.query.programId) {
let id = "program" + that.$route.query.programId;
if(that.$el.querySelector(`#${id}`)) {
// scrollIntoView 不能隨便添加參數(shù) 建議不要加任何參數(shù)
document.body.scrollTop = that.$el.querySelector(`#${id}`).scrollIntoView();
}
}
},1000)
}注意:
- scrollIntoView()方法最好不要添加任何參數(shù),加了參數(shù)有可能失效
- id選擇器千萬不能以數(shù)字開頭,且不能包括 \ 等特殊字符(我為了拼接原先頁面的路徑和id,將內(nèi)容區(qū)域id熟悉寫成:id=‘since/123’),此時(shí)會(huì)報(bào)錯(cuò):選擇器無效
- this.$el后面不能使用getElementId類似方法,只能使用querySelector類似的方法
- 元素渲染時(shí)期問題,需要添加定時(shí)器和this.$nextTick(()=>()),來操作元素
- 核心代碼:document.body.scrollTop = this.$el.querySelector(‘#’+search參數(shù)).scrollIntoView()
缺點(diǎn)
在Vue項(xiàng)目中,使用了document對(duì)象,雖然需求實(shí)現(xiàn)了,但是并不是最好的。如果你們有較好的方法可以評(píng)論區(qū)回復(fù)
題外話:
有的博主寫的是:
document.body.scrollTop = this.$el.querySelector(selector).offsetTop
親測(cè)無效!
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Vue實(shí)現(xiàn)組件間通信的幾種方式(多種場(chǎng)景)
本文主要介紹了Vue實(shí)現(xiàn)組件間通信的幾種方式,不同的場(chǎng)景使用不同的方式,基本滿足所有開發(fā)場(chǎng)景中的通信需求,感興趣的可以了解一下2021-10-10
vue3?v-bind="$attrs"繼承組件全部屬性的解決方案
這篇文章主要介紹了vue3?v-bind=“$attrs“?繼承組件全部屬性的解決方案,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-06-06
基于vue實(shí)現(xiàn)swipe輪播組件實(shí)例代碼
本篇文章主要介紹了基于vue實(shí)現(xiàn)swipe輪播組件實(shí)例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-05-05

