Nuxtjs buttom DropDown - vue.js

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]()"

Related

Nuxt js id through url

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

I want to add editing functions using Nuxt.js

What I want to come true
I am creating TodoLists.
I tried to implement the following editing features, but it didn't work and I'm having trouble.
Click the edit button to display the edit text in the input field
If you click the save button after entering the changes in the input field, the changes will be reflected in the first position.
Code
<v-row v-for="(todo,index) in todos" :key="index">
<v-text-field
filled
readonly
:value="todo.text"
class="ma-3"
auto-grow
/>
<v-menu
top
rounded
>
<template #activator="{ on, attrs }">
<v-btn
v-bind="attrs"
icon
class="mt-6"
v-on="on"
>
<v-icon>
mdi-dots-vertical
</v-icon>
</v-btn>
</template>
<v-list>
<v-list-item
link
>
<v-list-item-title #click="toEdit(todos)">
<v-icon>mdi-pencil</v-icon>
Edit
</v-list-item-title>
</v-list-item>
</v-list>
<v-list>
<v-list-item
link
>
<v-list-item-title #click="removeTodo(todo)">
<v-icon>mdi-delete</v-icon>
Delete
</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</v-row>
<v-text-field
v-model="itemText"
filled
color="pink lighten-3"
auto-grow
#keyup.enter="addTodo"
/>
<v-btn
:disabled="disabled"
#click="addTodo"
>
Save
</v-btn>
data () {
return {
editIndex: false,
hidden: false,
itemText: '',
items: [
{ title: 'Edit', icon: 'mdi-pencil' },
{ title: 'Delete', icon: 'mdi-delete' }
]
}
},
computed: {
todos () {
return this.$store.state.todos.list
},
disabled () {
return this.itemText.length === 0
}
},
methods: {
addTodo (todo) {
if (this.editIndex === false) {
this.$store.commit('todos/add', this.itemText)
this.itemText = ''
} else {
this.$store.commit('todos/edit', this.itemText, todo)
this.itemText = ''
}
},
toEdit (todo) {
this.editIndex = true
this.itemText = this.todos
},
removeTodo (todo) {
this.$store.commit('todos/remove', todo)
}
}
}
</script>
export const state = () => ({
list: []
})
export const mutations = {
add (state, text) {
state.list.push({
text
})
},
remove (state, todo) {
state.list.splice(state.list.indexOf(todo), 1)
},
edit (state, text, todo) {
state.list.splice(state.list.indexOf(todo), 1, text)
}
}
Error
Click the edit button and it will look like this
What I tried myself
//methods
toEdit (todo) {
this.editIndex = true
this.itemText = this.todos.text //add
},
// Cannot read property 'length' of undefined
For some reason I get an error that I couldn't see before
The properties/data types in your code are a bit mixed up.
Here you're accessing state.todos.list...
todos () {
return this.$store.state.todos.list
},
...but in your store the const state doesn't include todos:
export const state = () => ({
list: []
})
Furthermore, you're writing to itemText the content of todos, which should be a string but actually is an object - which leads to the output of [object Object].
toEdit (todo) {
this.editIndex = true
this.itemText = this.todos
},
Also, please check out kissu's comment about the mutations.

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>

Vue-i18n: how to save the selected locale

There is a site on vue to which i18n library is connected.There is a button for switching languages.
<div class="locale-changer">
<v-menu v-model="changeLocaleState" offset-y>
<template v-slot:activator="{ on }">
<v-btn
color="primary"
dark
v-on="on"
/>
</template>
<v-list>
<v-list-tile
v-for="(lang, i) in langs"
:key="`lang.lacale${i}`"
:value="lang.locale"
#click="$i18n.locale = lang.locale"
>
<v-list-tile-title><img :src="lang.img">{{ lang.locale }}</v-list-tile-title>
</v-list-tile>
</v-list>
</v-menu>
export default {
name: 'VeLanguageSwitcher',
data () {
return { langs: [
{
name: 'en',
locale: 'en-US',
img: '/assets/img/flag/GB.png'
},
{
name: 'ru',
locale: 'ru-RU',
img: '/assets/img/flag/RU.png'
}
] }
},
computed: {
changeLocaleState: {
get () {
return this.$store.state.ui.changeLocale
},
set (val) {
this.$store.commit('ui/setChangeLocale', val)
}
}
}
}
</script>
The selected locale is not saved.Theoretically, I understand that when choosing a language you make SET in vuex, and GET displays a picture of the current locale inside the button.But I don't know how to do it

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')
}
}
})