Vue.js:如何通过子组件方法滚动到父组件的ref元素
Vue 父子组件页面内滚动解决方案
问题分析
你之前的代码报错是因为两个原因:一是Vue2中普通DOM元素的ref直接指向DOM节点,不需要额外加$el;二是用this.$parent强依赖组件层级,耦合性极高,结构变动就会失效。以下是三种可行的解耦方案:
方案1:自定义事件+父组件处理滚动(推荐)
子组件只负责触发滚动事件,父组件处理具体的滚动逻辑,完全解耦父子组件。
父组件(LandingPage.vue)
<script> import InPageAnchor from '@/Components/Navigation/Buttons/InPageAnchor.vue'; export default { components: { InPageAnchor, }, methods: { scrollToTarget() { this.$refs.scrollHere.scrollIntoView({ behavior: 'smooth' }); } } }; </script> <template> <InPageAnchor @scroll-trigger="scrollToTarget" text="滚动到目标"/> <div ref="scrollHere"> <!-- 目标区域内容 --> </div> </template>
子组件(InPageAnchor.vue)
<script> export default { props: { text: { type: String, required: true } }, methods: { scrollTo() { this.$emit('scroll-trigger'); } } } </script> <template> <button type="button" class="rounded-md my-1 px-2 w-1/6 bg-teal-600 hover:border-violet-700 hover:border-x-4 hover:bg-teal-700/75" @click="scrollTo()"> {{ text }} </button> </template>
方案2:通过props传递目标元素引用
把父组件的目标DOM元素引用直接传给子组件,子组件负责执行滚动。
父组件(LandingPage.vue)
<script> import InPageAnchor from '@/Components/Navigation/Buttons/InPageAnchor.vue'; export default { components: { InPageAnchor, }, computed: { scrollTarget() { return this.$refs.scrollHere; } } }; </script> <template> <InPageAnchor :scroll-target="scrollTarget" text="滚动到目标"/> <div ref="scrollHere"> <!-- 目标区域内容 --> </div> </template>
子组件(InPageAnchor.vue)
<script> export default { props: { text: { type: String, required: true }, scrollTarget: { type: Element, required: true } }, methods: { scrollTo() { if (this.scrollTarget) { this.scrollTarget.scrollIntoView({ behavior: 'smooth' }); } } } } </script> <template> <button type="button" class="rounded-md my-1 px-2 w-1/6 bg-teal-600 hover:border-violet-700 hover:border-x-4 hover:bg-teal-700/75" @click="scrollTo()"> {{ text }} </button> </template>
方案3:通过ID选择器(适合props传递ID的场景)
如果实际场景中props传递的是目标元素的ID字符串,直接用原生API获取元素执行滚动。
父组件(LandingPage.vue)
<script> import InPageAnchor from '@/Components/Navigation/Buttons/InPageAnchor.vue'; export default { components: { InPageAnchor, } }; </script> <template> <InPageAnchor :target-id="'scrollHere'" text="滚动到目标"/> <div id="scrollHere"> <!-- 目标区域内容 --> </div> </template>
子组件(InPageAnchor.vue)
<script> export default { props: { text: { type: String, required: true }, targetId: { type: String, required: true } }, methods: { scrollTo() { const targetEl = document.getElementById(this.targetId); if (targetEl) { targetEl.scrollIntoView({ behavior: 'smooth' }); } } } } </script> <template> <button type="button" class="rounded-md my-1 px-2 w-1/6 bg-teal-600 hover:border-violet-700 hover:border-x-4 hover:bg-teal-700/75" @click="scrollTo()"> {{ text }} </button> </template>
内容的提问来源于stack exchange,提问作者LNFullStack
相关产品推荐
相关产品推荐

