admin管理员组文章数量:1135914
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?
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?
19 Answers
Reset to default 49You can use
<component
:is="isDisabled ? 'span' : 'router-link'"
to="/link"
>
/link
</component>
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.
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"
>
Link
</router-link>
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
</a>
Where route can be exactly the same thing you pass to a to
prop on router-link
.
Just set to=""
then the link doesn't go anywhere.
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>
</a>
</router-link>
an then the function
checkClick(event: any, navigate: any, meta: { enabled: boolean }) {
if (meta.enabled) {
navigate(event);
return;
}
event.preventDefault();
},
You can try:
<router-link
:event="whateverActivatesThisLink ? 'click' : ''"
>
Go to page
</router-link>
Or write a cleaner code with computed:
<router-link
:event="handleWhatEverEvent"
>
Go to page
</router-link>
computed: {
handleWhatEverEvent() {
return this.whateverActivatesThisLink ? 'click' : '';
}
}
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>
You can set route guard per-route
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();
}
}
}
]
})
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
Idk why nobody tried replace to
prop like this:
<router-link :to="disabled ? '' : '/link'">
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
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' }"
>
Ended up using v-if/v-else. Note the disabled attribute on the v-else button:
<router-link v-if="shouldBeDisabled" :to="somewhere">
<p-button class="w-full main-button" icon="pi pi-link" label="Detail" />
</router-link>
<p-button v-else class="w-full main-button" disabled icon="pi pi-link" label="Detail" />
One way would be to just switch to a different component, like to a <a>
tag.
This brings the benefit, that it keeps the same styling.
And as the <a>
tag does not have a to
attribute it will not do anything.
<template>
<component
:is="disabled ? 'a' : 'router-link'"
:class="{ 'disabled': disabled }"
to="/link"
>
/link
</component>
</template>
<style>
a.disabled {
cursor: not-allowed;
opacity: 0.5;
&:hover {
text-decoration: none;
}
}
</style>
Or simply switch between two components via v-if
/ v-else
This has the benefit that it does not invalidate the HTML with custom attributes and it is explicit.
<template>
<router-link
v-if="!disabled"
to="/link"
>
<slot />
</router-link>
<a
v-else
:class="{ 'disabled': disabled }"
href="javascript:void(0)"
>
<slot />
</a>
</template>
Add Button tag and set onclick to router push:
<button @click="router.push('/')" disabled>
MyButton-Text
</button>
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
</div>
</div>
</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>
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.
use div element or span element instead of in combination with @click event
<div @click="handleRouteNavigation">
your content..
</div>
in script methods define
handleRouteNavigation(){
if(conditionSatisfied){
this.$router.push('/mylink')
}
}
本文标签: javascriptHow to disable a vuejs routerlinkStack Overflow
版权声明:本文标题:javascript - How to disable a vuejs router-link? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736948317a1957352.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论