#vue.js
#vue.js
Вопрос:
Я пытаюсь создать функцию сортировки, в которой пользователь будет нажимать на разные штаты на карте США, и когда они нажимают на это состояние, отображается список городов, принадлежащих этому штату.
Так, например, у меня есть кнопка «Все», которая отображает все города в США, но если они нажимают на другой штат, тогда города необходимо отфильтровать до этих штатов.
Проблема, с которой я сталкиваюсь, заключается в том, что в некоторых городах есть либо полное название штата, либо аббревиатура.
Я бы хотел, чтобы мой фильтр мог сортировать как по полному имени, так и по аббревиатуре.
Итак, если я нажму на штат Алабама на карте, будут показаны города, в которых есть либо «Алабама», либо «Алабама».
Вот мой код
<template>
<div class="row">
<div class="col-md-12">
<div class="card">
<div class="card-body" id="sow-index">
<div class="row">
<div class="col-md-8">
<div class="form-group row">
<div class="col-sm-6">
<div class="btn-group btn-maps" role="group">
<button type="button" class="btn" v-on:click="selectedState = 'All'">All</button>
<button v-for="state in states" type="button" class="btn" v-on:click="selectedState = state">
<img :src="stateImage(state)">
<span>{{state}}</span>
</button>
</div>
</div>
<div class="col-sm-6">
<input type="text" class="form-control" v-model="search">
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<table class="table">
<thead>
<tr>
<th>Name</th>
</tr>
</thead>
<tbody>
<tr v-for="city in displayCities">
<td>{{city.name}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
export default {
data() {
return {
selectedState: 'All',
meta: {},
states: ['AL', 'CA', 'KS', 'OH'],
search: '',
state: 'All',
cities: [],
}
},
computed: {
stateCities() {
return ('All' === this.selectedState) ? this.cities.filter(city => {
city.state === this.selectedState
});
},
filteredCities() {
return ('' === this.search)
? this.stateCities
: this.stateCities.filter(city => this.getSearchString(city).indexOf(this.search.toLowerCase()) > -1);
},
},
methods: {
getSearchString(city) {
let string = city.name;
return string.replace('null', '').trim().toLowerCase();
},
stateImage(state) {
return "/states/image_" state ".jpg";
},
allCities() {
axios.get('/api/state/cities').then((response) => {
this.cities = response.data.cities;
})
}
},
mounted() {
this.allCities();
}
}
На данный момент я добавил только 4 состояния в свой код.
Вот пример вывода городов
cities: array(50)
0:
name: Athens
state: Alabama
1:
name: Greenville
state: AL
Комментарии:
1. Кроме того,
mounted
не должно быть в вашемmethods
объекте
Ответ №1:
Похоже, вам нужно, чтобы ваши states
значения содержали как сокращение, так и полное имя.
Например
data: () => ({
selectedState: null,
states: [{
name: "Alabama",
abbr: "AL"
}, {
name: "California",
abbr: "CA"
}, {
name: "Kansas",
abbr: "KS"
}, {
name: "Ohio",
abbr: "OH"
}],
search: '',
cities: [],
})
В вашем шаблоне привяжите эти значения объекта к selectedState
<button
type="button"
class="btn"
@click="selectedState = null"
>All</button>
<button
v-for="state in states"
:key="state.abbr"
type="button"
class="btn"
@click="selectedState = state"
>
<img :src="`/states/image_${state.abbr}.jpg`"> <!-- 👈 don't use methods for rendering -->
<span>{{state.abbr}}</span>
</button>
Затем в вашем вычисляемом методе используйте оба свойства для сопоставления
stateCities: ({ selectedState, cities }) => {
if (selectedState) {
return cities.filter(({ state }) =>
selectedState.abbr === state || selectedState.name === state)
}
return cities
}