当我滚动到vue.js中的组件时,如何动态更改URL中的散列?
我有一个带有多个组件的单页vue.js应用程序,现在我想在滚动这些组件时动态更改url中的散列。例如,如果您尝试在vue.js文档中滚动:
从以下位置滚动时,您会发现url正在更改:
https://v3.vuejs.org/guide/introduction.html#what-is-vue-js
至此:
https://v3.vuejs.org/guide/introduction.html#getting-started
以此类推。
我尝试在组件的第一个标记上创建@scroll="changeRoute"
,这会触发一个函数:
<script>
import { useRouter } from "vue-router";
export default {
setup() {
const router = useRouter();
const changeRoute = () => {
router.push({
name: "Home",
hash: "#landing-section",
});
console.log("route changes");
};
return {
changeRoute,
};
},
};
</script>
b此操作不起作用,该函数甚至未执行?
解决方案
为了帮助您入门,因为您提供了VUE文档作为示例,所以您只能在他们的页面上查看它是如何工作的。
他们使用了名为VuePress的包,该包具有setActiveHash函数。
看起来像是他们debounce
滚动事件,然后使用querySelectorAll
获取他们要用来更改哈希的所有元素,然后确定这些元素是否处于活动状态,然后用活动的元素哈希替换当前的哈希。
/* global AHL_SIDEBAR_LINK_SELECTOR, AHL_HEADER_ANCHOR_SELECTOR */
import debounce from 'lodash.debounce'
export default {
mounted () {
window.addEventListener('scroll', this.onScroll)
},
methods: {
onScroll: debounce(function () {
this.setActiveHash()
}, 300),
setActiveHash () {
const sidebarLinks = [].slice.call(document.querySelectorAll(AHL_SIDEBAR_LINK_SELECTOR))
const anchors = [].slice.call(document.querySelectorAll(AHL_HEADER_ANCHOR_SELECTOR))
.filter(anchor => sidebarLinks.some(sidebarLink => sidebarLink.hash === anchor.hash))
const scrollTop = Math.max(
window.pageYOffset,
document.documentElement.scrollTop,
document.body.scrollTop
)
const scrollHeight = Math.max(
document.documentElement.scrollHeight,
document.body.scrollHeight
)
const bottomY = window.innerHeight + scrollTop
for (let i = 0; i < anchors.length; i++) {
const anchor = anchors[i]
const nextAnchor = anchors[i + 1]
const isActive = i === 0 && scrollTop === 0
|| (scrollTop >= anchor.parentElement.offsetTop + 10
&& (!nextAnchor || scrollTop < nextAnchor.parentElement.offsetTop - 10))
const routeHash = decodeURIComponent(this.$route.hash)
if (isActive && routeHash !== decodeURIComponent(anchor.hash)) {
const activeAnchor = anchor
// check if anchor is at the bottom of the page to keep $route.hash consistent
if (bottomY === scrollHeight) {
for (let j = i + 1; j < anchors.length; j++) {
if (routeHash === decodeURIComponent(anchors[j].hash)) {
return
}
}
}
this.$vuepress.$set('disableScrollBehavior', true)
this.$router.replace(decodeURIComponent(activeAnchor.hash), () => {
// execute after scrollBehavior handler.
this.$nextTick(() => {
this.$vuepress.$set('disableScrollBehavior', false)
})
})
return
}
}
}
},
beforeDestroy () {
window.removeEventListener('scroll', this.onScroll)
}
}
相关文章