Vue应该只触发被点击的元素

时间:2019-06-17 14:26:44

标签: javascript vue.js

我正在第一个Vue项目。我有一张桌子,上面有牢房。当我双击一个单元格时,我想使用updated或类似的东西触发该单元格中的子组件。

到目前为止,我一直通过向其发送道具来做到这一点。有用。问题是,当我双击一个单元格时,所有子组件中都将触发updated。只需触发一个单元格,它就可以触发100或1000次。

屏幕截图

enter image description here

代码和问题

下面的代码与我的项目看起来相去甚远,但仍会显示问题。单击一个按钮,所有单元格都会对此做出反应,而不仅仅是单击的那个。

我确实理解为什么会这样。在我的子组件中,我输出由父组件更改的数据。然后,所有子组件都会对此做出反应。但是,当它们不处于活动状态时,无需全部触发它们。

我如何才能触发我单击的项目的updated

Vue.component('v-child', {
  props: ['item', 'active'],
  updated() {
    console.log('Clicked');
  },
  template: `
  <div>
      {{ item }} {{ active }}
  </div>`
  });

new Vue({
  el: '#app',
  data: {
    active: 0,
  	items: {
    	first: '1',
      second: '2',
      third: '3',
      a: 'a',
      b: 'b',
      c: 'c'
    },
    message: 'Hello Vue.js!'
  },
  methods: {
  	click(item) {
      this.active = item;
      console.log(this.active);
    }
  }
});
li {
  list-style: none;
  margin-bottom: 1rem;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
    <li v-for="item in items">
      <button v-on:click="click(item)">Button</button>
      <v-child :item="item" :active="active"></v-child>
    </li>
  </div>

2 个答案:

答案 0 :(得分:1)

每个孩子都会调用

updated,因为active已更改,因此需要渲染每个孩子。

有两种方法可以实现您想要的:

  • 导致active仅针对活动项目进行更改
  • 保留您的代码并添加一些验证,以检查孩子是否是活跃的孩子(Steven Spungin解决方案)

解决方案#1的示例

Vue.component('v-child', {
  props: ['item', 'active'],
  updated() {
    console.log('Clicked');
  },
  template: `
  <div>
      {{ item.value }} {{ item.count }}
  </div>`
});

new Vue({
  el: '#app',
  data: {
    active: 0,
    items: {
      first: {value:'1', count:0},
      second: {value:'2', count:0},
      third: {value:'3', count:0},
      a: {value:'a', count:0},
      b: {value:'b', count:0},
      c: {value:'c', count:0}
    },
    message: 'Hello Vue.js!'
  },
  methods: {
    click(item) {
      item.count++;
    }
  }
});
li {
  list-style: none;
  margin-bottom: 1rem;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <li v-for="item in items">
    <button v-on:click="click(item)">Button</button>
    <v-child :item="item" :active="active"></v-child>
  </li>
</div>

答案 1 :(得分:1)

将手表添加到active并将active的值与item进行比较。

Vue.component('v-child', {
  props: ['item', 'active'],
  watch: {
    active(value) {
      if (value === this.item) {
        console.log('Clicked:' + value);
      }
    }
  },
  template: `
  <div>
      {{ item }} {{ active }}
  </div>`
});

new Vue({
  el: '#app',
  data: {
    active: 0,
    items: {
      first: '1',
      second: '2',
      third: '3',
      a: 'a',
      b: 'b',
      c: 'c'
    },
    message: 'Hello Vue.js!'
  },
  methods: {
    click(item) {
      this.active = item;
    }
  }
});
li {
  list-style: none;
  margin-bottom: 1rem;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <li v-for="item in items">
    <button v-on:click="click(item)">Button</button>
    <v-child :item="item" :active="active"></v-child>
  </li>
</div>