У меня есть следующий модуль магазина:
const state = {
user: {}
}
const mutations = {
saveData(state, payload) {
state.user = payload
}
}
const actions = {
async loadData({ commit }, payload) {
try {
const res = await axios.get('https://api.example.com/user/1')
commit('saveData', res.data.data)
} catch(e) {
console.info(e)
}
}
}
const getters = {
getData(state) {
return state.user
}
}
Как лучше всего сохранить данные в компоненте? Он использует watch
import { mapGetters } from 'vuex'
export default {
data() {
return {
user: {}
}
},
computed: {
...mapGetters({
getData
})
},
watch: {
'$store.state.users.users'() {
this.user = this.getData
}
}
}
... или store.subscribe?
import { mapGetters } from 'vuex'
export default {
data() {
return {
user: {}
}
},
computed: {
...mapGetters({
getData
})
},
created() {
this.$store.subscribe((mutation, state) => {
if (mutation.type === 'saveData') {
this.user = this.getData
}
})
}
}



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Предпочтительно использовать свойства computed для доступа к данным хранилища и поддержания их активности.
Можно создать вычисляемое свойство с помощью mapGetters, как вы это делаете в общем фрагменте, однако, учитывая, что получатель просто возвращает user из состояния, я не думаю, что вам вообще нужен получатель, вы можете просто сопоставить значение из состояние с помощью помощника mapState. Таким образом, компонент можно упростить примерно до следующего:
import { mapState } from 'vuex'
export default {
computed: {
...mapState([
'user'
])
}
}
При использовании вышеуказанного подхода вы можете ссылаться на пользователя как this.user в методах компонента или просто как на user в шаблоне компонента. Кроме того, поскольку геттер больше не используется, вы можете удалить определение получателя из хранилища (если вы не используете его где-либо еще).
Поскольку вы уже знаете о отображении магазинов, я полагаю, вы пытаетесь создать какую-то форму редактирования, в которой вам нужны фактические данные, взятые из базы данных, а также возможность изменить эти данные, чтобы позже отправить их обратно в базу данных.
Вам не нужен получатель, чтобы иметь простую ссылку на товар в магазине. Вам будет очень хорошо с mapState в вашем компоненте:
{
computed: {
...mapState({
user: state => state.user,
}),
}
}
Итак, как только user сменится в магазине, ваш компонент узнает об этом. А здесь вы можете обновить редактируемый объект. Давайте переименуем его в edit, чтобы избежать коллизии:
{
data() {
return {
edit: {},
}
},
computed: {
...mapState({
user: state => state.user,
}),
},
watch: {
user: {
immediate: true,
handler(user) {
this.edit = { ...user }
},
},
},
}
Теперь edit обновляется соответствующим образом, даже если компонент был смонтирован после обновления элемента магазина (благодаря опции immediate), и вы можете безопасно изменить его в своем компоненте без какого-либо влияния на ссылку магазина.
P.S. Следует упомянуть, что в этой реализации, если вы хотите иметь реактивность для полей в объекте edit, вам необходимо обновлять весь объект edit при каждом обновлении его поля следующим образом: this.edit = {...this.edit, [prop]: value}. Но если вы хотите, чтобы это был естественный способ Vue, то сначала вам нужно инициализировать edit с реальной структурой объектов, а в наблюдателе для user выполнить что-то вроде Object.assign(this.edit, user).
Спасибо вам за разъяснение! Теперь вопрос, когда использовать store.subscribe()? Вы можете мне привести пример?
Вы используете его, когда вам нужно знать о какой-либо магазинной мутации. По правде говоря, я никогда этим не пользовался. Предположим, это может быть полезно, когда вам нужно отреагировать, когда многие элементы магазина могут измениться, но я обычно просто объединяю их в один объект и наблюдаю за ним.
Попался! Спасибо
Вы должны просто использовать Computed, потому что он будет меняться всякий раз, когда изменяется значение в магазине.