Vue.js 锚定到同一组件内的 div

Posted

技术标签:

【中文标题】Vue.js 锚定到同一组件内的 div【英文标题】:Vue.js anchor to div within the same component 【发布时间】:2017-07-27 12:33:44 【问题描述】:

我正在开发一个 Vue.js 应用程序,但无法将锚链接到组件中的某个 div。

我有以下锚:

<a href="#porto" class="porto-button">Porto, Portugal</a>

还有下面的div:

<div id="porto" class="fl-porto">

我在哈希模式下使用 vue-router。

问题是,每当我点击“porto-button”时,它都会将我重定向到“主页”页面('/')

我使用的是 Vue.js 1.X,我尝试使用历史模式(不带 hashbang 的 URL),但在刷新页面时它给了我一个 cannot GET '/page' 错误。

我做错了吗?我该怎么办?

【问题讨论】:

我想只是从你的 id 中去掉'#'?应该只是&lt;div id="porto" class="fl-porto"&gt;,不是吗? 我这样做了,但无济于事。这是我实际上尝试做的第一件事,但此时我已经做好了一切。 (不过我会编辑问题) 在您的 div 中放置一个命名的锚标记? &lt;a name="porto"&gt;,那么你的 a href="#porto"&gt; 应该可以工作了。 抱歉,我没有看到您处于哈希模式。如果你切换到历史模式,它应该可以工作,但你需要一个包罗万象的路线,每个:router.vuejs.org/en/essentials/… 我也尝试过使用历史模式。但是,每当我刷新我所在的页面时,链接就会以cannot GET /page 中断 【参考方案1】:

如果你在一个元素上设置了ref="something",你也可以使用这个带有@click的oneliner:

<a @click="$refs.something.$el.scrollIntoView()">
    Go to something
</a>

【讨论】:

【参考方案2】:

另一种解决方案是使用v-scroll-to 指令(webpage、github)。 我发现这个解决方案干净、简单、灵活且有效。使用方法:

    安装它:

    npm install --save vue-scrollto
    

    让 Vue “使用”它:

    var VueScrollTo = require('vue-scrollto');
    Vue.use(VueScrollTo)
    

    将它作为指令应用到你的 Vue 组件的模板中:

    <a href="#" v-scroll-to="'#element'">Scroll to #element</a>
    
    <div id="element">
      Hi. I'm #element.
    </div>
    

    或者在你的 Vue 组件的方法中以编程方式应用它:

    this.$scrollTo('#element', 500,  easing: 'ease-in-out' )
    

    或者以编程方式将其应用到您的 Vuex 操作中:

    import  scrollTo  from 'vue-scrollto'
    
    scrollTo('#element', 500,  easing: 'ease-in-out' )
    

另一种解决方案,如果你已经在使用 Vuetify,你可能更喜欢使用Vuetify's built-in programmatic scrolling method、$vuetify.goTo()

<v-btn @click="$vuetify.goTo('#element', duration: 500, easing: 'easeInOutCubic')">
  Scroll to #element
</v-btn>

<div id="element">
  Hi. I'm #element.
</div>

【讨论】:

感谢您提供此解决方案。 vue-scrollto 没有达到我的预期,但 vuetify 解决方案是神奇的【参考方案3】:

另一种方法是使用“scrollIntoView()”

所以,euvl 的代码仍然有效,只是你稍微改变一下方法:


    new Vue(
      el: '#app',
      methods: 
        goto(refName) 
            var element = this.$els[refName];
          element.scrollIntoView();
        
      
    )

如果你想变得花哨并使滚动流畅,你甚至可以添加以下内容:

element.scrollIntoView( behavior: 'smooth' );

请注意,对于旧版浏览器,这将需要一个 polyfill。

【讨论】:

在 VueJS 2 中,将 this.$els 替换为 this.$refs 以完成这项工作。【参考方案4】:

什么对我有用

<router-link to="#leaders">Leaders</router-link>

或动态

<router-link :to="`#$subMenuItem.linkTarget`" class="page-submenu-list__link">
                    subMenuItem.linkTitle
                </router-link>

在路由器中

routes:[],
scrollBehavior (to, from, savedPosition) 
    //https://router.vuejs.org/guide/advanced/scroll-behavior.html
    if (to.hash) 
            return  selector: to.hash 
         else if (savedPosition) 
            return savedPosition;
         else 
            return  x: 0, y: 0 
        
  

【讨论】:

这似乎只在第一次工作 - 如果我向上滚动并再次单击它不会将我向下滚动到正确的 div【参考方案5】:

由于您在哈希模式下使用路由器,因此您将无法轻松滚动,因为滚动到 /#something 实际上会将您重定向到“某事”页面。

您将不得不自己模拟滚动行为,尝试这样做:

//P.S. the code is written for Vue 2.
//You will have to adjust it to Vue 1.

//Your view:
<a class="porto-button" @click="scrollMeTo('porto')">Porto, Portugal</a>
...
<div ref="porto" class="fl-porto">
//Your code:
methods: 
  scrollMeTo(refName) 
    var element = this.$refs[refName];
    var top = element.offsetTop;

    window.scrollTo(0, top);
  

它是如何工作的:

    通过ref 属性将引用设置为要滚动到的元素; 编写一个函数,以编程方式将window.scrollY 设置为被引用元素的top。 工作完成:)

更新 1:

jsfiddle https://jsfiddle.net/5k4ptmqg/4/

更新 2:

似乎在 Vue 1 中 ref="name" 看起来像 el:name (docs),这是一个更新的示例:

https://jsfiddle.net/5y3pkoyz/2/

【讨论】:

我正在尝试重新创建它。它不工作。这与 Vue 1.X 兼容还是 Vue 2.X 独有?? 它不是 vue2 独有的,用你的尝试创建 jsfiddle @fmlopes 确实好像和Vue构建版本有关。因为它在使用 2.0.1 而不是 1.0.7 时有效。 jsfiddle.net/frankml/5y3pkoyz/1按下按钮返回“元素未定义” @fmlopes 为 vue 1(更新 2)添加了一个新示例。它对你有用吗? 是的,确实如此。这是正确的答案。我在 1.X 版本中进行了尝试,并且成功了。然后更新到 2.X 版本,它也能正常工作。

以上是关于Vue.js 锚定到同一组件内的 div的主要内容,如果未能解决你的问题,请参考以下文章

如何在不破坏响应性的情况下将 <div> 锚定到表格单元格的左下角?

如何在组件 vue.js 内的标签中发出事件

如何将组件内的 vue.js 方法转换为已创建的方法

将 ImageView 锚定到折叠工具栏

打造可复用Vuejs组件

如何将 UIAlertController 操作表锚定到特定单元格 UICollectionView?