简体   繁体   English

当Vuex存储状态更改时,如何更新Vue组件属性?

[英]How to update Vue component property when Vuex store state changes?

I'm building a simple presentation tool where I can create presentations, name them and add/remove slides with Vue js and Vuex to handle the app state. 我正在构建一个简单的演示工具,可以在其中创建演示文稿,命名演示文稿并使用Vue js和Vuex添加/删除幻灯片以处理应用程序状态。 All is going great but now I'm trying to implement a feature that detects changes in the presentation (title changed or slide added/removed) and couldn't not yet find the right solution for it. 一切都很好,但是现在我正在尝试实现一项功能,该功能可以检测演示文稿中的更改(标题更改或幻灯片的添加/删除),但找不到合适的解决方案。 I'll give the example only concerning the title change for the sake of simplicity. 为了简单起见,我将仅给出有关标题更改的示例。 Right now in my Vuex store I have: 现在在我的Vuex商店中,我有:

const state = {
    presentations: handover.presentations, //array of objects that comes from the DB
    currentPresentation: handover.presentations[0]
}

In my Presentation component I have: 在演示组件中,我有:

export default {
    template: '#presentation',
    props: ['presentation'],
    data: () => {
        return {
            shadowPresentation: ''
        }
    },
    computed: {
        isSelected () {
            if (this.getSelectedPresentation !== null) {
                return this.presentation === this.getSelectedPresentation
            }
            return false
        },
        hasChanged () {
            if (this.shadowPresentation.title !== this.presentation.title) {
                return true
            }
            return false
        },
        ...mapGetters(['getSelectedPresentation'])
    },
    methods: mapActions({
        selectPresentation: 'selectPresentation'
    }),
    created () {
        const self = this
        self.shadowPresentation = {
            title: self.presentation.title,
            slides: []
        }

        self.presentation.slides.forEach(item => {
            self.shadowPresentation.slides.push(item)
        })
    }
}

What I've done so far is to create a shadow copy of my presentation when the component is created and then by the way of a computed property compare the properties that I'm interested in (in this case the title) and return true if anything is different. 到目前为止,我所做的是在创建组件时创建演示文稿的卷影副本,然后通过计算属性比较我感兴趣的属性(在本例中为标题),如果满足则返回true一切都不同。 This works for detecting the changes but what I want to do is to be able to update the shadow presentation when the presentation is saved and so far I've failed to do it. 这适用于检测更改,但是我想要做的是能够在保存演示文稿时更新阴影演示文稿,到目前为止,我做不到。 Since the savePresentation action triggered in another component and I don't really know how pick the 'save' event inside presentation component I fail to update my shadow presentation. 由于savePresentation操作是在另一个组件中触发的,并且我真的不知道如何在演示组件中选择'save'事件,因此无法更新我的影子演示。 Any thoughts on how I could implement such feature? 关于如何实现此功能有任何想法吗? Any help would be very appreciated! 任何帮助将不胜感激! Thanks in advance! 提前致谢!

I ended up solving this problem in a different way than what I asked in the question but it may be of interest for some. 我最终以与我在问题中所提出的问题不同的方式解决了这个问题,但是对于某些人来说可能是有趣的。 So here it goes: 所以就这样:

First I abdicated from having my vue store communicating an event to a component since when you use vuex you should have all your app state managed by the vuex store. 首先,我放弃让我的vue商店将事件传达给组件,因为当您使用vuex时,应该将所有应用程序状态都由vuex商店进行管理。 What I did was to change the presentation object structure from 我所做的是将演示对象结构从

{
    title: 'title',
    slides: []
}

to something a little more complex, like this 像这样更复杂

{
    states: [{
        hash: md5(JSON.stringify(presentation)),
        content: presentation
    }],
    statesAhead: [],
    lastSaved: md5(JSON.stringify(presentation))
}

where presentation is the simple presentation object that I had at first. presentation是我最初拥有的简单演示对象。 Now my new presentation object has a prop states where I will put all my presentation states and each of this states has an hash generated by the stringified simple presentation object and the actual simple presentation object. 现在,我的新演示文稿对象具有道具states ,我将在其中放置所有演示文稿状态,并且每个状态都具有由字符串化的简单演示文稿对象和实际的简单演示文稿对象生成的哈希。 Like this I will for every change in the presention generate a new state with a different hash and then I can compare my current state hash with the last one that was saved. 这样,我将为演示文稿中的每个更改生成一个具有不同哈希值的新状态,然后将当前状态哈希值与保存的最后一个哈希值进行比较。 Whenever I save the presentation I update the lastSaved prop to the current state hash. 每当我保存演示文稿时,我都会将lastSaved更新为当前状态哈希。 With this structure I could simple implement undo/redo features just by unshifting/shifting states from states to statesAhead and vice-versa and that's even more than what I intended at first and in the end I kept all my state managed by the vuex store instead of fragmenting my state management and polluting components. 通过这样的结构,我可以只通过unshifting /从换挡状态简单实现撤销/重做功能statesstatesAhead ,反之亦然,这就是比我打算在第一和最后我存的vuex店管理的所有我的状态更改为分散我的状态管理和污染组件。

I hope it wasn't too much confusing and that someone finds this helpful. 我希望这不会造成太多混乱,并且有人会觉得这很有帮助。 Cheers 干杯

I had this issue when trying to add new properties to my user state so I ended up with this and it works well. 尝试向用户状态添加新属性时遇到了这个问题,所以我最终解决了这个问题,并且效果很好。

Action in Vuex store Vuex商店中的操作

   updateUser (state, newObj) {
      if (!state.user) {
        state.user = {}
      }
      for (var propertyName in newObj) {
        if (newObj.hasOwnProperty(propertyName)) {
          //updates store state
          Vue.set(state.user, propertyName, newObj[propertyName])
        }
      }
    }

Implementation 实作

Call your store action above from the Vue component 从Vue组件调用上面的商店操作

this.updateUser({emailVerified: true})

Object 宾语

{"user":{"emailVerified":true},"version":"1.0.0"}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM