2👍
Any time you need a value based on other values, you should look at using a computed. In this case, a computed that goes through the country data and picks out the selected city names and returns them as a list.
computed: {
selecteds() {
return this.countries
.map(c => c.selected)
.filter(s => s);
}
},
Check-and-uncheck functionality is supplied by v-model
on the radio inputs. If the value of what is bound to v-model
matches the value bound to value
, the button is checked; if not, not.
I used a settable computed to handle the case where you’re clicking an already-clicked button. If it is already selected, set the value to null to unselect it. Because I’m in a component, "set the value to null" is done by emitting an event that the parent uses to set the value.
computed: {
proxySelected: {
get() {
return this.data.selected;
},
set(newValue) {
this.$emit('update', this.data.name, this.data.selected === newValue ? null : newValue);
}
}
}
function countryData(name, cities) {
return {
name,
cities,
selected: null
};
}
new Vue({
el: '#app',
data: {
countries: [
countryData('England', ['Chelsea', 'MU', 'Arsenal']),
countryData('Spain', ['Madrid', 'Barcelona', 'Atletico']),
countryData('Italy', ['Juve', 'Milan', 'Inter'])
]
},
computed: {
selecteds() {
return this.countries
.map(c => c.selected)
.filter(s => s);
}
},
methods: {
update(countryName, newSelectedValue) {
this.countries.find(c => c.name === countryName).selected = newSelectedValue;
}
},
components: {
country: {
template: '#country-template',
props: ['data'],
data() {
return {
checked: []
};
},
computed: {
proxySelected: {
get() {
return this.data.selected;
},
set(newValue) {
this.$emit('update', this.data.name, this.data.selected === newValue ? null : newValue);
}
}
}
}
}
});
.list-unstyled {
list-style: none;
}
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.3.4/vue.min.js"></script>
<div id="app">
<country v-for="country in countries" :data="country" @update="update" :key="country.name"></country>
<div>{{selecteds.join(' - ')}}</div>
</div>
<template id="country-template">
<div class="col-md-4">
<ul class="list-unstyled">
<li><strong>{{data.name}}</strong></li>
<li v-for="city in data.cities">
<div class="checkbox">
<label>
<input type="radio" :name="data.name" class="radio" :value="city" v-model="proxySelected">
{{city}}
</label>
</div>
</li>
</ul>
</div>
</template>
0👍
Use v-model
to do this:
<input type="checkbox" v-model="italy">
And add vue will create an array for italy
which you can output in your vue template like {{ italy.join(' - ') }}