【问题标题】:vue.js how do I bind a class on click to a list item created by v-for utilising a template component?vue.js 如何将单击时的类绑定到 v-for 使用模板组件创建的列表项?
【发布时间】:2018-05-18 05:12:20
【问题描述】:

我试图在单击模板组件时将活动类应用于模板组件中的列表项,这应该是独占的,并从所有其他列表项中删除该类。

我尝试在点击时传递一个新的数据对象并引用它,我什至使用了官方文档中的示例无济于事,我不知道为什么它不起作用。

Vue.component('delivery-options', {
      props: ['deliveries'],
      template: '<li><p><strong>{{ deliveries.price }}</strong>{{ deliveries.title }}</p><p>{{ deliveries.desc }}</p></li>'
    })
    Vue.component('ledger', {
      props: ['values'],
      template: '<li><p>{{ values.title }}<span>{{ values.price }}</span></p></li>'
    })
    var checkout = new Vue({
      el: '#checkout-app',
      data: {
        deliveryList: [
          { id: 0, price: '£3.99 ', title: 'Home delivery', desc: 'Lorem ipsum dolor sit amet.' },
          { id: 1, price: 'Free ', title: 'Store collection', desc: 'Lorem ipsum dolor sit amet.' },
          { id: 2, price: '£5.99 ', title: 'Precise delivery', desc: 'Lorem ipsum dolor sit amet.' }
        ],
        valuesList: [
          { id: 0, price: '£1233.99', title: 'Order value', desc: 'Lorem ipsum dolor sit amet.' },
          { id: 1, price: '£3.99', title: 'Delivery', desc: 'Lorem ipsum dolor sit amet.' },
          { id: 2, price: '£5.99', title: 'Total', desc: 'Your total including delivery.' }
        ]
      }
    })
ul {
  padding: 0;
}

ul li {
  list-style-type: none;
}

.delivery-options li {
  padding: 1rem;
  margin: 1rem;
  border-radius: 3px;
  border: 1px solid grey;
}

.ledger {
  padding: 1rem;
  margin: 1rem;
  border-radius: 3px;
  border: 1px solid grey;
}
<script src="https://unpkg.com/vue"></script>
<div id="checkout-app">
    <ul class="delivery-options">
      <delivery-options
        v-for="option in deliveryList"
        v-bind:deliveries="option"
        v-bind:key="option.id">
      </delivery-options>
    </ul>
    <ul class="ledger">
      <ledger
        v-for="value in valuesList"
        v-bind:values="value"
        v-bind:key="value.id">
      </ledger>
    </ul>
  </div>

【问题讨论】:

    标签: javascript class vue.js vuejs2 vue-component


    【解决方案1】:

    你需要做这样的事情:

    console.clear()
    
    Vue.component('delivery-options', {
          props: ['deliveries', "isActive"],
          template: `<li @click="$emit('set-active', deliveries)" :class="{active: isActive}"><p><strong>{{ deliveries.price }}</strong>{{ deliveries.title }}</p><p>{{ deliveries.desc }}</p></li>`
        })
        Vue.component('ledger', {
          props: ['values'],
          template: '<li><p>{{ values.title }}<span>{{ values.price }}</span></p></li>'
        })
        var checkout = new Vue({
          el: '#checkout-app',
          data: {
            activeDelivery: null,
            deliveryList: [
              { id: 0, price: '£3.99 ', title: 'Home delivery', desc: 'Lorem ipsum dolor sit amet.' },
              { id: 1, price: 'Free ', title: 'Store collection', desc: 'Lorem ipsum dolor sit amet.' },
              { id: 2, price: '£5.99 ', title: 'Precise delivery', desc: 'Lorem ipsum dolor sit amet.' }
            ],
            valuesList: [
              { id: 0, price: '£1233.99', title: 'Order value', desc: 'Lorem ipsum dolor sit amet.' },
              { id: 1, price: '£3.99', title: 'Delivery', desc: 'Lorem ipsum dolor sit amet.' },
              { id: 2, price: '£5.99', title: 'Total', desc: 'Your total including delivery.' }
            ]
          },
        })
    ul {
      padding: 0;
    }
    
    ul li {
      list-style-type: none;
    }
    
    .delivery-options li {
      padding: 1rem;
      margin: 1rem;
      border-radius: 3px;
      border: 1px solid grey;
    }
    
    .ledger {
      padding: 1rem;
      margin: 1rem;
      border-radius: 3px;
      border: 1px solid grey;
    }
    
    .active {
      color: red
    }
    <script src="https://unpkg.com/vue"></script>
    <div id="checkout-app">
        <ul class="delivery-options">
          <delivery-options
            v-for="option in deliveryList"
            v-bind:deliveries="option"
            v-bind:key="option.id"
            v-bind:is-active="option === activeDelivery"
            v-on:set-active="v => activeDelivery = v">
          </delivery-options>
        </ul>
        <ul class="ledger">
          <ledger
            v-for="value in valuesList"
            v-bind:values="value"
            v-bind:key="value.id">
          </ledger>
        </ul>
      </div>

    基本上,使用数据属性跟踪哪个交付是活跃的,然后根据它是否是活跃交付来设置组件中的类。为了在点击时设置主动交付,组件需要发出一个事件,让父级知道点击了哪个交付。

    【讨论】:

    • 太棒了,谢谢,我以前也有类似的东西,但它只是跟踪对父级的点击,因此它实际上并没有更新任何东西
    猜你喜欢
    • 2019-09-21
    • 2019-08-06
    • 2019-04-14
    • 2021-02-08
    • 2020-12-14
    • 2019-03-27
    • 2019-12-09
    • 2017-12-10
    • 1970-01-01
    相关资源
    最近更新 更多