Problema

Necesito restablecer todos los select s dentro de una matriz que no tiene v-model s dentro de Vue.js.

Plantilla

<div id="app">
  <div v-for="(element, index) in elements">
    <select @input="setElement(index, $event.target.value)">
      <option v-for="option in options" :value="option">{{option}}</option>
    </select>
  </div>

  <button @click="addElement">
    Set three elements
  </button>
</div>

Guión

new Vue({
  el: '#app',
  data() {
    return {
      options: ['a', 'b', 'c'],
      elements: [{
        element: ''
      }, {
        element: ''
      }]
    }
  },

  methods: {
    addElement() {
        this.elements = []
        this.elements.push({
          element: ''
        })
        this.elements.push({
          element: ''
        })
        this.elements.push({
          element: ''
        })
      },

      setElement(index, el) {
        let element = {
          element: el
        }

        this.$set(this.elements, index, element)
      }
  }
})

Demostración : https://jsfiddle.net/jqb99tks/4/

Deseo

Cuando la longitud de elements cambia (por ejemplo, un reinicio), los select s deben reiniciarse.

Acercarse

Puedo recorrer todos los HTML select sy restablecerlos manualmente, pero parece una solución pirateada.

1
Julian 13 nov. 2017 a las 12:58

2 respuestas

La mejor respuesta

La razón por la que sucede es porque Vue intenta reutilizar HTML y evitar que sea costoso volver a reproducirlo porque cree que es posible hacerlo. En su caso, opta por no volver a entregar los cuadros de selección. Para decirle al framework que desea que se vuelva a generar HTML (como en su caso para restablecer el valor seleccionado), solo necesita usar una clave única que es diferente del valor renderizado anterior:

<div v-for="(element, index) in elements">
  <select :key="index + elements.length" @input="setElement(index, $event.target.value)">
    <option v-for="option in options" :value="option">{{option}}</option>
  </select>
</div>

Tenga en cuenta que agregué :key="index + elements.length". elements.length está ahí para hacer que la clave dependa de la longitud de elements, index solo no es suficiente, ya que será el mismo, es decir, 0, 1, etc.

También tenga en cuenta que para que funcione es necesario revisar el método setElement ya que está haciendo algo extraño en este momento, this.$set(this.elements, index, element) es un problema. Cámbielo a algo como esto:

setElement(index, value) {
  this.$set(this.elements[index], 'element', value)
}

Demostración: https://jsfiddle.net/jqb99tks/6/

1
dfsq 13 nov. 2017 a las 10:32

Quizás esto sea mejor para ti. v-model se puede utilizar para "seleccionar".

https://jsfiddle.net/loocao/jqb99tks/8/

<div v-for="(element, index) in elements">
  <select v-model="element.element">
    <option v-for="option in options" :value="option" :selected="element.element === option">{{option}}</option>
  </select>
</div>

Métodos:

addElement() {
    // first select
    this.elements.splice(0,1,{element: ''})
    // add one
    this.elements.push({element: 'a'})
}
0
loocao 13 nov. 2017 a las 12:47