如何禁用 vuejs 路由器链接?

Posted

技术标签:

【中文标题】如何禁用 vuejs 路由器链接?【英文标题】:How to disable a vuejs router-link? 【发布时间】:2020-08-07 07:46:24 【问题描述】:

我有一个使用 vue 创建的单页应用程序,导航链接全部使用 router-link 标签完成。导航中有几项我的老板想在导航中添加但已禁用,以便人们可以一睹即将推出的一些功能。但是我不知道如何完全禁用路由器链接!

preventDefault 什么都不做,@click.native.prevent="stopClick()" 什么都不做(我尝试将它发送到一个函数以查看是否会阻止点击,但它只是调用函数和路由,尽管阻止),添加一个 disabled 类并设置 pointer-events: none; 的 css 规则什么都不做。我不确定还有什么可以尝试的,这是使禁用的链接成为正常文本而不是路由器链接的唯一方法吗?

【问题讨论】:

【参考方案1】:

今天仍然没有原生解决方案。但是在 vue-router repo 上有一个公开的 PR:https://github.com/vuejs/vue-router/pull/2098。

一种解决方法是使用:

<router-link 
  :disabled="!whateverActivatesThisLink" 
  :event="whateverActivatesThisLink ? 'click' : ''"
  to="/link"
>
  /link
</router-link>

【讨论】:

在 Vue Router v4 中已弃用 next.router.vuejs.org/guide/migration/…【参考方案2】:

你可以使用

<router-link 
  :is="isDisabled ? 'span' : 'router-link'"
  to="/link"
>
  /link
</router-link>

【讨论】:

【参考方案3】:

我认为这个问题没有合适的解决方案,因为路由器链接没有disabled 属性,但一个技巧是使用tag="button" 来添加所需的属性,如下所示:

<router-link 
     to="/link"
     tag="button"
     :disabled="true"
>
  Link
</router-link>

【讨论】:

那是因为router-link呈现为html锚标签,而&lt;a&gt;也不支持禁用属性。添加tag="button" 将使routerlink 呈现为按钮,因此该按钮自然可以与:disabled 一起使用。【参考方案4】:

没有内置任何东西,probably won't ever be。也就是说,对我来说最有用的是使用 CSS。

<router-link to="/my-route" :class=" disabled: someBoolean " />
.disabled 
    opacity: 0.5;
    pointer-events: none;

不透明度使它看起来被禁用,pointer-events: none; 使它看起来如此你不需要处理:hover 样式,或设置cursor 样式。

【讨论】:

【参考方案5】:

方法一:阻止点击事件

诀窍是在捕获阶段处理事件并阻止它向上传播。

<router-link 
  to="/path"
  @click.native.capture.stop
>
  Go to page
</router-link>

或者强制:

<router-link 
  to="/path"
  @click.native.capture="handleClick"
>
  Go to page
</router-link>
function handleClick(event) 
  if (passesSomeCheck) event.stopPropagation();

如果您想从 Vue Router 获取解析的路径以在没有 SPA 导航的情况下强制页面加载,这可能非常有用。

function handleClick(event) 
  if (loadWithoutSpa) 
    event.stopPropagation();
    window.location.href = event.currentTarget.href;
  ;

方法二:将默认事件改为空字符串

<router-link 
  to="/path"
  event
>
  Go to page
</router-link>

方法3:使用&lt;a&gt;标签

<a :href="$router.resolve(route).href">
  Go to page
</a>

路由可以与您传递给router-link 上的to 道具的东西完全相同。

【讨论】:

使用 event.preventDefault() 而不是 event.stopPropagation() 为我禁用了路由器链接 我不会推荐它,因为事件将不再传播,例如不会触发全局事件监听器。【参考方案6】:

只需设置to="" 然后链接就不会去任何地方。

【讨论】:

【参考方案7】:

您可以为每个路由设置路由保护

const router = new VueRouter(
  routes: [
    
      path: '/foo',
      component: Foo,
      beforeEnter: (to, from, next) => 
        //here you can set if condition 
        if (conditionTrue) 
          //redirect to other route
          next(path: '/bar');
         else 
          next();
        
                
    
  ]
)

