How to use multiple component to filter data
我想要发生的是,当您单击左侧的单选按钮时,它会过滤右侧的内容以仅显示相同的位置。
当有人单击单选按钮时,我不知道如何发出事件。
我在这个 vue 代码中使用了 x-template。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | 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 } }); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | .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; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"> <location-filter :location="location"></location-filter> {{ team.name }} <script type="text/x-template" id="location-filter"> <label> <input type="radio" name="place" value="place.value">{{ place.title }} </label> |
希望我的解释和代码足以让您了解我正在努力实现的目标。
您可以从组件内部发出自定义事件,例如当用户单击单选标签时,如下所示:
1 | <label @click="$emit('location', place.value)"> |
我将事件命名为
1 | <location-filter :location="location" @location="changeLocation"> |
现在,
1 2 3 | changeLocation(location) { this.selected = location; } |
您可以看到它为所选位置设置了一个名为
1 2 3 4 5 6 7 | filtered() { if (this.selected) { return this.teams.filter(team => team.location == this.selected); } else { return this.teams; } } |
最后,更新模板以循环遍历这个
1 |
我包含了一个更新的片段。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | 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; } } }); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | .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; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"> <location-filter :location="location" @location="changeLocation"></location-filter> {{ team.name }} <script type="text/x-template" id="location-filter"> <label @click="$emit('location', place.value)"> <input type="radio" name="place" value="place.value">{{ place.title }} </label> |