Nuxt js id through url - vue.js

I want to get ID user, so I have a button DropDown=
<v-menu
transition="slide-y-transition"
bottom
offset-y
>
<template v-slot:activator="{ on, attrs }" >
<v-btn
color="primary"
dark
v-bind="attrs"
v-on="on"
>
List
</v-btn>
</template>
<v-list>
<v-list-item
v-for="(item, index) in items"
:key="index"
:to="item.url"
>
<v-list-item-title>{{item.title}}</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
and this data:
<script>
export default {
data: () => ({
items: [
{
title: 'List User',
url: '`/user/function/listUser/${route.params.id}`'
},
{
title: 'structure User',
url: '`/user/function/structUser/${route.params.id}`'
}
]
})
}
</script>
My intention is to send user ID. This way, I can get with route.params.id actually
url: '`/user/function/structUser/${route.params.id}`'
is not working, what I'm doing wrong?

This this one
`/user/function/structUser/${this.$route.params.id}`
Also, maybe try this one in a computed because it may not be computed.

Template strings use backticks only, but yours are using both single quotes and backticks.
The substitution value (route.params.id) refers to a route variable that appears to be undefined in your example. I believe you're trying to access this.$route, so the actual substitution should be this.$route.params.id
The items array should look like this:
export default {
data() {
return {
items: [
{
title: 'List User',
url: `/user/function/listUser/${this.$route.params.id}`
},
{
title: 'structure User',
url: `/user/function/structUser/${this.$route.params.id}`
}
]
}
}
}
demo

Related

Vue: I want to send data to another page

I have a page that lists employees.
<template>
<v-container>
<v-card
class="mb-6 pa-2 mx-auto rounded-lg"
max-width="1000"
color=""
v-for="user in users"
:key="user.id"
>
............
<v-btn
class="mb-3 mt-3"
v-on:click="sendConfirm(user.ID)"
to="/companyApplicants/menteeListPage"
color="green"
>
<v-icon>mdi-clipboard-account</v-icon>
</v-btn>
...........
</v-col>
</v-list-item>
</v-card>
</v-container>
</template>
<script>
export default {
data() {
return {
userDatas: [],
users: [
{
.....
},
],
}
},
mounted() {
this.getUserData()
},
methods: {
getUserData() {
return this.$axios.$get('/api/MyMentors').then((response) => {
this.users = response
console.log(response)
})
},
},
}
</script>
And when they press the button and go to the other page I want to send Id of the clicked mentor. I can get the Id but couldn't figure out how to send that Id to the other page
you can add the id to the route
<v-btn
class="mb-3 mt-3"
v-on:click="sendConfirm(user.ID)"
:to="`/companyApplicants/menteeListPage/${user.ID}`"
color="green"
>
<v-icon>mdi-clipboard-account</v-icon>
</v-btn>
just need to update your route to have the data available there
{
path: "/companyApplicants/menteeListPage/:userID",
name: "menteeListPage",
component: () => import(/* webpackChunkName: "views" */ "./views/MenteeListPage.vue"),
meta: {
requiresAuth: true,
title: "Menteen List Page {{userID}}",
},
},
your variable will then be accessible in the vue components through this.$route.params.userID
If you want to make it optional for the route use ? at the end :
path: "/companyApplicants/menteeListPage/:userID?",

Nuxtjs buttom DropDown

