Ответы пользователя по тегу Vuex
  • Можно ли сделать vuex store уникальным для каждого компонента?

    0xD34F
    @0xD34F Куратор тега Vue.js
    изменяя что-то в одном компоненте, меняется во всех

    Вам следует изменить структуру данных в хранилище - так, чтобы можно было держать там данные сразу для нескольких экземпляров mortgage-list. Сделайте объект, ключами будут id (те, что вы используете в качестве key - они ведь уникальные, правда же?). Ну а значениями - объекты с данными для отдельного экземпляра. В сам компоненте mortgage-list надо добавить вычисляемое свойство, где по id из хранилища будет извлекаться нужный объект.
    Ответ написан
    1 комментарий
  • Как организовать детальную страницу в каталоге с SPA + VueRouter + Vuex?

    0xD34F
    @0xD34F Куратор тега Vue.js
    При клике на элемент - я сохраняю текущий элемент в store vuex и перехожу по роуту...

    Вот и корень ваших проблем. Не надо ничего сохранять при клике. Просто переходите. А компонент, отображающий детальную информацию - пусть он сам разбирается, что и как. Получает в качестве параметра идентификатор объекта, который должен отобразить, и запрашивает нужные данные. Ну и watch на идентификатор - чтобы при его смене данные также обновлялись.

    UPD. Если все данные на клиенте уже есть, то вообще ничего не надо, кроме одного вычисляемого свойства в Detail, где по id (или что там у вас) будет из vuex извлекаться нужный объект.
    Ответ написан
  • Почему поля хранилища пусты при записи в объект?

    0xD34F
    @0xD34F
    Как выглядит ваш стейт:

    state: {
      user:{
        name:'',

    Как вы его пытаетесь обновлять:

    updateName(state, name){
      state.name=name;

    Так что там насчёт вашего name - он должен находиться в корне или быть частью user'а? То же касается и остальных редактируемых пользователем значений.

    Непосредственно к вашей проблеме не относится, но глаз режет сильно:

    Многовато копипастите.

    Четыре вычисляемых свойства, все одинаковые - как-то чересчур. Сделайте одно - объект user будет завёрнут в Proxy, для перехвата установки значений свойств:

    user() {
      return new Proxy(this.$store.state.user, {
        set: (target, prop, value) => {
          this.$store.commit('updateUser', { [prop]: value });
          return true;
        },
      });
    },

    И мутация тоже будет одна:

    updateUser(state, user) {
      Object.assign(state.user, user);
    },

    В v-model, соответственно, указываются свойства объекта:

    <input v-model="user.name">
    <input v-model="user.surname">
    <input v-model="user.email">
    <input v-model="user.phone">


    Неправильно обновляете стейт.

    this.$store.state.user.LS.push(userObj);

    this.$store.state.isAdding=false;

    Почему напрямую? Сделайте соответствующие мутации.
    Ответ написан
    2 комментария
  • Как правильно обновить вложенный объект?

    0xD34F
    @0xD34F
    Передавайте в мутацию не весь объект, а только ту его часть, которую собираетесь обновить:

    this.$store.commit('updateProduct', {
      product: product.options,
      data: {
        isFree: true,
      },
    });

    В противном случае, необходимо выполнять рекурсивное слияние свойств объектов. Если не готовы реализовывать подобное самостоятельно, воспользуйтесь каким-нибудь уже существующим решением, например.
    Ответ написан
    Комментировать
  • Как использовать в v-model свойства объекта из хранилища?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Вычисляемое свойство будет представлять собой объект из стейта, завёрнутый в Proxy, чтобы перехватывать установку значений свойств и вызывать мутацию:

    user() {
      return new Proxy(this.$store.state.user, {
        set: (target, prop, value) => {
          this.$store.commit('updateUser', { [prop]: value });
          return true;
        },
      });
    },

    Соответственно, сама мутация:

    updateUser(state, payload) {
      Object.assign(state.user, payload);
    },

    https://jsfiddle.net/jgv3h15k/
    Ответ написан
    2 комментария
  • Почему выдается ошибка "[vuex] unknown action type: ADD_CONTACT"?

    0xD34F
    @0xD34F
    this.$store.dispatch({type:'ADD_CONTACT'}, payload)

    actions:{
        addContact:

    Вы и вправду считаете, будто ADD_CONTACT и addContact - это одно и то же?

    И уж если при вызове действия (мутаций это тоже касается) используете объектный синтаксис - payload должен передаваться не отдельным параметром, а как часть первого:

    this.$store.dispatch({
      type: 'addContact',
      payload,
    });

    actions: {
      addContact: ({ commit }, { payload }) => commit('ADD_CONTACT', payload),
    },

    Ну и не очень понятно, зачем тут вообще нужно действие, никаких асинхронных операций не выполняете, можете сразу мутацию вызывать: this.$store.commit('ADD_CONTACT', payload).
    Ответ написан
    Комментировать
  • Как избежать автоматического обновления данных в store?

    0xD34F
    @0xD34F
    При присваивании или передаче в качестве параметра объект не копируется, копируется ссылка на него. Так что у вас в сторе оказывается тот же объект (в смысле - ссылка на тот же объект), что и в компоненте с формой.

    Когда кидаете объект в стор, делайте копию. Типа, не size: this.namespaceSize, а size: { ...this.namespaceSize }. Или внутри стора копируйте, в мутации.
    Ответ написан
  • Как вызвать геттер в другом модуле vuex?

    0xD34F
    @0xD34F
    Читаем документацию внимательнее, там сказано, что геттер

    получает следующие аргументы <...> При определении в модуле

    state,       // при использовании модулей — локальный state модуля
    getters,     // локальные геттеры текущего модуля
    rootState,   // глобальный state
    rootGetters  // все геттеры

    Особое внимание - на четвёртый параметр.
    Ответ написан
    Комментировать
  • Как выполнить код после завершения действия?

    0xD34F
    @0xD34F
    Читаем документацию внимательнее:

    Первое, что нужно знать — store.dispatch может обрабатывать Promise, возвращаемый обработчиком действия, и также возвращает Promise

    Возвращаете из своего действия промис - then - вызываете что там вам надо.
    Ответ написан
    1 комментарий
  • Почему не вызывается действие?

    0xD34F
    @0xD34F
    console.log(this.$store) - этот экшн видит
    spoiler
    5c6526665ea4f007374285.png

    На что стоит обратить внимание - наличие в сторе таких свойств, как originalCommit / originalDispatch. Надо полагать, какой-то плагин взял, да и подменил настоящие commit и dispatch (сохранив при этом ссылки исходные методы), и что там происходит в новых методах, почему не вызывается действие... Честно говоря, не очень интересно. Попробуйте воспользоваться исходным методом: this.$store.originalDispatch('setCategory', cat).
    Ответ написан
  • Как ждать первоначального наполнения стора перед загрузкой страницы?

    0xD34F
    @0xD34F Куратор тега Vue.js
    В хуке App.vue выглядит не очень уместно, хочется вынести эту логику в другое место.

    Это какую такую логику? У вас там в created будет простой вызов экшена, это одна строка. Уместно, делайте.

    UPD. Вынесено из комментариев:

    Почему я не могу блокировать загрузку приложения до выполнения нужного мне действия (запрос на апи, возврат ответа и наполнение стора)?

    Можете в своём main.js завернуть создание экземпляра vue в коллбек экшена, который загружает данные:

    store.dispatch('получитьДанные').then(() => {
      new Vue({
        el: '#app',
        store,
        router,
        ...

    Только пользователь ничего не увидит в процессе загрузки. А если инициировать загрузку данных внутри, можно показывать какой-нибудь прелоадер, пока данные не будут получены:

    <div v-if="данные в хранилище есть">
      основной контент приложения
    </div>
    <div v-else>
      данные загружаются, надо подождать
    </div>
    Ответ написан
  • Можно ли во vuex писать mutation через Object.assign?

    0xD34F
    @0xD34F
    Можно.

    Только разберитесь, что это за штука такая, Object.assign, что делает. А то вы явно чего-то не до конца понимаете, судя по показанному коду. Ну и имейте в виду, что если какое-то из свойств payload отсутствует в стейте, то после добавления оно не будет реактивным.
    Ответ написан
    1 комментарий
  • Почему не получается обратиться к getters?

    0xD34F
    @0xD34F Куратор тега Vue.js
    не получается обратиться к геттеру <...> показывает null, хотя если вызвать store.getters, то данные есть

    "Показывает null" - значит не успели ещё данные загрузиться к тому моменту, когда вы дёргаете геттер, только и всего. Нечего тут сказки рассказывать про "не получается". Всё окей.

    "Хотя" - не более чем особенность отображения объектов в консоли. Когда разворачиваете объект в первый раз, подтягивается его актуальное содержимое. Т.е., в консоль вы store.getters кидаете до получения данных, а смотрите что там есть уже после.

    Не хотите в компоненте видеть этот null - не надо рендерить экземпляр компонента, пока данные не будут получены:

    <компонент v-if="$store.getters.profile" />

    Правда, прямо сейчас вы так сделать не сможете, есть косяк, вот здесь:

    //Подключаю хранилище
    import store from './store';
    
    store.dispatch('getUser');
    new Vue({
        el: '#app',
        router: router,
        components:{
            'head-app':headImplant,
            'footer-app':footer,
            'sidebar-app': sidebar
        }
    });

    Где подключение-то? Просто импортировать в main.js экземпляр хранилища недостаточно, вы должны передать его в конструктор Vue, как свойство store объекта с настройками:

    new Vue({
      store,
      ...
    Ответ написан
    Комментировать
  • Как управлять состоянием множества диалоговых окон (Vue, Vuex, Element UI)?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Передавайте в мутацию вместо просто состояния диалога объект вида { имя_диалога: состояние }. Тогда при обновлении состояния диалогов не будет необходимости обращаться к ним поимённо:

    mutations: {
      dialogShow: (state, payload) => Object.assign(state.modals, payload),
    },

    В компоненте, вместо вычисляемого свойства modal, отвечающего за работу с одним диалогом, будет свойство modals, обеспечивающее получение состояния всех диалогов. А чтобы изменение состояния диалога по-прежнему выглядело как присваивание, воспользуемся Proxy, где будем перехватывать установку значений и вызывать мутацию:

    modals() {
      return new Proxy(this.$store.state.modals, {
        set: (target, prop, value) => {
          this.$store.commit('dialogShow', { [prop]: value });
          return true;
        },
      });
    },

    Соответственно, в шаблоне заменяем установку значения просто свойства на установку значения свойства объекта:

    <el-button @click="modals.dialogSignIn = true">sign in</el-button>
    
    <el-dialog :visible="modals.dialogSignIn" @close="modals.dialogSignIn = false">
      <span slot="footer" class="dialog-footer">
        <el-button @click="modals.dialogSignIn = false">Закрыть</el-button>
      </span>
    </el-dialog>

    Посмотреть живьём.
    Ответ написан
    1 комментарий
  • Как проверить, завершилось ли действие, вызванное из другого компонента?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Да не надо ничего проверять. Что у вас является следствием завершившегося действия? - наличие нужных данных. Сделайте соответствующий геттер, и повесьте на экземпляр компонента v-if с этим геттером. Пока данных нет - экземпляр компонента не будет рендериться, а значит и мутация, требующая отсутствующих данных, тоже вызвана не будет, а значит и ошибки не будет.
    Ответ написан
    Комментировать
  • Как передать данные из одного модуля в другой?

    0xD34F
    @0xD34F
    В products мутацию замените на экшен, который будет вызывать мутацию в cart. А из одного модуля напрямую менять состояние другого - идея так себе, на мой взгляд.
    Ответ написан
    Комментировать
  • Как сделать задержку главного компонента App при загрузке данных пользователя?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Сначала загружаете данные пользователя, а затем инициализируете приложение:

    store.dispatch('заргузитьДанныеПользователя').then(() => {
      new Vue({ ... });
    });

    Или, в компоненте:

    created() {
      this.$store.dispatch('заргузитьДанныеПользователя');
    },

    <div v-if="$store.state.данныеПользователя">
      контент
    </div>
    <индикатор-загрузки v-else />
    Ответ написан
    Комментировать
  • Для чего нужны фигурные скобки в списке параметров действий/мутаций?

    0xD34F
    @0xD34F
    Как распознать говнокодера, практическое руководство

    <...>

    Признак #17. Неспособность разграничить язык и фреймворк. Отнесение незнакомых синтаксических конструкций языка к особенностям используемого фреймворка.

    <...>

    Признак #32. Нечтение документации.

    Даже там упомянуто, что это за зверь:

    На практике для упрощения кода часто используется деструктуризация аргументов из ES2015 (особенно при необходимости многократного вызова commit):

    actions: {
      increment ({ commit }) {
        commit('increment')
      }
    }

    Ответ написан
    1 комментарий
  • Почему возникает ошибка "unknown action type"?

    0xD34F
    @0xD34F
    Потому что нет экшена. Что непонятного-то? Раз нет, а вызывать надо - добавьте его.

    UPD. Вынесено из комментариев:

    я понял, что нет экшена. Вопрос в том, что он есть )

    Не говорите ерунды, ошибка вываливается - значит нет. То, что вы показали метод с таким-то именем, ещё не значит, что у вас есть такой экшен.

    Какие могут быть варианты:
    • Вместо actions засунули его в mutations
    • Допустили опечатку - вместо actions написали anctions или action или actons или...
    • Забыли подключить модуль, в котором экшен находится
    • Неправильно вызываете - экшен находится в namespaced модуле
    • ...

    Проверяйте код своего хранилища, думайте.
    Ответ написан
  • Почему getter выдаёт undefined?

    0xD34F
    @0xD34F
    В state.FIELDS.formFieldsMap данные лежат

    А точно лежат? - может, не лежат, а подгружаются посредством запроса к базе данных или ещё куда. А пока не подгрузились, FIELDS является пустым объектом, никакого свойства formFieldsMap у него нет. Соответственно, геттер возвращает undefined. Может же такое быть?

    UPD. Вынесено из комментариев:

    Действительно, а как тогда быть?

    Можно заглушку какую-нибудь возвращать, если ничего нет, например:

    getters: {
      transportFields: state => state.FIELDS.formFieldsMap || [],
      ...

    А лучше - заранее создать в FIELDS нужное свойство, с пустым массивом в качестве начального значения.
    Ответ написан