admin管理员组

文章数量:1434924

After a successful mutation to the vuex store (state.posts.postments) using this code, and using Vue.set so Vue can recognize the addition of an object property:

store/modules/post.js

const mutations = {
    [types.SET_POST_COMMENTS] (state, { ments, id }) {
      let post = state.posts.find(post => post._id === id)
      Vue.set(post, 'ments', ments)
    }
}

There is no update to the template or ponent. The prop post is non-reactive (I assume because even the watcher isn't triggered). I've double checked and the Vuex store for each post's ments property is successfully being updated with a ments object, but the ponent SinglePost.vue doesn't see these changes.

SinglePost.vue

export default {
  name: 'single-post',
  props: {
    'post': {
      type: Object
    }
  },
  data () {
    return {
      currPost: this.post // tried to reassign post locally
    }
  },
  puted: {
    ments() {
      return this.postments // tried to pute ments locally
    }
  },
  watch: {
    post: function(val) { // tried to watch currPost for changes
       console.log('never triggered')
       this.currPost = val 
    }
  }

Ultimately, I can just set a local var by explicitly returning ments from the store to a ponent method and setting a local ments object, but I want to use my central store (and assume there'd be a way).

SinglePost template

{{ments}} // always empty
{{post}} // doesn't reflect store Vue.set for postments
{{currPost}} // doesn't reflect store Vue.set for postments

Edit

How I'm getting posts is:

getPosts ({ mit, state, getters, dispatch, rootState }, ctx) {
  //other stuff
  APIHelper.post('/post/search', mergedPayload).then(res => {
    var results = res.data.results
    mit('SET_POSTS', posts || [])
    // where SET_POSTS is just state.posts = posts

the vuex action getPosts is called from Posts.vue ponent without returning anything since it's set by a mutation @click="getPosts(this.context)" (this works great for setting the posts)

    <div v-for="post in posts">
      <single-post :key="post._id" :post="post" context="feed" />
    </div>

After a successful mutation to the vuex store (state.posts.post.ments) using this code, and using Vue.set so Vue can recognize the addition of an object property:

store/modules/post.js

const mutations = {
    [types.SET_POST_COMMENTS] (state, { ments, id }) {
      let post = state.posts.find(post => post._id === id)
      Vue.set(post, 'ments', ments)
    }
}

There is no update to the template or ponent. The prop post is non-reactive (I assume because even the watcher isn't triggered). I've double checked and the Vuex store for each post's ments property is successfully being updated with a ments object, but the ponent SinglePost.vue doesn't see these changes.

SinglePost.vue

export default {
  name: 'single-post',
  props: {
    'post': {
      type: Object
    }
  },
  data () {
    return {
      currPost: this.post // tried to reassign post locally
    }
  },
  puted: {
    ments() {
      return this.post.ments // tried to pute ments locally
    }
  },
  watch: {
    post: function(val) { // tried to watch currPost for changes
       console.log('never triggered')
       this.currPost = val 
    }
  }

Ultimately, I can just set a local var by explicitly returning ments from the store to a ponent method and setting a local ments object, but I want to use my central store (and assume there'd be a way).

SinglePost template

{{ments}} // always empty
{{post}} // doesn't reflect store Vue.set for post.ments
{{currPost}} // doesn't reflect store Vue.set for post.ments

Edit

How I'm getting posts is:

getPosts ({ mit, state, getters, dispatch, rootState }, ctx) {
  //other stuff
  APIHelper.post('/post/search', mergedPayload).then(res => {
    var results = res.data.results
    mit('SET_POSTS', posts || [])
    // where SET_POSTS is just state.posts = posts

the vuex action getPosts is called from Posts.vue ponent without returning anything since it's set by a mutation @click="getPosts(this.context)" (this works great for setting the posts)

    <div v-for="post in posts">
      <single-post :key="post._id" :post="post" context="feed" />
    </div>
Share Improve this question edited Feb 6, 2018 at 21:36 Kyle Cureau asked Feb 6, 2018 at 19:40 Kyle CureauKyle Cureau 19.4k23 gold badges77 silver badges104 bronze badges 6
  • Can you show how you're retrieving the post object from the store and passing it to the ponent as the prop? – thanksd Commented Feb 6, 2018 at 21:18
  • @thanksd, i updated my post with an "Edit" -- basically posts (contains many post objects) are set on the store, iterated over with v-for in Posts.vue where each post is passed as a prop to SinglePost.vue (i've gotten it to work by retrieving and setting ments in SinglePost, but not using the vuex store) – Kyle Cureau Commented Feb 6, 2018 at 21:39
  • In that v-for, where / how is the data for posts being set? – thanksd Commented Feb 6, 2018 at 21:44
  • @thanksd, it's set in the SET_POSTS mutation in the vuex store with state.posts = payload called from the getPosts action. The getPosts action is dispatched by the action handler getPosts attached to a click event (@click="getPosts(this.context)") in Posts.vue — in brief, posts is set in the vuex store, not in the ponent – Kyle Cureau Commented Feb 6, 2018 at 21:59
  • I mean how are you accessing the value of those posts from your ponent? Do you have a getter set up? Are you using mapGetters? – thanksd Commented Feb 6, 2018 at 22:03
 |  Show 1 more ment

2 Answers 2

Reset to default 4

You should use vuex's mapGetters helper method.

puted: {
    ...mapGetters({
        currPost: 'GET_CURRENT_POST'
    })
},

It gives access to store state and is reactive so you won't need watchers or additional puteds.

Two-way data binding is a great way to achieve this, you can create your own getter/setter method and import it in your Vue ponents whenever you need it:

export function mapFields(fields)
{
    let puters = {}
    for (let field of fields) {
        puters[field] = {
            get() {
                return this.$store.state[field];
            },
            set(value) {
                this.$store.mit(`UPDATE_${field.toUpperCase()}`, value);
            }
        }
    }
    return puters;
}

Then in your Vue ponent:

import {mapFields} from 'utils.js'; // or whatever the name of the file

puted: {
   ...mapFields(['mappedState']),
},

Updating this.mappedState in your Vue ponent:

this.mappedState = ['foo', 'bar'];

will trigger:

this.$store.mit('UPDATE_MAPPEDSTATE', ['foo', 'bar']);

And to get the property's data just call it in your ponent:

// In your template
{{ mappedState }}

// In Vue methods
this.mappedState;

本文标签: javascriptUpdate prop property when vuex store changesStack Overflow