Vuejs - 如何在点击时进行 v-for 循环

Vuejs - How to v-for loop on click

我正在学习 Vue 并尝试自己完成一项任务。

我想了解如何在@click 上 运行 v-for 循环,以便在初始状态下,只出现 "city" 模板,并且在每次点击时,游览模板呈现相关游览。

let EventBus = new Vue();
Vue.component('cities', {

 name: 'Listings',
 props: ['city','tour'],
 
 template: `
 <div>
 <div class='city-list box'>
 <city v-for='city in cities' :id='city.id' :key='city.id' :city='city' :tour='tour' @click.native='select(city)'></city>
 </div>
 <div class='tour-list box'>
 <tours v-for='tour in filter(tours)' :id='tour.id' :key='tour.id' :tour='tour'></tours>
 </div>
 </div>
 `,

 data() {
  return {

   cities: [
   {id:1, name: 'Istanbul'},
   {id:2, name: 'Paris'},
   {id:3, name: 'Barça'},
   {id:4, name: 'Rome'},
   {id:5, name: 'Mars'}
   ],

   tours: [
   {id:1, cid:1, name: 'Bosphorus'},
   {id:2, cid:2, name: 'Eiffel'},
   {id:3, cid:3, name: 'La Sagrada Familia'},
   {id:4, cid:4, name: 'Colosseum'},
   {id:5, cid:5, name: 'Mars Canyon'},
   {id:6, cid:1, name: 'Sultanahmet'},
   {id:7, cid:2, name: 'Champs-Élysées'},
   {id:8, cid:3, name: 'Casa Mila'},
   {id:9, cid:4, name: 'Trevi Fountain'},
   {id:10, cid:5, name: 'Mars Desert'},
   ]
  };
 },

 methods: {
  select(city) {
   console.log('select');
   EventBus.$emit('filter', city);
  },

  filter(tours) {
   console.log('filter');
   EventBus.$on('select', ()=>{
   cid = this.city.id;
   return tours.filter(function(tour) {
    return tour.cid == cid;
   });
  });
  },
 },

 components: {

  'city': {
   name: 'City',
   props: ['city'],
   template: `
   <div :id="[city.name.toLowerCase()]" :class="[city.name.toLowerCase()]">
   <h1>{{ city.name }}</h1>
   </div>`
  },

  'tour': {
   name: 'Tour',
   props: ['city', 'tour'],
   template: `
   <div :class="['tour-' + tour.id]" :id="[city.name.toLowerCase() + '-tours']" :refs="city.id" :data-id="city.id">
   {{ tour.name }}
   </div>
   `,
  },
 },

});

new Vue({
 el: '#root'
});
 body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
 }
 .box {
  margin: 48px auto;
  max-width: 1024px;
  display: flex;
  justify-content: center;
  align-items: center;
 }
 .box h1 {
  font-size: 1.1rem;
  color: #41f;
 }
 .box > div {
  padding: 24px;
  margin: 12px;
  width: 20%;
  min-height: 100px;
  border-radius: 2px;
  font-size: 1.15rem;
  line-height: 1;
 }

 .box > div:nth-child(1)
 {background-color: #ffb3ba;}
 .box > div:nth-child(2)
 {background-color: #ffdfba;}
 .box > div:nth-child(3)
 {background-color: #ffffba;}
 .box > div:nth-child(4)
 {background-color: #baffc9;}
 .box > div:nth-child(5)
 {background-color: #bae1ff;}
<script src="https://unpkg.com/vue@2.4.4/dist/vue.js"></script>
 <div id="root">
  <cities></cities>
 </div>

我也对艺术状态感兴趣,如果将两个模板放在一起(相关)并将此模型与数据库和路由器连接(city/tour-list)是一个好习惯。或者你会如何处理这种情况(我想 jsfiddle 应该是不言自明的)。

作为旁注,我尝试将游览作为子组件添加到父组件 [jsfiddle],我在其中按 ID 过滤结果,我不确定这种方式是否是组件和过滤结果的更好方法建筑感。

https://jsfiddle.net/oy5fdc0r/29/

https://jsfiddle.net/oy5fdc0r/30/

使用数据 属性 来跟踪所选城市,而不是 Eventbus。然后,您可以根据所选城市使用计算 属性 来显示正确的游览。

computed:{
      selectedTours(){
          return this.tours.filter(tour=>tour.cid == this.selectedCity.id)
      }
  },
    methods: {
        select(city) {
            this.selectedCity = city;
        },
    },