Сбросить v-модель без обновления ее зависимых переменных

avatar
user1436631
7 апреля 2018 в 22:15
3441
1
1

У меня есть поля <input> типа

<input type="text" v-model=user.name" />
<input type="text" v-model="user.phone" />
<button @click="add">add user</button>

всякий раз, когда я нажимаю add user, он должен перемещать массив user в users и очищать v-model (чтобы привлечь больше пользователей). Мой метод add() выглядит следующим образом.

add()
{
  this.users.push( this.user );
  this.user.name = '';
  this.user.phone = '';
}

Однако после сброса user v-model элемент в массиве users также превращается в пустую строку. Как сбросить v-model без изменения данных в массиве users?

Источник
acdcjunior
7 апреля 2018 в 22:24
0

Описанное вами поведение не происходит с опубликованным вами кодом. Вы упрощаете более сложный сценарий?

Ответы (1)

avatar
acdcjunior
7 апреля 2018 в 22:39
0

Самый простой способ — сбросить весь объект user вместо свойства по свойству:

add()
{
  this.users.push( this.user );
  this.user = {name: '', phone: ''};
}

Демо:

new Vue({
  el: '#app',
  data: {
    user: {name: '', phone: ''},
    users: []
  },
  methods: {
    add() {
      this.users.push(this.user);
      this.user = {name: '', phone: ''};
    }
  }
})
<script src="https://unpkg.com/vue"></script>

<div id="app">
  name: <input type="text" v-model="user.name" /><br>
  phone: <input type="text" v-model="user.phone" /><br>
  <button @click="add">add user</button>
  <hr>
  users: {{ users }}
</div>

Почему это не сработало?

Потому что когда вы делаете:

this.users.push( this.user );
// this changes the name of the user that happens to be inside the users array
this.user.name = '';

Вы добавляете this.user в массив this.users. Если вы измените его позже, например this.user.name = 'something';, вы измените тот же объект (который теперь также находится внутри массива this.users).

С другой стороны, при перезаписи это новый объект:

this.users.push(this.user);
this.user = {name: '', phone: ''};
// the line above makes `this.user` point to (reference) a new object.
// the object that was pushed into the array still exists, but this.user does not point to it anymore
// the line below sets the name of the user created in the line above, not the previous (that is in the array)
this.user.name = 'bob';

Альтернатива: Клонирование.

Если бы вы захотели пойти по этому пути, у вас было бы несколько альтернатив. Из "ручного" клонирования:

new Vue({
  el: '#app',
  data: {
    user: {name: '', phone: ''},
    users: []
  },
  methods: {
    add() {
      this.users.push({name: this.user.name, phone: this.user.phone});
      this.user.name = '';
      this.user.phone = '';
    }
  }
})
<script src="https://unpkg.com/vue"></script>

<div id="app">
  name: <input type="text" v-model="user.name" /><br>
  phone: <input type="text" v-model="user.phone" /><br>
  <button @click="add">add user</button>
  <hr>
  users: {{ users }}
</div>

Для глубокого клонирования:

new Vue({
  el: '#app',
  data: {
    user: {name: '', phone: ''},
    users: []
  },
  methods: {
    add() {
      let userDeepClone = JSON.parse(JSON.stringify(this.user));
      this.users.push(userDeepClone);
      this.user.name = '';
      this.user.phone = '';
    }
  }
})
<script src="https://unpkg.com/vue"></script>

<div id="app">
  name: <input type="text" v-model="user.name" /><br>
  phone: <input type="text" v-model="user.phone" /><br>
  <button @click="add">add user</button>
  <hr>
  users: {{ users }}
</div>

Для поверхностного клонирования:

new Vue({
  el: '#app',
  data: {
    user: {name: '', phone: ''},
    users: []
  },
  methods: {
    add() {
      let userShallowClone = {...this.user}; // or Object.assign({}, this.user);
      this.users.push(userShallowClone);
      this.user.name = '';
      this.user.phone = '';
    }
  }
})
<script src="https://unpkg.com/vue"></script>

<div id="app">
  name: <input type="text" v-model="user.name" /><br>
  phone: <input type="text" v-model="user.phone" /><br>
  <button @click="add">add user</button>
  <hr>
  users: {{ users }}
</div>
user1436631
7 апреля 2018 в 22:45
0

Спасибо. Это сработало. можете ли вы объяснить, почему сброс свойства по свойству не работает, поскольку оба делают то же самое?