v-модель в v-цикле отображается в текстовом поле, но ничего не меняется

#loops #vue.js #vuejs2 #components #v-model

#петли #vue.js #vuejs2 #Компоненты #v-образная модель

Вопрос:

я пытаюсь перебрать массив объектов, чтобы составить список полей ввода, все работает нормально, кроме v-model, оно просто появляется в текстовом поле, но ничего не изменилось, я видел здесь много похожих вопросов, но ни один из ответов не сработал

мой корневой компонент:

 <template>
<div class="container">
    <add-product :inputs="inputs"></add-product>>
</div>
</template>

<script>

export default {
data(){
    return{
        inputs: [
            {id: '1', label: 'name', type: 'text', model:'name'},
            {id: '2', label: 'description', type: 'text', model: 'desc'},
            {id: '3', label: 'price', type: 'text', model: 'price'},
            {id: '4', label: 'size', type: 'text', model: 'size'},
            {id: '5', label: 'stock', type: 'text', model: 'stock'},

        ]
    }
},
components: {
    addProduct: AddProduct
}
}
 

Вложенный компонент:

  <template>
<transition name="fade">
    <div class="add-box">
        <div class="input--form" v-for="(input, index) in inputs" :key="index">
            <label >{{ input.label }}: </label>
            <input :type="input.type" v-model="input.model">
        </div>
    </div>
</transition>    
</template>

<script>
 export default {
props: {
    inputs: Array
},
data(){
    return{
        name: '',
        desc: '',
        price: '',
        size: '',
        stock: ''
    }
},

  </script>
 

Комментарии:

1. Ваш v-model должен быть на родительском компоненте, а не на дочерних элементах. Оставьте свой inputs реквизит для дочерних элементов, но вам нужно добавить a this.$emit , чтобы отправить реквизит обратно родительскому элементу (от дочерних элементов).

Ответ №1:

Основная причина, по которой ничего не происходит, заключается в том, что вы не выдаете событие, называемое input, из дочернего компонента. v-model это просто ярлык для привязки значения и отправки события, таким образом реализуя двустороннюю привязку данных с помощью одной директивы (см. Здесь ).

Однако вам не следует пытаться напрямую изменять prop в дочерних компонентах. Настоятельно рекомендуется не изменять какое-либо значение без ведома родителя.

В общем, всякий раз, когда вам нужно перебирать значения, вместо создания компонента, который обрабатывает весь массив, часто лучше, чтобы компонент обрабатывал одно значение из массива. То, как вы назвали дочерний компонент addProduct, предполагает, что вы также хотели, чтобы это было так. Поэтому я бы предложил следующие изменения.

Вложенный компонент

  <template>
  <transition name="fade">
    <div class="add-box">
      <div class="input--form">
        <label>{{ input.label }}: </label>
        <input :type="input.type" :value="input.model" @input="onInput" />
      </div>
    </div>
  </transition>
</template>

<script>
export default {
  props: {
    input: Object,
  },
  methods: {
    onInput(event) {
      this.$emit("input", {
        ...this.input,
        model: event.target.value,
      });
    },
  },
};
</script>
 

Родительский компонент

 <template>
  <div id="app">
    <add-product
      v-for="(input, index) in inputs"
      :key="input.id"
      :input="input"
      v-model="inputs[index]"
    ></add-product>
  </div>
</template>

<script>
import AddProduct from "./AddProduct";

export default {
  name: "App",
  components: {
    AddProduct,
  },
  data() {
    return {
      inputs: [
        { id: "1", label: "name", type: "text", model: "name" },
        { id: "2", label: "description", type: "text", model: "desc" },
        { id: "3", label: "price", type: "text", model: "price" },
        { id: "4", label: "size", type: "text", model: "size" },
        { id: "5", label: "stock", type: "text", model: "stock" },
      ],
    };
  },
};
</script>
 

Дочерний компонент не изменяет prop, а только выдает входной объект с обновленным значением. Поскольку имя события вводится, а имя реквизита — значение, v-model будет работать. В родительском массиве inputs выполняется итерация, и для каждого ввода v-model прилагается директива. Найдите живую демонстрацию здесь