或者你可以全局设置

routes: [
  path: '/foo', component: Foo, meta:conditionalRoute: true
]; 

router.beforeEach((to, from, next) =>  
    if (to.matched.some(record => record.meta.conditionalRoute))  
        // this route requires condition/permission to be accessed
        if (!checkCondition )  
            //check condition is false
            next( path: '/');
         else  
            //check condition is true
            next();
         
     else  
        next(); // Don't forget next
     
)

更多信息: https://router.vuejs.org/guide/advanced/navigation-guards.html#global-before-guards

【讨论】:

【参考方案8】:

你可以试试:

  <router-link
   :event="whateverActivatesThisLink ? 'click' : ''"
  >
  Go to page
  </router-link>

或者使用计算编写更简洁的代码:

  <router-link
  :event="handleWhatEverEvent"
  >
  Go to page
  </router-link>

computed: 
  handleWhatEverEvent() 
    return this.whateverActivatesThisLink ? 'click' : '';
  

【讨论】:

【参考方案9】:

为了防止点击,您可以像这样直接访问 router-link 元素的事件属性(您可以使用原生点击来做其他事情):

<router-link 
:event="clickable ? 'click' : ''" 
@click.native="!clickable ? doOtherThing : ''" > Link </router-link>

【讨论】:

【参考方案10】:

路由器 v4 更新:

使用boolean 变量status 来确定链接是否处于活动状态,并将链接 (ctalink) 作为变量传递。

偶然发现这里来自 nuxt-link 实现与更新中断,因此根据经验,这同样适用。

    <router-link
      v-slot=" navigate "
      :to="ctalink"
      custom
    >
      <div @click="status ? navigate(ctalink) : null">
        <div :class="status ? 'text-green' : 'text-gray'"> 
          Click me when active 
        </div>
      </div>
    </router-link>

来源:https://next.router.vuejs.org/api/#router-link-s-v-slot

【讨论】:

【参考方案11】:

NuxtLink(Vue 路由器 v4)

对我来说,下面的代码很有吸引力。这是我在应用程序中使用nuxttailwind 的真实代码。

              <nuxt-link
                v-slot=" navigate "
                :to="`lesson/$lesson.lesson_id`"
                append
                custom
              >
                <button
                  class="focus:outline-none"
                  :class="
                    'text-gray-500 cursor-default': !lesson.released,
                  "
                  :disabled="!lesson.released"
                  @click="navigate"
                >
                   lesson.title 
                </button>
              </nuxt-link>

【讨论】:

【参考方案12】:

使用 div 元素或 span 元素代替 结合@click事件

<div @click="handleRouteNavigation">
your content..
</div>

在脚本方法中定义

handleRouteNavigation()

  if(conditionSatisfied)
      this.$router.push('/mylink')
   


【讨论】:

【参考方案13】:

由于我必须使用 &lt;router-link&gt; 和自定义属性(并向路由添加自定义元数据),我能够像这样解决它:

<router-link :to="route.path"
                  custom
                  v-slot="href, route, navigate, isActive, isExactActive">
                <a v-bind="$attrs"
                :href="href"
                @click="checkClick($event, navigate, route.meta)">
                ...
                <slot></slot>
            </a>
</router-link>

然后是函数

checkClick(event: any, navigate: any, meta:  enabled: boolean ) 
            if (meta.enabled) 
                navigate(event);
                return;
            
            event.preventDefault();
        ,

【讨论】:

以上是关于如何禁用 vuejs 路由器链接?的主要内容,如果未能解决你的问题,请参考以下文章

VueJs 路由器链接在实时服务器上不起作用

Vue JS:如何在路由器链接中设置活动 <a> 标记的样式?

VueJs:使用 vue-router 的两个独立且独立的路由/视图

VueJS Router-link 未链接到视图

如何使用 vuejs 3 将路由器添加到 @vue/cli 应用程序?

VueJs 路由视图转换