【问题标题】:How to update Vue component property when Vuex store state changes?Vuex store 状态变化时如何更新 Vue 组件属性?
【发布时间】:2017-01-10 20:09:40
【问题描述】:

我正在构建一个简单的演示工具,我可以使用 Vue js 和 Vuex 创建演示、命名以及添加/删除幻灯片以处理应用程序状态。一切都很顺利,但现在我正在尝试实现一项功能,该功能可检测演示文稿中的更改(标题更改或幻灯片添加/删除),但尚未找到合适的解决方案。为简单起见,我将仅提供有关标题更改的示例。现在在我的 Vuex 商店中,我有:

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

在我的演示组件中,我有:

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)
        })
    }
}

到目前为止,我所做的是在创建组件时创建演示文稿的影子副本,然后通过计算属性比较我感兴趣的属性(在本例中为标题)和如果有任何不同,则返回 true。这适用于检测更改,但我想要做的是能够在保存演示文稿时更新阴影演示文稿,到目前为止我还没有这样做。由于在另一个组件中触发了 savePresentation 操作,而且我真的不知道如何在演示组件中选择“保存”事件,因此我无法更新我的影子演示。关于如何实现此类功能的任何想法?任何帮助将不胜感激!提前致谢!

【问题讨论】:

    标签: javascript vue.js vuex


    【解决方案1】:

    我最终以与我在问题中提出的方式不同的方式解决了这个问题,但某些人可能会对此感兴趣。就这样吧:

    首先,我放弃了让我的 vue 商店将事件传递给组件,因为当你使用 vuex 时,你的所有应用程序状态都应该由 vuex 商店管理。我所做的是从

    更改演示对象结构
    {
        title: 'title',
        slides: []
    }
    

    到更复杂一点的东西,像这样

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

    presentation 是我最初拥有的简单表示对象。现在我的新演示对象有一个道具states,我将在其中放置所有演示状态,并且每个状态都有一个由字符串化的简单演示对象和实际的简单演示对象生成的散列。像这样,我将为演示文稿中的每一次更改生成一个具有不同哈希的新状态,然后我可以将我当前的状态哈希与保存的最后一个哈希进行比较。每当我保存演示文稿时,我都会将 lastSaved 属性更新为当前状态哈希。有了这个结构,我可以简单地实现撤消/重做功能,只需将状态从states 取消转换/转换到statesAhead,反之亦然,这甚至比我最初的预期要多,最后我将所有状态都由vuex 存储,而不是分散我的状态管理和污染组件。

    我希望这不会太令人困惑,并且有人会觉得这很有帮助。 干杯

    【讨论】:

    • 智能解决方案,我个人无法使用,但仍然很智能 - 干得好! :)
    • 但是为了记录,我是在两个队友的帮助下才来到这里的。学分不全是我的。
    • 很公平,适当指出:D
    【解决方案2】:

    我在尝试向我的用户状态添加新属性时遇到了这个问题,所以我最终解决了这个问题,它运行良好。

    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])
            }
          }
        }
    

    实施

    从 Vue 组件调用上面的 store 操作

    this.updateUser({emailVerified: true})
    

    对象

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

    【讨论】:

      猜你喜欢
      • 2021-12-25
      • 2021-10-28
      • 2019-03-13
      • 2020-08-04
      • 2018-03-27
      • 2019-08-06
      • 1970-01-01
      • 2019-03-20
      • 2020-09-23
      相关资源
      最近更新 更多