Событие $emit от дочерних элементов до родительского элемента, который находится внутри v-for в VueJS

Допустим , я получил следующую структуру:

// parent template
<div v-for="item in items">
   <span>Parent</span>
   <children1>
      // inside children1, i got another children
      <children2 @on:finished="onFinished"></children2>
      <button>Click me</button>
   </children1>
</div>

Тогда у детей1 methods у меня было бы что-то вроде этого, чтобы слушать children2:

methods: {
    onFinished: function () {
       // Here i would like to disable `click me` button and change its text for this particular item inside the iteration
    }
}

От детей2 Я просто выполняю это, когда что-то заканчивается там.

this.$emit('on:finished', true)

Поскольку я пишу внутри метода, я хотел бы иметь возможность изменять с помощью VueJS только один из элементов $emit от его дочерних элементов. Но я думал об использовании свойства данных, но это повлияет на весь шаблон, а как насчет использования computed возможно? это будет работать? но как?

Какие-либо предложения?

3 ответа

Решение

Кажется, вам не хватает данных для отслеживания отключенного состояния каждого дочернего компонента. Посмотрите, нужен ли этот пример, нажмите кнопку "Готово" для каждого дочернего элемента, чтобы отключить другую кнопку:

Vue.component('child-component', {
  props: ['disabled', 'text'],
  template: `<div><button :disabled="disabled">{{ text }}</button><button @click="$emit('finished')">Finish</button></div>`
})

new Vue({
  el: '#app',
  data () {
    return {
      children: []
    }
  },
  mounted () {
    this.children = Array.from(Array(10), (x,i) => {
      return {
        id: i,
        disabled: false,
        text: 'Click Me'
      }
    })
  },
  methods: {
    onFinished (e, i) {
      this.children[i].disabled = !this.children[i].disabled
      this.children[i].text = this.children[i].disabled ? 'Disabled' : 'Click Me'
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <span>Parent</span>
  <child-component :disabled="child.disabled" :text="child.text" v-for="(child, i) in children" @finished="onFinished($event, i)" :key="child.id"></child-component>
</div>

Прежде всего, вы должны правильно прислушиваться к

  <div v-for="(item,index) in items">
   <span>Parent</span>
   <children :myIndex='index' @finished="onFinished"></children>
   <button>Click me</button>
  </div>

Обратите внимание, что я также добавил индекс для вашего ребенка, который должен быть принят в качестве опоры в вашем дочернем компоненте.

props:[myIndex]

куда onFinished() это метод внутри вашего родительского компонента

В вашем дочернем компоненте излучайте так

this.$emit('finished', {state: true, index: myIndex})

Теперь вы можете использовать этот индекс внутри вашего метода

onFinished(itemState){
this.items[itemState.index].state = itemState.state
}

Вы можете использовать индекс предмета для изменения его состояния.

    data: function () {
     items: [
       {
          enabled: true  
       },
       {
          enabled: true
        }
    ]

Для отключения функции:

disableItem (index) {
  this.items[index].enabled = false
}

И в шаблоне:

<div v-for="(item, index) in items">
<span>Parent</span>
<children @on:finished="disable(index)"></children>
<button>Click me</button>
</div>
Другие вопросы по тегам