how binding value on params router-link in vue 3? - vue.js

Hi sorry for my noob question. I need binding params value of router-link. i search a lot and i think it's correct my code but don't work.
<router-link :to="{name: 'registro-new', params: {id: cliente.id}}">registro </router-link>
this is the error in console.log
[Vue warn]: Unhandled error during execution of setup function
at <RouterLink to=
Object { name: "registro-new", params: {…} }
​
name: "registro-new"
​
params: Object { id: undefined }
​
<prototype>: Object { … }
>
at <Cliente onVnodeUnmounted=fn<onVnodeUnmounted> ref=Ref< undefined > >
at <RouterView>
at <Dashboard onVnodeUnmounted=fn<onVnodeUnmounted> ref=Ref< undefined > >
at <RouterView key="/cliente/1" >
at <App> runtime-core.esm-bundler.js:6873:16
i think that cliente.id it's null but if I write {{cliente.id}} inside to div i get the value.
if i put manually a number like this my route work
<router-link :to="{name: 'registro-new', params: {id:1}}">registro </router-link>
so i don't kwnow really where is my bad. Can someone help me please?

It looks like at the rendering the client id had not been available yet, so add a condition to render the router link when the id is ready v-if="cliente.id" :
<router-link v-if="cliente.id" :to="{name: 'registro-new', params: {id: cliente.id}}">
registro
</router-link>

Related

Component works only once using router-link - Laravel vue

I am working on a project that uses Laravel Vue SPA, and I got a problem accessing the data of the single product, it's only working when I click once, but when I select again with other product, I can't get the product data, but the URL is correct it's changes the ID but can't access the data.
It is working when I click another link like Services then select product, it can display the product data.
Here is my HTML
<ul >
<li v-for="product in products">
<router-link :to="{ name: 'edit-product', params: { id: product.id } }">
{{ product.title }}
</router-link>
</li>
</ul>
My Vue Routes
const EditProduct = require('./components/EditProduct').default;
{
path: '/edit/product/:id',
component: EditProduct,
name: 'edit-product'
}
my EditProduct component
<template>
<div>
<h1>this.$route.params.id</h1>
</div>
</template>
Cheers
Look at this answer. You have to watch the productId and execute your logic again.
Possible solution
try to define a computed property inside your EditProduct component for get product id
computed: {
productId(){
return this.$route.params.id
}
}
and use productId inside your <h1> tag
<template>
<div>
<h1>{{ productId }}</h1>
</div>
</template>
update
solution :
add this watcher to your EditProduct component for reacting with params change
watch: {
$route(to) {
console.log(to.params.id)
// you can call your method here and pass product id to them for example: this.getProductDetails(to.params.id)
},
beforeRouteEnter (to, from, next) {
next(vm => {
//also call your method here => vm.getProductDetails(to.params.id)
});
},
you can read more about params changes here: Reacting to Params Changes

Vuesax router link

How to create a vuesax router link? Any answer would be appreciated.
What I tried: Adding to="/path" to vuesax-navbar__item, but it does not trigger class change.
From this documentation, it describes the router support for the button.
You can send a string or object to directive to. This directive wrap a $router.push() vue method, you can use all programmatic navigation on vue router.
String literal Object Path Named Router With Query
<vs-button color="primary" type="filled" to="/components/list.html">String literal</vs-button>
<vs-button color="warning" type="filled" :to="{ path: '/components/list.html' }">Object Path</vs-button>
<vs-button color="success" type="filled" :to="{ name: 'user', params: { userId: 123 } }">Named Router</vs-button>
<vs-button color="dark" type="filled" :to="{ path: 'register', query: { plan: 'private' } }">With Query</vs-button>

Vue.js Router Link Not Updating

I am encountering an issue that I have reproduced with the following simplified code:
App.vue
<router-link to="/">Home</router-link> |
<router-link :to="{name: 'View1', params: {myprop: 'hello 1'}}"> |
View 1 - Param 1
</router-link>
<router-link :to="{name: 'View1', params: {myprop: 'hello 2'}}"> |
View 1 - Param 2
</router-link>
<router-view :key='$route.path' />
View1.vue
<template>
<div>
My prop = {{myprop}}
</div>
</template>
If I start on the Home link and click “View 1 - Param 1”, I am taken to View1 and see “My prop = hello 1”. This is as expected.
If I then go back to the home page and click “View 1 - Param 2”, I am taken to View1 and see “My prop = hello 2”. This is also as expected.
Here’s where the trouble starts. If I click “View 1 - Param 1” while I am already on “View 1 - Param 2”, then I am taken to View1, but the message does not update. So, I see “My prop = hello 2” again instead of seeing “My prop = hello 1”.
My understanding is that Vue is not rerendering View1 as an optimization since the “from” view and “to” view are the same, but clearly that is not the behavior I would like.
I did some research on this and came across a video that suggested using “key=’$route.path’” in the view tag would address this. However, this is not solving the issue for me.
What is the correct way to address this issue, please?
Your solution won't work because the $route.path string does not contain the query parameters. So, when you change go from "View 1 - Param 2" to "View 1 - Param 1", the $route.path remains same, and does not update the view.
Use $route.fullPath this will update the view as it contains the The full resolved URL including query and hash.
<router-link to="/">Home</router-link> |
<router-link :to="{name: 'View1', params: {myprop: 'hello 1'}}"> |
View 1 - Param 1
</router-link>
<router-link :to="{name: 'View1', params: {myprop: 'hello 2'}}"> |
View 1 - Param 2
</router-link>
<router-view :key='$route.fullPath' />
Alternatively, you can add a watcher to the route query parameter inside your "View1.vue". This way you wont have to add key to your router-view
View1.vue
<template>
<div>
My prop = {{pageProp}}
</div>
</template>
<script>
export default {
data() {
return {
pageProp: ""
}
},
watch: {
"$route.query": {
immediate: true,
handler(n) {
this.pageProp = n.myProp
}
}
}
</script>
You can use
<router-view :key ='$route.params'/>
instead of using
<router-view :key ='$route.path'/>
In my case it worked.

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>

[Vue warn]: The client-side rendered virtual DOM tree is not matching server-rendered content

[Vue warn]: The client-side rendered virtual DOM tree is not matching server-rendered content. This is likely caused by incorrect HTML markup, for example nesting block-level elements inside , or missing . Bailing hydration and performing full client-side render.
<template lang="pug">
div
header
h1 project news line
nav
nuxt-link(to='/') home
nuxt-link(to='/about') about
nuxt-link(to='/contacts') call me
.wrapper
form(#submit="postMesseage")
section.container
md-input-container
label With label
md-input(placeholder='Head', v-model="name", type='text', )
button(type="submit") add news
.quill-editor(:content='content', #change='onEditorChange($event)', #blur='onEditorBlur($event)', #focus='onEditorFocus($event)', #ready='onEditorReady($event)', v-quill:myquilleditor='editorOption', v-model="newMessage")
section#message(v-for='(message, index) in messages')
button( #click="deleteRow(index)" v-bind:id="message._id") удалить
nuxt-link(:to="{ path: '/edite/'+message._id, params: { id: message._id } }")
button Редактировать
h2
nuxt-link(:to="{ path: '/news/'+message._id, params: { id: message._id } }" ) {{ message.name }}
div(v-html="message.content") {{ message.content }}
</template>
how fix it ? not understand :( help please