相关文章推荐
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I have a single-page app that i've created using vue, and the nav links are all done using router-link tags. There are a couple of items in the nav that my boss wants to have in the nav but disabled so that people can get a glimpse of some features that will be coming soon. However I can't figure out how to completely disable a router-link!

preventDefault does nothing, @click.native.prevent="stopClick()" does nothing (i tried sending it to a function to see if that would prevent the click but it just calls the function and routes anyway despite the prevent), adding a disabled class and setting a css rule of pointer-events: none; does nothing. I'm not sure what else to try, is the only way around this to make the disabled links normal text and not router-links?

@Luciano, this is not working for me in Vue 3 and vue-router 4.0.13. But what actually work is ` :to="isDisabled ? '' : '/link'" ` Disorder May 19, 2022 at 13:45 @Disorder I'm just testing it (Vue 2 vue-router 3.x.x) and your solution works, but unfortunately, it shows a link that does nothing, so in my case using :is looks prettier. Anyways I will take your suggestion for future Vue 3 projects. Thanks Luciano May 19, 2022 at 13:51 Well no... :is works with <component> ... so... change <router-link to <component and it works like a charm. Joeri May 31, 2022 at 19:06

There is nothing built in, and probably won't ever be . That said, what worked great for me is to use CSS.

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

The opacity makes it look disabled, and the pointer-events: none; makes it so you don't need to also handle :hover styles, or set the cursor style.

This answer is cleanest, and everyone needs to see that Github post. Later I'd scrutinize accessibility aspects, ie is the disabled link still tabbable or do screen readers ignore it? – Kalnode May 27 at 13:14

There is still no native solution today. But there is an open PR for this on the vue-router repo : https://github.com/vuejs/vue-router/pull/2098.

A workaround is to use :

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

I don't think there's a suitable solution for this problem since router links do not have the disabled attribute, but one trick would be using tag="button" in order to add the required attribute as follows:

<router-link 
     to="/link"
     tag="button"
     :disabled="true"
</router-link>
                That's because router-link renders as html anchor tag, and <a> also doesn't support disabled attr. Adding tag="button" will make routerlink renders as button instead, and therefore the button will be naturally usable with :disabled.
– SC Kim
                Apr 23, 2020 at 23:23

Method 1: Prevent the click event

The trick is to handle an event on a capture phase and stop it from propagating up top.

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

Or imperatively:

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

This might be very useful if you want to get the resolved path from Vue Router to force a page load without SPA navigation.

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

Method 2: Change default event to an empty string

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

Method 3: Use an <a> tag

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

Where route can be exactly the same thing you pass to a to prop on router-link.

Using event.preventDefault() instead of event.stopPropagation() worked for me to disable the router-link – Rohan Hadnum Dec 3, 2021 at 10:19 I wouldn't recommend it since event will no longer propagate and for example would not trigger global event listeners. – CyberAP Dec 4, 2021 at 11:24 This still renders a functional link that points to the current page, which is not desired. – Kalnode May 27 at 13:11

As I had to use <router-link> with custom attribute (and added custom meta to routes), I was able to solve it like this:

<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>
</router-link>

an then the function

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

Idk why nobody tried replace to prop like this:

<router-link :to="disabled ? '' : '/link'">
</router-link>

But it's 100% work with any version of Vue and vue-router. Another answers are not working for me with Vue 3 and vue-router 4

This still renders a functional link that points to the current page, which is not desired. – Kalnode May 27 at 13:08

To prevent a click you can directly access to event property of the router-link element like this (and you can use native click to do something else) :

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

Or you can set globally

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

For more info: https://router.vuejs.org/guide/advanced/navigation-guards.html#global-before-guards

If using PrimeVue...

You can use class="p-disabled" to disable a link.

Change it dynamically as follows:

:class="isDisable ?  'p-disabled' : ''"

If you use it for a <div>, All the things inside the <div></div> will be disabled.

You could try using a dynamic component to change the element, it seems to work well now that tag prop has been removed.

<component 
    :is="disabled ? 'span' : 'router-link'"
    :to="{ path: '/path' }"

Update for Router v4:

Using a boolean variable status to determine if the link is active or not and passing the link (ctalink) as a variable as well.

Stumbled in here coming from nuxt-link implementation that broke with the update, so from experience this works likewise.

    <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 
    </router-link>

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

NuxtLink (Vue Router v4)

To me what worked like a charm was the code below. This is a real code that I'm using in my application with nuxt and tailwind.

              <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>
                Using <a> (NuxtLink is <a>) with <button> inside is bad. <a> content is 'Transparent, but there must be no interactive content descendant, a element descendant, or descendant with the tabindex attribute specified.' html.spec.whatwg.org/multipage/…
– Eduardo
                Jan 6 at 7:37

use div element or span element instead of in combination with @click event

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

in script methods define

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

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.

 
推荐文章