Vue валидация динамическое формы

273
15 октября 2021, 10:40

Есть vue, bootstrap-vue и динамическая форма, введенные значения нужно провалидировать. Форма динамическая, т.е. пользователь может добавлять добавлять и удалять поля.

<ul>
  <li v-for="(input, index) in inputs_hosts_ip">
     <b-input-group>
        <b-form-input type="text" v-model="input.host">
     </b-form-input>
     <b-form-input type="text" v-model="inputs_hosts_ip[index].ip">
     </b-form-input>
     <mu-button small slot="actions" @click="deleteHostIp(index)" class="demo-color-btn" color="#0097a7">отмена</mu-button>
     </b-input-group>
  </li>
</ul>

Пробовал добавить vee-validate - одна ошибка дублируется под каждым полем, а так не пойдет. Даже не представляю как зацепиться за уникальные значения полей, чтобы сделать валидацию.

Answer 1

Так подойдет ? Вы можете обращаться к модели по индексу и валидировать значения в методе. Если не получится - пишите :)

var app = new Vue({ 
  el: '#app', 
  data: { 
    inputs_hosts_ip: [], 
    form: [], 
  }, 
  methods: { 
    addField(item) { 
      this.inputs_hosts_ip.push({ 
        name: 'input_' + this.inputs_hosts_ip.length, 
        type: item 
      }); 
    }, 
    removeField(index) { 
      this.form.splice(index, 1); 
      this.inputs_hosts_ip.splice(index, 1); 
    }, 
    validate(e) { 
      // validation here 
    } 
  }, 
})
*{margin:0;padding:0;box-sizing:border-box}#app{padding:15px}ul{list-style:none;width:300px}div{margin-top:10px;font-size:12px}label{display:flex;align-items:center}input{border:none;width:100px;height:100%;outline:0;transition:.2s;font-size:16px;margin:10px 0;margin-right:5px}input+button{flex-shrink:0;border:none;background:0 0;font-size:14px;cursor:pointer;outline:0;border:1px dotted #ccc;padding:5px}.type{margin-left:10px}input:focus+button{border-color:red}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script> 
 
<div id="app"> 
  <ul> 
    <li v-for="(input, index) in inputs_hosts_ip"> 
      <label> 
        <input 
           v-model="form[index]" 
           :name="input.name" 
           :type="input.type" 
           class="input" 
           :placeholder="input.name" 
           @blur="validate" 
         > 
         <button @click="removeField(index)">Remove</button> 
         <span class="type">Type is <kbd>{{ inputs_hosts_ip[index].type }}</kbd></span> 
     </label> 
 
    </li> 
  </ul> 
  <button @click="addField('text')">Add text field</button> 
  <button @click="addField('password')">Add password field</button> 
  <button @click="addField('email')">Add email field</button> 
  <div> 
    Array: <kbd>{{ form }}</kbd> 
  </div> 
 
</div>

UPD: Добавил кнопки выбора типа инпута для добавления

Answer 2

у меня это получилось как-то так: https://codepen.io/gleb-shalajkin/pen/qBBYwEq?editors=1010

new Vue({ 
  el: '#app', 
  data () { 
    return { 
      items: [], 
      name: 'text' 
    } 
  }, 
  methods: { 
    creatNewInput(){ 
      this.items.push({ [this.name]: '' }); 
    }, 
    deleteInput(){ 
      this.items.pop(); 
    }, 
    check(){ 
      //проверка 3 поля 
      const input = 2; 
 
      if(this.items[input].text === '') { 
        this.items[input].text = 'Чувак, ты не заполнил 3 поле' 
        this.$refs[`${this.name}_${input}`][0].style.background = 'red'; 
      } 
    } 
  } 
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script> 
  <div id="app"> 
      <div v-for="(item, index) in items"> 
        <input type="text" v-model="item[name]" :ref="name + '_' +index"> 
      </div> 
       
      <button @click="creatNewInput()">Добавить</button> 
      <button @click="deleteInput()">Удалить</button> 
      <button @click="check()">Проверить</button> 
  </div>

Так как все свойства vue реактивны, их нужно указывать вначале или задавать с помощью Vue.set(object, propertyName, value). Если у пользователя должна быть возможность создавать сколько угодно инпутов, то как по мне оба эти варианта не очень подходят. Можно сделать одно единственное реактивное свойство(в моем случае это items) и хранить/удалять в нем данные.

Так же обращаться к инпутам можно с помощью ref. Официальная документация: https://ru.vuejs.org/v2/api/#ref

READ ALSO
Перебор всех строк таблицы

Перебор всех строк таблицы

Есть некоторая таблица

138
Задача на рекурсию в JavaScript [закрыт]

Задача на рекурсию в JavaScript [закрыт]

Хотите улучшить этот вопрос? Обновите вопрос так, чтобы он вписывался в тематику Stack Overflow на русском

300
Скрыть блок при нажатии вне его

Скрыть блок при нажатии вне его

Есть два input-а реализованные, как selectЕсли кликаем на первый блок, затем на второй, то первый должен закрываться У них одинаковые классы

160
WPF не работает MinWidth/MinHeight

WPF не работает MinWidth/MinHeight

Не работает MinWidth/MinHeightЧто делать? Xaml: 1) Работает

135