Vuejs 2, VUEX, data-binding when editing data

前端 未结 4 1183
情书的邮戳
情书的邮戳 2020-12-29 13:26

I have a user profile section and Im trying to allow the user to edit their information. I am using vuex to store the user profile data and pulling it into the form. The e

相关标签:
4条回答
  • 2020-12-29 13:55

    If you are looking for a non binding solution with vuex you can clone the object and use the local version for v-model than on submit commit it.

    in your created lifecycle function do this:

    created (){
        this.profile = Object.assign({}, this.$store.getters.getUserDetails);
    },
    
    0 讨论(0)
  • 2020-12-29 13:57

    The problem is caused by using v-model with mapGetters - this creates the two-way binding you've described. The simple solution is to use value instead:

    :value="profile.firstName"
    

    This way the form is only changing the local copy of field and not pushing the changes back to the Vuex store.

    0 讨论(0)
  • 2020-12-29 14:03

    @AfikDeri solution is great, but it only create a shallow copy(for example it wont work if you have nested objects, which is common to have), to solve this you may serialize then parse your vuex state object getUserDetails, as follow:

    created (){
        this.profile = JSON.parse(JSON.stringify(this.$store.getters.getUserDetails));
    }
    
    0 讨论(0)
  • 2020-12-29 14:09

    Why I think it is not working as expected for you: you're receiving an object, binding it to a local property. Then when you change that local property, it's bound by object pointer (/memory address) to the store's object. Creating a new object and setting the properties on that new object based on the properties of the state's user profile object should do the trick, since the new object would have it's own address in memory, would point to another place...

    Illustration:

    created (){
        // create a new object with {...}
        this.profile = {
            // assign values to properties of same name
            firstName: this.$store.getters.getUserDetails.firstName,
            lastName: this.$store.getters.getUserDetails.lastName,
        };
    },
    

    However if those properties (firstName, lastName) are objects or arrays (anything accessed by pointer to memory address) then this wouldn't work either.


    So... what I'd most likely end up doing myself in this situation is something like this:

    data() {
        return {
            firstName: '',
            lastName: ''
        }
    },
    

    This defines local properties. When loading the data, you would populate the local values with profile data you have in the Vuex store.

    created() {
        let profile = this.$store.getters.getUserDetails;
        if (profile.firstName && profile.lastName) {
            this.firstName = profile.firstName;
            this.lastName = profile.lastName;
        }
    },
    

    Then, when saving, you use your local variables to update the store's values.

    methods: {
        save() {
            let profile = {
                firstName: this.firstName,
                lastName: this.lastName
            };
    
            // ajax call to POST this.profile then
            this.$store.commit('setData', {
                name: 'userDetails',
                data: profile
            });
        }
    }
    

    I'm writing this from the top of my head, so there might be a bug or typo in here... But I hope at the very least my logic is correct ;-P and clear to you.

    Pro: until you're ready to save the edited information, you're not reflecting it anywhere else.

    Con: if you'd need to reflect temporary changes (maybe in a User Profile Preview area), this might or might not work depending on your app's structure. You might want to bind or save on @input to a state.temporaryUserProfile object in that case?

    I am still new to Vue.js, started using it 2 weeks ago. Hope this is clear and correct :)

    0 讨论(0)
提交回复
热议问题