Vue js dynamically render router link path - vue.js

I'm struggling to find a way to render the path of the router-link dynamically, for example with the test variable. I'm trying to bind :to but unsuccessfully. I don't know if I can use the ternary operator in the binding as shown below:
<template>
<div>
<router-link
:to="{ test ? '/success' : '/fail' }"
tag="button"
class="btn-next">
<span class="btn-text">BUTTON</span>
</router-link>
</div>
</template>
<script>
export default {
// ...
data: function() {
return {
test: false
};
}
}
</script>

Your solution is close (you don't need the curly brackets). It should look like this:
<router-link :to="test ? '/success' : '/fail'">
demo

Related

Nuxt : #click does not work with Nuxt-link

I am expecting to include on my web application an effect that underlines the section where we are in the list of sections.
I am working with Nuxt.
I don't know why the following code does not change the value of the boolean isActive.
<nuxt-link
:to="`${path}/${filterItem.filter}`"
:style='{"text-decoration": (isActive ? "underline" : "none")}'
#click="selectSeason(filterItem.filter) toggleUnderline()" >
methods: {
selectSeason(filter) {
this.$router.push(`${this.path}/${filter}`)
},
toggleUnderline() {
this.isActive = !this.isActive
}
},
You could probably achieve this with something like this
<template>
<nuxt-link to="/about" :custom="true">
<a #click="test">go to about page</a>
</nuxt-link>
</template>
<script>
export default {
methods: {
test() {
console.log('called test method')
},
},
}
</script>
As shown here: https://github.com/vuejs/router/issues/846#issuecomment-808150258
Even thought, this is probably not the best approach overall and seems quite too hacky for a simple use case.
Use a button tag if you want an action, otherwise put conditional logic on your route but don't mix a client side navigation and some kind of click events.
In Nuxt3 <NuxtLink> will get a class="router-link-active router-link-exact-active" if it's active, so you can use those to underline active link.
Same as router-link, you need to use v-on:click.native
<nuxt-link
:to="`${path}/${filterItem.filter}`"
:style='{"text-decoration": (isActive ? "underline" : "none")}'
#click.native="selectSeason(filterItem.filter) toggleUnderline()"
>
</nuxt-link>
How do we v-on:click nuxt-link?
Nuxt3:
<script lang="ts" setup>
const anyFunction = () => {
console.log('easy')
}
</script>
<template>
<NuxtLink
:to="'/'"
#click.prevent="anyFunction()"
>easy</NuxtLink>
</template>

how to redirect to specific component in vue js

I want to redirect inside a URL without page refresh, without using a router link as below :
<router-link to="/about us " active-class="active">foo</router-link>
I want to print routes like below:
<li class="nav-item phone">
<a class="nav-link" href="contact-us.html">
اتصل بنا
</a>
</li>
My route:
const routes = [
{ path: '/aboutus/', component: AboutUs }
]
Try this
this.$router.push('about')
You may need a workaround for this.
This solution won't change the url either :)
Set an html in the data
data: () => {
return {
html: null
}
}
Get the content of your html file using any request and assign to the html in data section. You can fetch this from any life cycle hook. Here I'm using beforeMount.
beforeMount() {
this.fetchAllEmployees();
axios.get('contact-us.html')
.then(response => {
this.html = response.data;
})
}
Now you can show the html content in your component like this
<template>
<div>
<div v-html="html"></div>
</div>
</template>
To show only when clicking the a tag, you can add another variable in the data which can be used to toggle the value.

Why won't vue.js update the DOM?

Working my way learning about Vue. I chose it as the better alternative after looking at React, Angular and Svelte.
I have a simple example that its not working probably because I'm not getting/understanding the reactive behaviour of Vue.
Plain simple App:
<template>
<div id="app">
<app-header></app-header>
<router-view />
<app-footer></app-footer>
</div>
</template>
<script>
import Header from './components/Header.vue'
import Home from './components/Home.vue'
import Footer from './components/Footer.vue'
export default {
components: {
name: 'App',
'app-header': Header,
'app-footer': Footer
}
}
</script>
Where Home.vue and Footer.vue have plain HTML content on the template.
On Header.vue I have:
<template>
<div>
<h1>The Header</h1>
<nav>
<ul>
<li>Curr Player: {{ ethaccount }}</li>
<li>Prop owner: {{ propOwner }}</li>
</ul>
</nav>
<hr />
</div>
</template>
<script>
export default {
data() {
return {
ethaccount: 'N/A',
propOwner: 'N/A'
}
},
methods: {
update() {
var ethaccount = '0xAAAAAA123456789123456789123456789'
console.log('ETH Account: ' + ethaccount)
var propOwner = '0xPPPPPPPPPPP987654321987654321'
console.log('Prop Account: ' + propOwner)
}
},
mounted() {
this.update()
}
}
</script>
But I'm unable to get the header updated and unable to find what I'm doing wrong. Help.
If you need to read a little bit more about the reactivity of the datas in vuejs check this link : https://v2.vuejs.org/v2/guide/reactivity.html
If you need to access/change your data try to do it like that :
this.$data.ethaccount = 'foo';
this.$data.propOwner = 'bar';
For me the problem is taht you re-declare your variable locally by doing :
var ethaccount = "0xAA...";
By doing such you never change the value of the data you're accessing through your template.
Hope it will solve your problem.

Cannot Render $children in Another Component

I would like to have a dynamic content so I tried something like below. When I log $children[0], I get a proper data but nothing is shown on the HTML. Is there way to render $children?
Main:
<template>
<foo>
<h1>Content should be rendered {{number}} time.</h1>
</foo>
</template>
<script>
components: { Foo },
data() {
return {
number: 1
}
}
...
</script>
Foo:
<template>
<div v-html="$children[0]"></div>
</template>
You need to use Slot. Simply replace <div v-html="$children[0]"></div> with <slot></slot>.

Disable nuxt link based on boolean

I can't seem to find a good way to disable a nuxt-link based on a data variable. Could anyone suggest something? I've tried looking at doucmentation but I can't come up with anything.
Say I have a boolean called disable I want to do something like this
<nuxt-link :disabled="disable"></nuxt-link>
I basically just don't want the link to be clickable if the boolean is set to false
<nuxt-link> is essentially <router-link> of Vue Router.
You can disable it using the event prop.
Assuming your one of your data or computed property is disabled boolean:
<nuxt-link :event="disabled ? '' : 'click'"></nuxt-link>
Working example:
const Foo = { template: '<div>foo</div>' }
const Bar = { template: '<div>bar</div>' }
const Baz = { template: '<div>baz</div>' }
const routes = [
{ path: '/foo', component: Foo },
{ path: '/bar', component: Bar },
{ path: '/baz', component: Baz }
]
const router = new VueRouter({
routes
})
const app = new Vue({
router,
data(){
return {
disabled: true
}
}
}).$mount('#app')
<script src="https://unpkg.com/vue#2.7.13/dist/vue.min.js"></script>
<script src="https://unpkg.com/vue-router#3.6.5/dist/vue-router.min.js"></script>
<div id="app">
<h1>Hello App!</h1>
<div>
<!-- Assume they are <nuxt-link> because they are the same -->
<router-link
:event="disabled ? '' : 'click'"
to="/foo"
>
Go to Foo ({{ disabled ? 'Disabled' : 'Enabled' }})
</router-link>
<router-link to="/bar">Go to Bar</router-link>
<router-link to="/baz">Go to Baz</router-link>
</div><br />
<button #click="disabled = !disabled">Toggle Foo availability</button><br /><br />
<router-view></router-view>
</div>
I found that the most simple way was to just create a class for the disabled links. I'm still not sure if this is the best way to do it but it works for me and does exactly what I want.
<nuxt-link to="/search" :class="{ disabled: disabled }"> Search </nuxt-link>
my css
.disabled {
color: lightgrey
pointer-events: none
}
Another way to do this, which I'd like the most. Is to change the tag to the button and use the native :disabled state.
<nuxt-link tag="button" :disabled="disabled" to="/some/location">Some location</nuxt-link>
Then just turn the button into the link with the help of styles.
In Nuxt3 this works for me: :to="canNavigate ? link : null"
In Vue Router 4, router-link do not support tag and event props anymore. Here you can have more information.
I'll copy the example from the link above here:
replace
<router-link to="/about" tag="span" event="dblclick">About Us</router-link>
with
<router-link to="/about" custom v-slot="{ navigate }">
<span #click="navigate" #keypress.enter="navigate" role="link">About Us</span>
</router-link>
And I'll give a real example of usage. This piece of code I'm using in a real project, using nuxt and tailwind.
<nuxt-link
v-slot="{ navigate }"
class="flex-grow font-ember"
:to="`lesson/${l.lesson_id}`"
append
custom
>
<button
class="flex items-center"
:class="{
'text-gray-400 cursor-not-allowed': !l.released,
'text-gray-900': l.released,
}"
:disabled="!l.released"
#click="navigate"
>
...
</button>
</nuxt-link>
Just add the event prop if you simply want to disable a nuxt-link
<nuxt-link event="">Go to Foo</nuxt-link>
For this case anyway you can click on it. It displaying disabled but still clickable.
You need to use attribute tag in you nuxt-link
Example here <nuxt-link tag="button" :disabled="disable"></nuxt-link>
None of these seemed to work for me, so I set the :to on the nuxt-link to a computed method. The to attribute on nuxt link will redirect nowhere when empty. For example:
<script>
export default{
computed: {
redirectRequest(){
return this.isMobile ? "" : "/Worklog";
}
}
}
</script>
<template>
<NuxtLink :to="redirectRequest"></NuxtLink>
</template>