I try to when I choose the first select and second select will according to the first option and put data into second select
It can put the data into first select but the second select still can't run
I think maybe my emit does't work but I still can't solve it
What the problem
This my App.vue
<template>
<test
:cities="cities"
:areas="areas"
@input="cityidx"
></test>
</template>
<script>
import test from '@/components/SelectBoxTest.vue';
import datalist from '@/assets/data.json';
export default {
name:'App',
components: {
test,
Map,
},
data(){
return{
cityidx : 0,
}
},
computed: {
cities(){
return datalist
},
areas(){
return datalist[this.cityidx].AreaList
}
}
}
</script>
And this is my SelectBoxTest.vue
<template>
<!--CitySelect-->
<div>
<select id="countryselect" class="text-center" v-model="cityselect">
<option
v-for="(city , idx) of cities"
:key="city.text"
:value="idx">{{city.CityEngName}}</option>
</select>
</div>
<!--AreaSelect-->
<div>
<select id="areaselect" class="text-center" v-model="areaselect">
<option
v-for="area of areas"
:key="area.text"
>{{area.AreaEngName}}</option>
</select>
</div>
</template>
<script>
export default {
name:'test',
props:{
'cities': {
type: Array
},
'areas': {
type: Array
},
'cityidx': {
type: Number
},
},
data(){
return{
cityselect: 0,
areaselect: 0,
}
},
computed: {
update: {
get(){
return this.cityselect
},
set(value){
this.$emit('input',value)
}
},
},
};
</script>
The part of json
[
{
"CityEngName":"Taipei City",
"AreaList":[
{
"ZipCode":"100",
"AreaEngName":"Zhongzheng Dist."
}
]
},
{
"CityEngName":"Keelung City",
"AreaList":[
{
"ZipCode":"200",
"AreaEngName":"Ren’ai Dist."
}
]
}
]
After I try the new code , it can work by I want
But I meet an another problem is I need to choose the same option twice the select will change
What the bug of it
Thanks a lot
This Code of New App.vue
<template>
<test
:cities="cities"
:areas="areas"
v-model:current-city = "cityidx"
v-model:current-area = "areaidx"
></test>
</template>
<script>
import test from '@/components/SelectBoxTest.vue';
export default {
name:'App',
components: {
test,
},
data(){
return{
cityidx: 0,
areaidx: 0
}
},
computed: {
cities(){
return datalist
},
areas(){
return datalist[this.cityidx].AreaList
}
},
}
</script>
And SelectBoxTest.vue
<template>
<!--CitySelect-->
<div>
<select v-model="cityselect">
<option
v-for="(city , idx) of cities"
:key="idx"
:value="idx">{{city.CityEngName}}</option>
</select>
</div>
<!--AreaSelect-->
<div>
<select v-model="areaselect">
<option
v-for="(area , idx) of areas"
:key="idx"
:value="idx">{{area.AreaEngName}}</option>
</select>
</div>
</template>
<script>
export default {
name:'test',
props:{
'cityidx': {
type: Number,
default: 0
},
'areaidx': {
type: Number,
default: 0
},
'cities': {
type: Array,
default: () => []
},
'areas': {
type: Array,
default: () => []
},
},
computed: {
cityselect: {
get(){
return this.cityidx;
},
set(val){
this.$emit('update:current-city' , val);
}
},
areaselect: {
get(){
return this.areaidx;
},
set(val){
this.$emit('update:current-area' , val);
}
},
},
};
</script>
You can try like this:
<template>
<select v-model="selectedCity" name="city">
<option v-for="city in cities" :key="city.id" :value="city.id">{{ city.name }}</option>
</select>
<select v-model="selectedArea" name="area">
<option v-for="area in areas" :key="area.id" :value="area.id">{{ area.name }}</option>
</select>
</template>
<script>
export default
{
name: 'SelectCityArea',
props:
{
currentCity:
{
type: [String, Number],
default: null
},
currentArea:
{
type: [String, Number],
default: null
},
cities:
{
type: Array,
default: () => []
},
areas:
{
type: Array,
default: () => []
},
},
emits: ['update:current-city', 'update:current-area'],
computed:
{
selectedCity:
{
get()
{
return this.currentCity;
},
set(val)
{
this.$emit('update:current-city', val);
}
},
selectedArea:
{
get()
{
return this.currentArea;
},
set(val)
{
this.$emit('update:current-area', val);
}
},
}
}
and then use it like
<template>
<SelectCityArea v-model:current-city="myCity" v-model:current-area="myArea" :cities="cityList" :areas="areaList" />
</template>
<script>
export default
{
name: 'ParentComponent',
data()
{
return {
myCity: null,
myArea: null,
}
},
computed:
{
cityList()
{
return [
{ id: 1, name: 'Paris' },
{ id: 2, name: 'New York' },
]
},
areaList()
{
return [
{ id: 3, name: 'Europe' },
{ id: 4, name: 'North America' },
]
}
}
}
Working example below:
const { createApp } = Vue;
createApp({
components:
{
SelectCityArea:
{
template: `<label>City: <select v-model="selectedCity" name="city" class="space">
<option v-for="city in cities" :key="city.id" :value="city.id">{{ city.name }}</option>
</select></label>
<label>Area: <select v-model="selectedArea" name="area" class="space">
<option v-for="area in areas" :key="area.id" :value="area.id">{{ area.name }}</option>
</select></label>`,
props:
{
currentCity:
{
type: [String, Number],
default: null
},
currentArea:
{
type: [String, Number],
default: null
},
cities:
{
type: Array,
default: () => []
},
areas:
{
type: Array,
default: () => []
},
},
emits: ['update:current-city', 'update:current-area'],
computed:
{
selectedCity:
{
get()
{
return this.currentCity;
},
set(val)
{
this.$emit('update:current-city', val);
}
},
selectedArea:
{
get()
{
return this.currentArea;
},
set(val)
{
this.$emit('update:current-area', val);
}
},
},
}
},
template: `<SelectCityArea v-model:current-city="myCity" v-model:current-area="myArea" :cities="cityList" :areas="areaList"></SelectCityArea><div class="space">City: {{ myCity }}</div><div class="space">Area: {{ myArea }}</div>`,
data()
{
return {
myCity: null,
myArea: null,
};
},
computed:
{
cityList()
{
return [
{ id: 1, name: 'Paris' },
{ id: 2, name: 'New York' },
]
},
areaList()
{
return [
{ id: 3, name: 'Europe' },
{ id: 4, name: 'North America' },
]
}
},
}).mount('#app');
<script src="https://unpkg.com/vue@3"></script>
<div id="app"></div>
<style>
.space
{
margin: 5px;
}
</style>