Reputation: 174
I'm looking for a solution to dynamicly watch the values of an array with objects in vue:
new Vue({
el: "#app",
data: {
options: [
{"id": 1, "title": "One", "value": false},
{"id": 2, "title": "Two", "value": false },
{"id": 3, "title": "Three", "value": false}
]
},
I tried different solutions with watch
and methods
but none worked properly. How can I watch the objects in "options" for change of "value" and limit the maximum number of true objects to a number in this case 1 for example. If I set 2nd object true the first object need to set to false so that only the last changed object is true?
Upvotes: 0
Views: 621
Reputation: 8329
You just need to update the options
, like this (in case of limit: 1
):
new Vue({
el: "#app",
data: {
limit: 1, // this is not used in this snippet!
options: [{
"id": 1,
"title": "One",
"value": false
},
{
"id": 2,
"title": "Two",
"value": false
},
{
"id": 3,
"title": "Three",
"value": false
}
]
},
methods: {
setToTrue(id) {
// creating a copy of the options data object
let options = JSON.parse(JSON.stringify(this.options))
this.options = options.map(e => {
const value = e.id === id ? true : false
return { ...e, value }
})
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div v-for="option in options" :key="option.id">
ID: {{ option.id }}<br />
Title: {{ option.title }}<br />
Value: <span style="font-weight: 700; cursor: pointer;" @click="setToTrue(option.id)">{{ option.value }}</span><br />
<hr />
</div>
</div>
For a higher limit (like you'd allow 2 or more true
values), you'd need to come up with the ruleset about which ones to keep (beside the new one) - the strategy (ruleset) could be FIFO, LIFO, etc.
Upvotes: 1
Reputation: 1409
A computed property does the trick:
...
data: () => ({
options: [...], // your current options
trueValuesLimit: 2 // If you want to set the limit as data a property
})
computed: {
// If limitOn is true, then at least one value property is true
limitOn() {
const count = this.options.reduce((acc, option) => {
// If value is true, then add one to the accumulator
option.value ? acc++ : null
return acc
} , 0)
// Limit sets to 1, update as required
return count >= 1
// You can use a data property to validate the limit
// return count >= this.trueValuesLimit
}
}
...
Now you can use limitOn property to enable/disable the input to select/deselect options.
Upvotes: 1