Для чего нужна 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
зависимости в компонентах.