如果单击框列表,如何添加选择的按钮?

时间:2018-09-29 07:54:48

标签: twitter-bootstrap vue.js vuejs2 bootstrap-4 vue-component

我从这里得到参考:

https://bootstrap-vue.js.org/docs/components/card/#card-groups

https://bootstrap-vue.js.org/docs/components/button/#pressed-state-and-toggling

我的Vue组件是这样的:

<template>
    ...
        <b-card-group deck v-for="row in formattedItems">
            <b-card :title="item.title"
                    img-src="http://placehold.it/140?text=No image"
                    img-alt="Img"
                    img-top
                    v-for="item in row">
                <p class="card-text">
                    {{item.price}}
                </p>
                <p class="card-text">
                    {{item.country}}
                </p>
                <div slot="footer">
                    <b-button-group size="sm">
                        <b-button :pressed.sync="oriPress" variant="outline-primary">Original</b-button>
                        <b-button :pressed.sync="kwPress" variant="outline-primary">Kw</b-button>
                    </b-button-group>
                    <b-btn variant="primary" block>Add</b-btn>
                </div>
            </b-card>
        </b-card-group>
    ....
</template>

<script>
    export default {
        ..
        data () {
            return{
                items: [
                     {id:1, title:'chelsea', price:900, country: 'england'},
                     {id:2, title:'liverpool', price:800, country: 'england'},
                     {id:3, title:'mu', price:700, country: 'england'},
                     {id:4, title:'city', price:600, country: 'england'},
                     {id:5, title:'arsenal', price:500, country: 'england'},
                     {id:6, title:'tottenham', price:400, country: 'england'},
                     {id:7, title:'juventus', price:300, country: 'italy'},
                     {id:8, title:'madrid', price:200, country: 'span'},
                     {id:9, title:'barcelona', price:100, country: 'span'},
                     {id:10, title:'psg', price:50, country: 'france'}
                ],
                oriPress: true,
                kwPress: false
            }
        },
        mounted: function () {
            this.getItems()
        },
        computed: {
            formattedItems() {
                return this.items.reduce((c, n, i) => {
                    if (i % 4 === 0) c.push([]);
                    c[c.length - 1].push(n);
                    return c;
                }, []);
            }
        }
    }
</script>

如果执行了脚本,则所有框中的原始按钮处于活动状态,而所有框中的kw按钮处于非活动状态

那是我所期望的。但是我的问题是,当我单击kw按钮或原始按钮时,所有按钮都处于活动状态或无效状态。我只希望在每个框上选择的按钮上激活它

例如,有10个盒子。当我单击第三个框中的原始按钮时,第三个框中的原始按钮将处于活动状态,而kw按钮将处于非活动状态。当我单击第九个框中的按钮kw时,第九个框中的按钮kw将处于活动状态,而原始按钮将处于非活动状态。其他人也是如此

我该怎么办?

1 个答案:

答案 0 :(得分:2)

问题是所有项目都使用相同的oriPresskwPress数据属性。您可以将这些属性移到items[]中,以使它们对于每个项目都是唯一的:

// script
data() {
  return {
    items: [
      {id: 1, oriPress: true, kwPress: false, ...},
      {id: 2, oriPress: true, kwPress: false, ...},
    ]
  }
}

//template
<b-card-group v-for="row in formattedItems">
  <b-card v-for="item in row">

      <b-button :pressed.sync="item.oriPress">Original</b-button>
      <b-button :pressed.sync="item.kwPress">Kw</b-button>

  </b-card>
</b-card-group>

...但是我假设items[]的形状无法更改。另一种方法是创建一个oriPresskwPress属性的映射(每项一个)。这可以通过将items[]上的watcher初始化oriPresskwPress到项目ID到布尔值的映射来完成:

// script
data() {
  return {
    items: [...],
    oriPress: {},
    kwPress: {},
  }
},
watch: {
  items: {
    immediate: true,
    handler(value) {
      this.oriPress = value.reduce((p,c) => {
        p[c.id] = true;
        return p;
      }, {});

      this.kwPress = value.reduce((p,c) => {
        p[c.id] = false;
        return p;
      }, {});
    }
  }
},


//template
<b-card-group v-for="row in formattedItems">
  <b-card v-for="item in row">

      <b-button :pressed.sync="oriPress[item.id]">Original</b-button>
      <b-button :pressed.sync="kwPress[item.id]">Kw</b-button>

  </b-card>
</b-card-group>

new Vue({
  el: '#app',
  data() {
    return{
      items: [
        {id:1, title:'chelsea', price:900, country: 'england'},
        {id:2, title:'liverpool', price:800, country: 'england'},
        {id:3, title:'mu', price:700, country: 'england'},
        {id:4, title:'city', price:600, country: 'england'},
        {id:5, title:'arsenal', price:500, country: 'england'},
        {id:6, title:'tottenham', price:400, country: 'england'},
        {id:7, title:'juventus', price:300, country: 'italy'},
        {id:8, title:'madrid', price:200, country: 'span'},
        {id:9, title:'barcelona', price:100, country: 'span'},
        {id:10, title:'psg', price:50, country: 'france'}
      ],
      oriPress: {},
      kwPress: {}
    }
  },
  watch: {
    items: {
      immediate: true,
      handler(value) {
        this.oriPress = value.reduce((p,c) => {
          p[c.id] = true;
          return p;
        }, {});
        this.kwPress = value.reduce((p,c) => {
          p[c.id] = false;
          return p;
        }, {});
      }
    }
  },
  computed: {
    formattedItems() {
      return this.items.reduce((c, n, i) => {
        if (i % 4 === 0) c.push([]);
        c[c.length - 1].push(n);
        return c;
      }, []);
    }
  }
})
<script src="https://unpkg.com/vue@2.5.17"></script>

<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css"/>
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.css"/>
<script src="//unpkg.com/babel-polyfill@latest/dist/polyfill.min.js"></script>
<script src="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.js"></script>

<div id="app">
  <b-card-group deck v-for="row in formattedItems">
    <b-card :title="item.title"
            img-src="http://placehold.it/140?text=No image"
            img-alt="Img"
            img-top
            v-for="item in row">
      <p class="card-text">
        {{item.price}}
      </p>
      <p class="card-text">
        {{item.country}}
      </p>
      <div slot="footer">
        <b-button-group size="sm">
          <b-button :pressed.sync="oriPress[item.id]" variant="outline-primary">Original</b-button>
          <b-button :pressed.sync="kwPress[item.id]" variant="outline-primary">Kw</b-button>
        </b-button-group>
        <b-btn variant="primary" block>Add</b-btn>
      </div>
    </b-card>
  </b-card-group>
</div>