VueJS: v-модель на элементе? Как с этим справиться?

#vue.js #vuejs2 #vuex

#vue.js #vuejs2 #vuex

Вопрос:

У меня есть этот простой компонент, отображающий информацию о пользователе:

 <div class="m-card-user__details">
  <span class="m-card-user__name m--font-weight-500">
    {{ firstname }} {{ lastname }}
  </span>
  <a class="m-card-user__email m--font-weight-300 m-link">
    {{ loginEmail }}
  </a>
</div>
  

Скрипт

 <script>
export default {
  data () {
    return {
      loginEmail : this.$store.getters.user.loginEmail,
      firstname: this.$store.getters.user.firstName,
      lastname: this.$store.getters.user.lastName,
    }
  }
};
</script>
  

Проблема в том, что если другой компонент изменяет значение свойства firstname в хранилище VueX, я вижу, что значение хорошо обновлено в хранилище, но не в моем компоненте здесь..

Как я могу установить 2 способа привязки к элементу?

Ответ №1:

Прикрепление переменной хранилища непосредственно к data() нарушит двустороннюю привязку.

Используйте для этого вычисляемое свойство, например:

 computed: { 
  loginEmail() { 
    return this.$store.getters.user.loginEmail;
  }
} 
  

а затем используйте вычисленное для span , как {{ loginEmail }} обычно.


Улучшение: Если вы хотите, вы можете вернуть все ...getters.user (как объект) с computed помощью, например:

 computed: { 
  user() { 
    return this.$store.getters.user;
  }
} 
  

а затем используйте его в своем span, например {{ user.loginEmail }} , и так далее.

Это сэкономит вам несколько строк, повысит читаемость и, возможно, немного повысит производительность.

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

1. В этом случае я бы использовал mapGetters вспомогательную функцию: vuex.vuejs.org/guide/getters.html#the-mapgetters-helper

Ответ №2:

Вы также можете напрямую использовать $store в своем шаблоне.

 <div class="m-card-user__details">
  <span class="m-card-user__name m--font-weight-500">
    {{ $store.getters.user.firstName }} {{ $store.getters.user.lastName }}
  </span>
  <a class="m-card-user__email m--font-weight-300 m-link">
    {{ $store.getters.user.loginEmail }}
  </a>
</div>
  

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

Смотрите также https://github.com/vuejs/vuex/issues/306 .

Редактировать: Поскольку вы упомянули двустороннюю привязку: вы не должны делать это для обновления $store , вместо этого используйте действия и мутации. В этом случае все в порядке, поскольку это, по сути, односторонняя привязка, при которой состояние передается в innerHTML ваших <span> файлов.

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

1. Обратите внимание, что при таком подходе требуется многократный доступ к хранилищу Vuex, что может немного замедлить работу приложения, особенно если оно большое, а может и не замедлить. Это также снижает читаемость.