Nano Hash - криптовалюты, майнинг, программирование

Как использовать Vue Router из состояния Vuex?

В своих компонентах я использовал:

this.$router.push({ name: 'home', params: { id: this.searchText }});

Изменить маршрут. Теперь я переместил метод в свои действия Vuex, и, конечно же, this.$router больше не работает. И Vue.router. Итак, как мне вызвать методы маршрутизатора из состояния Vuex, пожалуйста?

23.11.2016


Ответы:


1

Я предполагаю, что vuex-router-sync здесь не поможет, так как вам нужен маршрутизатор пример.

Поэтому, хотя это не кажется идеальным, вы можете установить экземпляр как глобальный в веб-пакете, т.е.

global.router = new VueRouter({
  routes
})

const app = new Vue({
  router
  ...

теперь у вас должна быть возможность: router.push({ name: 'home', params: { id: 1234 }}) из любого места в вашем приложении


В качестве альтернативы, если вам не нравится идея вышеизложенного, вы можете вернуть Promise из своего действия. Затем, если действие завершается успешно, я предполагаю, что оно вызывает мутацию или что-то в этом роде, и вы можете resolve выполнить обещание. Однако, если он не удастся и какое бы условие ни потребовалось для перенаправления, вам reject будет выполнено обещание.

Таким образом, вы можете переместить перенаправление маршрутизаторов в компонент, который просто улавливает отклоненное обещание и запускает push vue-router, т.е.

# vuex
actions: {
  foo: ({ commit }, payload) =>
    new Promise((resolve, reject) => {
      if (payload.title) {
        commit('updateTitle', payload.title)
        resolve()
      } else {
        reject()
      }
    })

# component
methods: {
  updateFoo () {
    this.$store.dispatch('foo', {})
      .then(response => { // success })
      .catch(response => {
        // fail
        this.$router.push({ name: 'home', params: { id: 1234 }})
      })
23.11.2016
  • Ваше первое предложение работает - спасибо. Почему подключать роутер к global - плохая идея? Точно так же мне нужен глобальный доступ к Vue-Resource - по какой-то причине импорт Vue и использование Vue.http отлично работает (но оптимально ли это?) Везде, где мне нужен Vue-Resource. Должен ли я также прикрепить Vue-Resource к глобальному? Что касается вашего второго пункта, я рассмотрю это (я не очень понимаю обещания) 23.11.2016
  • Я не совсем уверен, что это плохая идея, просто кажется, что это немного неправильно - как будто это должно быть что-то встроенное в vuex-router-sync. Я развил вторую идею на всякий случай, потому что мне очень нравятся обещания! Что касается vue-resource, да, это нормально - Vue.http предназначен для использования таким образом, нет необходимости делать это глобальным. 23.11.2016
  • У меня проблемы с синтаксисом Promise - не могли бы вы поискать секунду? jsbin.com/webezelaki/edit?js 23.11.2016

  • 2

    В такой ситуации я использую .go вместо .push.

    Извините, без объяснения причин, но в моем случае это сработало. Я оставляю это будущим гуглерам вроде меня.

    06.05.2019

    3

    Я считаю, что rootState.router будет доступен в ваших действиях, если вы передали router в качестве параметра в основном конструкторе Vue.

    Как упоминал GuyC, я также подумал, что вам может быть лучше вернуть обещание из вашего действия и маршрутизации после его разрешения. Проще говоря: dispatch(YOUR_ACTION).then(router.push()).

    24.11.2016
  • Да, я в конечном итоге придерживался подхода Promise, о котором упоминал GuyC. Как вы узнали / откуда мы должны знать о rootState? Нигде не видел, чтобы это было задокументировано. 24.11.2016
  • Да, вероятно, в документации не уделяется должного внимания. Это вроде как упоминается в документации по действиям Vuex, а иначе упоминается только в модули документации - она ​​определенно не бросается в глаза. 24.11.2016
  • По умолчанию в rootState нет router. Вводить его вручную также было бы излишним, поскольку экземпляр маршрутизатора в основном неизменяем, за исключением самого route, который является частью состояния при использовании vuex-router-sync. 15.08.2017

  • 4

    Обновлять

    После того, как я опубликовал этот ответ, я заметил, что определение его так, как я представил Typescript, перестало обнаруживать поля state. Я предполагаю, что это потому, что я использовал any как тип. Возможно, я мог бы определить тип вручную, но для меня это звучит как повторение. Таким образом, на данный момент я получил функцию вместо расширения класса (я был бы рад сообщить мне другое решение, если кто-то его знает).

    import { Store } from 'vuex'
    import VueRouter from 'vue-router'
    // ...
    
    export default (router: VueRouter) => {
      return new Store({
      // router = Vue.observable(router) // You can either do that...
      super({
        state: {
          // router // ... or add `router` to `store` if You need it to be reactive.
          // ...
        },
        // ...
      })
    }
    
    import Vue from 'vue'
    import App from './App.vue'
    import createStore from './store'
    // ...
    
    new Vue({
      router,
      store: createStore(router),
      render: createElement => createElement(App)
    }).$mount('#app')
    

    Первоначальное содержание ответа

    Я лично только что сделал обертку для типичного класса Store.

    import { Store } from 'vuex'
    import VueRouter from 'vue-router'
    // ...
    
    export default class extends Store<any> {
      constructor (router: VueRouter) {
        // router = Vue.observable(router) // You can either do that...
        super({
          state: {
            // router // ... or add `router` to `store` if You need it to be reactive.
            // ...
          },
          // ...
        })
      }
    }
    

    Если вам нужно $route, вы можете просто использовать router.currentRoute. Просто помните, что Вам скорее понадобится router реактивный, если Вы хотите, чтобы Ваш getters с router.currentRoute работал должным образом.

    А в main.ts (или .js) я просто использую его с new Store(router).

    import Vue from 'vue'
    import App from './App.vue'
    import Store from './store'
    // ...
    
    new Vue({
      router,
      store: new Store(router),
      render: createElement => createElement(App)
    }).$mount('#app')
    
    15.11.2020
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..