I'm building a buttom like Dropdown, this button is for print and dowloand document, so this is my code:
<template>
<v-menu
transition="slide-y-transition"
bottom
offset-y
>
<template v-slot:activator="{ on, attrs }" >
<v-btn
v-bind="attrs"
v-on="on"
>
Actions
</v-btn>
</template>
<v-list>
<v-list-item
v-for="(item, index) in actions"
:key="index"
#click="item.to"
>
<v-list-item-title class="white--text">
{{item.title}}
</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</template>
<script>
export default {
data()=>({
actions: [
{
title: 'Print',
to: 'print()'
},
{
title: 'Download',
to: 'download()'
}
]
}),
methods: {
print() {
//some code
},
download() {
//some code
}
}
</script>
so, when a try to click in button and select opction "Print" this error is showing me:
TypeError: handler.apply is not a function
why this error is showing me??
is possible call one function like string??
Give the method names without () then add a handler method for the click event as follows :
#click="handleMethod(item.to)"
and in script :
export default {
data()=>({
actions: [
{
title: 'Print',
to: 'print'
},
{
title: 'Download',
to: 'download'
}
]
}),
methods: {
print() {
//some code
},
download() {
//some code
},
handleMethod(method){
this[method]()
}
}
}
or just remove the () from the method names and try out #click="this[item.to]()"

Vue.js pass $store data from different modules

Hi I need to understand how to "pass" some $store values from settings module to header module, being the $store updated by settingsmodule
I have this app.vue module:
<template>
<v-app>
<router-view name="sidebar" />
<router-view name="header" :handleSettingsDrawer="handleSettingsDrawer" />
<v-main class="vue-content">
<v-fade-transition>
<router-view name="settings" />
</v-fade-transition>
</v-main>
<router-view name="footer" />
<app-settings-drawer
:handleDrawer="handleSettingsDrawer"
:drawer="settingsDrawer"
/>
</v-app>
</template>
in the <router-view name="header" /> there are a couple of v-menu to select currency and language:
<v-menu offset-y close-on-click>
<template v-slot:activator="{ on }">
<v-btn v-on="on" small fab class="mr-3">
<v-avatar size="30">
<v-img :src="currentLocaleImg"></v-img>
</v-avatar>
</v-btn>
</template>
<v-list dense class="langSel">
<v-list-item
v-for="(item, index) in langs"
:key="index"
#click="handleInternationalization(item.value,item.rtl)"
>
<v-list-item-avatar tile class="with-radius" size="25">
<v-img :src="item.img"></v-img>
</v-list-item-avatar>
<v-list-item-title>{{ item.text }}</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
in the script section I import the availableLanguages and availableCurrencies , I set them in data() where I also reference the user:
data() {
return {
items: [
{ icon: "settings", text: "Settings",link: "/settings" },
{ icon: "account_balance_wallet", text: "Account", link:"/tos" },
{ divider: true },
{ icon: "login", text: "Log In",link:"/auth/login" },
{ icon: "desktop_access_disabled", text: "Lock Screen",link:"/auth/lockscreen" },
{ icon: "exit_to_app", text: "Logout",link:"/auth/logout" },
],
langs: availableLocale,
currs: availableCurrency,
user: this.$store.state.userdata.user,
};
},
then, in computed: I have the 2 functions that should get the current value of curr and lang:
currentLocaleImg()
{
return this.langs.find((item) => item.value === this.$store.state.userdata.user.locale).img;
},
currentCurrencyImg() {
return this.currs.find((itemc) => itemc.value === this.$store.state.userdata.user.currency).img;
}
}
BUT the value of this.$store.state.userdata.user is updated firing the loadData() function mounted in the <router-view name="settings" /> module of App.vue
mounted(){
this.loadData();
},
methods:
{
async loadData(){
let jwt=sessionStorage.getItem('jwt');
try{
const res = await this.$http.post('/ajax/read_settings.php', {"jwt":jwt});
this.$store.dispatch("setUser", res.data.user);
this.$store.dispatch("setLocale", res.data.user.locale);
this.$store.dispatch("setCurrency", res.data.user.currency);
}
the problem is that header module does not have the value of this.$store.state.userdata.user.locale
(and .currency) and I get twice the following message:
vue.runtime.esm.js:1888 TypeError: Cannot read property 'img' of undefined
I do not know how to "pass" the data from one module to the other (or perhaps because the header is rendered before the settings module) and therefore the value of the currency and of the language are not known yet
What's wrong in this procedure?
How can I fix it?
There's a race condition in which you try to use data in the template that isn't loaded yet. But first, avoid setting store data directly into component data because the component data won't be updated when the store changes. Replace this:
user: this.$store.state.userdata.user
With a computed:
computed: {
user() {
return this.$store.state.userdata.user;
}
}
You can use v-if to conditionally render only when some data is available:
<v-img :src="currentLocaleImg" v-if="user"></v-img>
The currentLocaleImg computed will not even trigger until user has some data so you will avoid the error. Do the same for currentCurrencyImg if necessary.

vue js how to get notified when any property's value is being read?

i'm working in vue js and i'm trying to achieve something which has dependency. Actually inside data i have a property of boolean, what i want is that whenever this property's value is being used or this property is accessed i'm get notified so that i'm able to change other properties before this property's value getting used.
<template>
<!-- <v-card> -->
<v-navigation-drawer
v-model="drawer"
:mini-variant.sync="mini"
permanent
height="100%"
style="border:1px solid black;"
>
<v-list-item class="px-2">
<v-list-item-avatar>
<v-img src="https://randomuser.me/api/portraits/men/85.jpg"></v-img>
</v-list-item-avatar>
<v-list-item-title>John Leider</v-list-item-title>
<v-btn
icon
#click.stop="changeMiniValue()"
>
<v-icon>mdi-chevron-left</v-icon>
</v-btn>
</v-list-item>
<v-divider></v-divider>
<v-list dense>
<v-list-item
v-for="item in items"
:key="item.title"
link
>
<v-list-item-icon>
<v-icon>{{ item.icon }}</v-icon>
</v-list-item-icon>
<v-list-item-content>
<v-list-item-title>{{ item.title }}</v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list>
</v-navigation-drawer>
<!-- </v-card> -->
</template>
<script>
export default {
data () {
return {
drawer: true,
items: [
{ title: 'Home', icon: 'mdi-home-city' },
{ title: 'My Account', icon: 'mdi-account' },
{ title: 'Users', icon: 'mdi-account-group-outline' },
],
mini:this.getMini(),
}
},
methods:{
changeMiniValue(){
this.mini=!this.mini;
this.$store.dispatch('changeMini',!this.$store.state.mini);
},
getMini(){
this.$store.dispatch('changeColsToMin','9');
console.log('method executed');
return this.$store.state.mini;
}
},
created(){
this.$store.dispatch('changeColsToMin','11');
this.mini=this.$store.state.mini;
},
// computed:{
// getMiniValueCompute(){
// this.$store.dispatch('changeColsToMin','9');
// return this.$store.state.mini;
// }
// }
}
</script>
<style scoped>
</style>
This could be a possibile solution: create an "hidden" field and expose it through computed properties, with your custom logic.
<script>
export default {
data () {
return {
_mini: false
}
},
methods: {
// Your methods here...
},
computed: {
mini {
get: function () {
// TODO: notify your listeners, functions, etc.
return this._mini;
},
set: function (value) {
this._mini = mini;
}
}
}
}
</script>

Problem when creating a menu by iteration

I'm new to vue and vuetify. I need to create a submenu and for that I am using v-menu. Its construction is by iteration, where I need each sub menu to assign it a method. But it turns out that the way I'm doing it generates an error
[Vue warn]: Error in v-on handler: 'TypeError: handler.apply is not a function'
. What am I doing wrong?
https://codepen.io/maschfederico/pen/vMWBPV?editors=1011
<div id="app">
<v-app id="inspire">
<div class="text-xs-center">
<v-menu>
<template #activator="{ on: menu }">
<v-tooltip bottom>
<template #activator="{ on: tooltip }">
<v-btn
color="primary"
dark
v-on="{ ...tooltip, ...menu }"
>Dropdown w/ Tooltip</v-btn>
</template>
<span>Im A ToolTip</span>
</v-tooltip>
</template>
<v-list>
<v-list-tile
v-for="(item, index) in items"
:key="index"
#click="item.f"
>
<v-list-tile-title>{{ item.title }}</v-list-tile-title>
</v-list-tile>
</v-list>
</v-menu>
</div>
</v-app>
</div>
new Vue({
el: '#app',
data: () => ({
items: [
{ title: 'Click Me1',f:'login'},
{ title: 'Click Me2',f:'login' },
{ title: 'Click Me3',f:'login' },
{ title: 'Click Me4' ,f:'login' }
]
}),
methods: {
login(){console.log('login')}
}
})
Try to pass the method name to another one and handle it inside the last one like :
<v-list-tile
v-for="(item, index) in items"
:key="index"
#click="handle(item.f)"
>
inside the methods :
methods: {
handle(f){
this[f]();
},
login(){console.log('login')}
}
check this codepen
You are passing the method's name - a string - instead of a function. The click event listener generated by vue is trying to call a function using apply, this is why you are getting that error.
One solution would be to pass directly the function when the Vue instance is created (before that, the method might not be available, so passing it directly to the data { title: 'Click Me1', f: this.login } would not work).
For example, you could keep having method names in the data, and replace them with the actual methods at create:
new Vue({
el: '#app',
data: () => ({
items: [
{ title: 'Click Me1', f: 'login' }
]
}),
created () {
this.items.forEach(item => {
item.f = this[item.f]
})
},
methods: {
login (){
console.log('login')
}
}
})