Плагин vuex-presistedstate
имеет параметр конфигурации под названием rehydrated
, который позволяет вам передавать функцию, которая будет вызываться сразу после replaceState
. Если вы заботитесь только о звонках на replaceState
из этого плагина, тогда это должно соответствовать вашим потребностям.
Я не верю, что само хранилище обеспечивает «ловушку» для вызова replaceState
. Здесь реализован метод replaceState
:
https://github.com/vuejs/vuex/blob/e0126533301febf66072f1865cf9a77778cf2176/src/store.js#L183
Как видно из кода, он мало что делает. Даже абоненты, зарегистрированные с помощью subscribe
, не звонят. Однако вы могли бы потенциально использовать watch
для регистрации наблюдателя в указанном свойстве c в пределах состояния и использовать его для определения, когда состояние заменяется:
https://vuex.vuejs.org/api/#watch
Конечно, вам нужно быть осторожным, чтобы структурировать вещи так, чтобы только вызовы replaceState
вызывали наблюдателя, что может привести к сбою.
Еще одна альтернатива - это патч / переопределение метод replaceState
. Замените его своим собственным методом, который обращается к оригиналу, давая вам точку подключения для любой дополнительной функциональности, которая вам может понадобиться.
Я попытался продемонстрировать все вышеперечисленное в приведенном ниже примере:
// Can't use localStorage in an SO snippet...
const fakeStorage = {
vuex: `{"flag": {}, "number": ${Math.random()}}`
}
const storage = {
getItem (key) {
return fakeStorage[key]
},
setItem (key, value) {
fakeStorage[key] = value
},
removeItem (key) {
delete fakeStorage[key]
}
}
// Override replaceState with our own version
class StoreOverride extends Vuex.Store {
replaceState (...args) {
super.replaceState(...args)
console.log('replaceState called')
}
}
const store = new StoreOverride({
state: {
flag: {},
number: 0
},
plugins: [
createPersistedState({
rehydrated () {
console.log('rehydrated called')
},
storage
})
]
})
store.subscribe(() => {
console.log('store.subscribe called (will not happen for replaceState)')
})
store.watch(state => state.flag, () => {
console.log('store.watch called')
})
console.log('creating Vue instance')
new Vue({
el: '#app',
store,
methods: {
onReplace () {
// The property 'number' is changed so we can see something happen
this.$store.replaceState({
flag: {},
number: this.$store.state.number + 1
})
}
}
})
<script src="https://unpkg.com/vue@2.6.11/dist/vue.js"></script>
<script>
Vue.config.devtools = false
Vue.config.productionTip = false
</script>
<script src="https://unpkg.com/vuex@3.1.1/dist/vuex.js"></script>
<script src="https://unpkg.com/vuex-persistedstate@2.7.0/dist/vuex-persistedstate.umd.js"></script>
<div id="app">
<button @click="onReplace">Replace</button>
<p>{{ $store.state.number }}</p>
</div>