Reputation: 364
Say I have this:
<v-btn v-for="action in actions" :key="action.icon" :disabled="action.disabled" icon
@click="action.click(item.id)">
<v-icon>{{ action.icon }}</v-icon>
</v-btn>
And actions is defined like this:
export default {
props: {
rowEditingDisabled: Boolean,
},
data() {
return {
actions: [
{icon: 'mdi-pencil', disabled: this.rowEditingDisabled, click: this.edit},
],
};
},
};
How can I make it so the disabled property is updated when the component prop 'rowEditingDisabled' gets updated?
This is a snippet demonstrating what I mean:
Vue.component('child', {
template: `
<div>
<v-btn :disabled="rowEditingDisabled">This works!</v-btn>
<v-btn v-for="action in actions" :key="action.icon" :disabled="action.disabled" icon
@click="action.click(item.id)">
<v-icon>{{ action.icon }}</v-icon>
</v-btn>
</div>`,
props: {
rowEditingDisabled: Boolean,
},
data() {
return {
actions: [
{icon: 'mdi-pencil', disabled: this.rowEditingDisabled, click: this.edit},
],
};
},
})
new Vue({
el: '#app',
vuetify: new Vuetify(),
data() {
return {
isDisabled: true
};
},
created() {
setInterval(() => {
this.isDisabled = !this.isDisabled;
}, 1000);
},
})
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/@mdi/[email protected]/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.css" rel="stylesheet">
<div id="app">
<v-app>
<v-main>
<v-container>
<child :row-editing-disabled="isDisabled"></child>
</v-container>
</v-main>
</v-app>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.js"></script>
It works when I just use the prop, but when I put it in an array it doesn't work anymore.
Upvotes: 2
Views: 593
Reputation: 4684
Sometimes props might be recieved with some delay. In such cases to preserve dynamicity you can make use of computed. Please check the modified lines below
Vue.component('child', {
template: `
<div>
<v-btn v-for="action in actions" :key="action.icon" :disabled="disableRow" @click="action.click(item.id)"> <!-- ***Changes here*** -->
<v-icon>{{ action.icon }}</v-icon>
</v-btn>
</div>`,
props: {
rowEditingDisabled: Boolean,
},
data() {
return {
actions: [
{icon: 'mdi-pencil', click: this.edit},// ***Changes here***
],
};
},
// ***Changes here below***
computed: {
disableRow() {
return this.rowEditingDisabled;
}
}
})
new Vue({
el: '#app',
vuetify: new Vuetify(),
data() {
return {
isDisabled: true
};
},
created() {
// ***Changes here***
// Commenting the below becoz it changes the flag to false
/* setInterval(() => {
this.isDisabled = !this.isDisabled;
}, 1000); */
},
})
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/@mdi/[email protected]/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.css" rel="stylesheet">
<div id="app">
<v-app>
<v-main>
<v-container>
<child :row-editing-disabled="isDisabled"></child>
</v-container>
</v-main>
</v-app>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.js"></script>
Upvotes: 0
Reputation: 27202
From the data()
method, you can reference the component's properties using this.
Can you try this :
data() {
return {
actions: [
{icon: 'mdi-pencil', disabled: this.rowEditingDisabled, click: this.edit},
],
};
}
Update : Created a working sample code snippet as per my understanding mentioned above and it is working fine. Can you please cross check the naming convention of the props
in template, It should be hyphen separated. i.e. :row-editing-disabled="..."
.
Working Demo :
Vue.component('post', {
template: '#post-template',
props: {
rowEditingDisabled: Boolean
},
data() {
return {
actions: [
{icon: 'mdi-pencil', disabled: this.rowEditingDisabled, click: this.edit}
]
};
}
});
var vm = new Vue({
el: '#app',
data: {
isRowEditingDisabled: true,
}
});
<script src="https://cdn.jsdelivr.net/vue/1.0.16/vue.js"></script>
<div id="app">
<post :row-editing-disabled="isRowEditingDisabled"></post>
</div>
<template id="post-template">
<button v-for="action in actions" :key="action.icon" :disabled="action.disabled">
Click Me!
</button>
</template>
Upvotes: 0
Reputation: 1575
Please ensure that you watch the changes in the prop, like this:
export default {
props: { rowEditingDisabled: Boolean, },
data() {
return {
actions: [{
icon: 'mdi-pencil',
disabled: false,
click: this.edit
}],
};
},
watch: {
rowEditingDisabled: function(newVal, oldVal) {
// watch it
console.log('Prop changed: ', newVal, ' | was: ', oldVal);
this.actions[0].disabled = newVal;
}
},
};
Upvotes: 1