私がしたいのは、左側のラジオボタンをクリックすると、右側のコンテンツがフィルタリングされて、同じ場所だけが表示されるようにすることです。
誰かがラジオボタンをクリックしたときにイベントを発行する方法がわかりません。
このvueコードではxテンプレートを使用しています。
const locations = {
options: [
{
title: 'A',
value: 'a'
},
{
title: 'B',
value: 'b'
},
{
title: 'C',
value: 'c'
}]
};
const team = {
options: [
{
name: 'Team A',
location: 'a'
},
{
name: 'Team B',
location: 'b'
},
{
name: 'Team C',
location: 'c'
}]
};
Vue.component('location-filter', {
template: '#location-filter',
props: {
location: {
type: Array,
required: true
}
}
});
new Vue({
el: '#location-finder',
data: {
location: locations.options,
teams: team.options
}
});
.page {
padding:5px;
border:1px solid #cccccc;
display:flex;
flex-flow:row;
}
.sidebar {
flex-grow:0.6;
border: 1px solid red;
padding:10px;
}
.body {
padding:10px;
border:1px solid blue;
flex-grow:1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div class="page" id="location-finder">
<div class="sidebar">
<location-filter :location="location"></location-filter>
</div>
<div class="body">
<div v-for="team in teams">
<div>{{ team.name }}</div>
</div>
</div>
</div>
<script type="text/x-template" id="location-filter">
<div>
<div v-for="place in location">
<label>
<input type="radio" name="place" value="place.value">{{ place.title }}
</label>
</div>
</div>
</script>
うまくいけば、私の説明とコードで、私が達成しようとしていることの全体像を把握するのに十分です。
次のように、ユーザーが無線ラベルをクリックしたときなど、コンポーネントの内部からカスタムイベントを発行できます。
<label @click="$emit('location', place.value)">
イベントに名前を付けましたlocation
。これlocation
で、次のように親のテンプレート(locationFinder
)で指定されたイベントをリッスンできます。
<location-filter :location="location" @location="changeLocation">
ここで、そのイベントが発行さlocationFinder
れるchangeLocation
たびに呼び出されるインスタンス内のメソッドを呼び出そうとしますlocation
。そのメソッドは次のようになります。
changeLocation(location) {
this.selected = location;
}
selected
選択した場所に呼び出されるデータプロパティを設定していることがわかります。したがって、teams
そのselected
場所を確認するためにループが必要になり、その場所が選択した場所と一致する場合にのみチームを表示します。これを行う最良の方法computed
は、チームリストのフィルタリングされたバージョンを常に含むプロパティを作成することです。選択したチームがない場合は、すべてのチームが返されます。
filtered() {
if (this.selected) {
return this.teams.filter(team => team.location == this.selected);
} else {
return this.teams;
}
}
最後に、テンプレートを更新してfiltered
、フィルタリングされていないリストではなく、このチームリストをループします。
<div v-for="team in filtered">
更新されたスニペットを含めました。
const locations = {
options: [
{
title: 'A',
value: 'a'
},
{
title: 'B',
value: 'b'
},
{
title: 'C',
value: 'c'
}]
};
const team = {
options: [
{
name: 'Team A',
location: 'a'
},
{
name: 'Team B',
location: 'b'
},
{
name: 'Team C',
location: 'c'
}]
};
Vue.component('location-filter', {
template: '#location-filter',
props: {
location: {
type: Array,
required: true
}
}
});
new Vue({
el: '#location-finder',
data: {
location: locations.options,
teams: team.options,
selected: null
},
computed: {
filtered() {
if (this.selected) {
return this.teams.filter(team => team.location == this.selected);
} else {
return this.teams;
}
}
},
methods: {
changeLocation(location) {
this.selected = location;
}
}
});
.page {
padding:5px;
border:1px solid #cccccc;
display:flex;
flex-flow:row;
}
.sidebar {
flex-grow:0.6;
border: 1px solid red;
padding:10px;
}
.body {
padding:10px;
border:1px solid blue;
flex-grow:1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div class="page" id="location-finder">
<div class="sidebar">
<location-filter :location="location" @location="changeLocation"></location-filter>
</div>
<div class="body">
<div v-for="team in filtered">
<div>{{ team.name }}</div>
</div>
</div>
</div>
<script type="text/x-template" id="location-filter">
<div>
<div v-for="place in location">
<label @click="$emit('location', place.value)">
<input type="radio" name="place" value="place.value">{{ place.title }}
</label>
</div>
</div>
</script>
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加