Для чего нужна vuex-router-sync?

Насколько я знаю vuex-router-sync только для синхронизации route с vuex store и разработчик может получить доступ к route следующее:

store.state.route.path
store.state.route.params

Тем не менее, я также могу справиться route от this.$route что более кратко.

Когда мне нужно использовать маршрут в магазине, и в каком сценарии мне нужна vuex-router-sync?

1 ответ

Решение

Вот мои два цента. Вам не нужно импортировать vuex-router-sync если вы не можете выяснить его вариант использования в своем проекте, но вы можете захотеть, когда вы пытаетесь использовать route объект в вашем vuex метод (this.$route не будет хорошо работать в сфере Vuex).

Я хотел бы привести пример здесь.
Предположим, вы хотите показать сообщение в одном компоненте. Вы хотите отобразить сообщение как Have a nice day, Jack почти на каждой странице, за исключением случая, когда Welcome back, Jack должен отображаться при просмотре главной страницы пользователя.

Вы можете легко достичь этого с помощью vuex-router-sync,

const Top = {
  template: '<div>{{message}}</div>',
  computed: {
    message() {
      return this.$store.getters.getMessage;
    }
  },
};
const Bar = {
  template: '<div>{{message}}</div>',
  computed: {
    message() {
      return this.$store.getters.getMessage;
    }
  }
};

const routes = [{
    path: '/top',
    component: Top,
    name: 'top'
  },
  {
    path: '/bar',
    component: Bar,
    name: 'bar'
  },
];

const router = new VueRouter({
  routes
});

const store = new Vuex.Store({
  state: {
    username: 'Jack',
    phrases: ['Welcome back', 'Have a nice day'],
  },
  getters: {
    getMessage(state) {
      return state.route.name === 'top' ?
        `${state.phrases[0]}, ${state.username}` :
        `${state.phrases[1]}, ${state.username}`;
    },
  },
});

// sync store and router by using `vuex-router-sync`
sync(store, router);

const app = new Vue({
  router,
  store,
}).$mount('#app');












// vuex-router-sync source code pasted here because no proper cdn service found
function sync(store, router, options) {
  var moduleName = (options || {}).moduleName || 'route'

  store.registerModule(moduleName, {
    namespaced: true,
    state: cloneRoute(router.currentRoute),
    mutations: {
      'ROUTE_CHANGED': function(state, transition) {
        store.state[moduleName] = cloneRoute(transition.to, transition.from)
      }
    }
  })

  var isTimeTraveling = false
  var currentPath

  // sync router on store change
  store.watch(
    function(state) {
      return state[moduleName]
    },
    function(route) {
      if (route.fullPath === currentPath) {
        return
      }
      isTimeTraveling = true
      var methodToUse = currentPath == null ?
        'replace' :
        'push'
      currentPath = route.fullPath
      router[methodToUse](route)
    }, {
      sync: true
    }
  )

  // sync store on router navigation
  router.afterEach(function(to, from) {
    if (isTimeTraveling) {
      isTimeTraveling = false
      return
    }
    currentPath = to.fullPath
    store.commit(moduleName + '/ROUTE_CHANGED', {
      to: to,
      from: from
    })
  })
}

function cloneRoute(to, from) {
  var clone = {
    name: to.name,
    path: to.path,
    hash: to.hash,
    query: to.query,
    params: to.params,
    fullPath: to.fullPath,
    meta: to.meta
  }
  if (from) {
    clone.from = cloneRoute(from)
  }
  return Object.freeze(clone)
}
.router-link-active {
  color: red;
}
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
<script src="https://unpkg.com/vuex/dist/vuex.js"></script>

<div id="app">
  <p>
    <router-link to="/top">Go to Top</router-link>
    <router-link to="/bar">Go to Bar</router-link>
  </p>
  <router-view></router-view>
</div>

возиться здесь

Как видите, компоненты хорошо отделены от vuex а также vue-router логика
Этот шаблон иногда действительно эффективно работает в том случае, если вас не интересует связь между текущим маршрутом и значением, возвращаемым геттером vuex.

Я видел эту тему, когда я изучал Vue. Добавил немного моего понимания по этому вопросу.

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

В идеале, мы должны получить / построить согласованные (или идентичные) представления, если предоставленные состояния хранилища совпадают. Однако, маршрутизатор, совместно используемый несколькими компонентами, ломает это. Если нам нужно подумать о том, почему страница отображается так, как она есть, нам нужно проверить состояние хранилища, а также состояние маршрутизатора, если мы выводим представление из this.$router свойства.

vuex-router-sync является помощником для синхронизации состояния маршрутизатора с централизованным хранилищем состояний. Теперь все представления могут быть построены из государственного магазина, и нам не нужно проверять this.$router,

Обратите внимание, что route состояние является неизменным, и мы должны "изменить" его состояние через $router.push или же $router.go вызов. Может быть полезно определить некоторые действия в магазине как:

// import your router definition
import router from './router'

export default new Vuex.Store({
  //...
  actions: {
    //...
    // actions to update route asynchronously
    routerPush (_, arg) {
      router.push(arg)
    },
    routerGo (_, arg) {
      router.go(arg)
    }
  }
})

Это оборачивает route обновления в магазине действий, и мы можем полностью избавиться от this.$router зависимости в компонентах.

Другие вопросы по тегам