Data binding Vuejs 2,VUEX,编辑数据时的数据绑定

Data binding Vuejs 2,VUEX,编辑数据时的数据绑定,data-binding,vue.js,vuejs2,vue-router,vuex,Data Binding,Vue.js,Vuejs2,Vue Router,Vuex,我有一个用户配置文件部分,我试图允许用户编辑他们的信息。我正在使用vuex存储用户配置文件数据并将其拉入表单。编辑表单位于userProfile组件的子组件中,该组件加载数据保存并将其提交到VUEX 因此,我可以使用VUEX中的数据填充表单,但只要我更改表单中的任何值,它也会更改父组件中的值 在保存表单之前,我不会将更改提交到VUEX,因此这意味着数据会双向绑定到VUEX。我觉得这是不可能的。在这种情况下,不需要这样做,因为如果用户更改了某些数据,然后在没有实际单击“保存”的情况下导航离开,则数

我有一个用户配置文件部分,我试图允许用户编辑他们的信息。我正在使用vuex存储用户配置文件数据并将其拉入表单。编辑表单位于userProfile组件的子组件中,该组件加载数据保存并将其提交到VUEX

因此,我可以使用VUEX中的数据填充表单,但只要我更改表单中的任何值,它也会更改父组件中的值

在保存表单之前,我不会将更改提交到VUEX,因此这意味着数据会双向绑定到VUEX。我觉得这是不可能的。在这种情况下,不需要这样做,因为如果用户更改了某些数据,然后在没有实际单击“保存”的情况下导航离开,则数据仍然是VUEX,并且仍然会更改

注意,这是一个简化的示例。我实际上使用路由器视图来加载子组件,或者通过道具传递数据。我已经测试过直接加载编辑配置文件组件,如下所示,我也有同样的问题

请看下面的代码,我找不到为什么数据会被发送回商店。非常感谢您的帮助

在父级中,我设置如下检索用户数据:

<template>
    <div class="content">
        <h1>{{getUserDetails.firstname}} {{getUserDetails.lastname}} </h1>
        <edit-profile></edit-profile>
    </div>
</template>
<script>
    import { mapGetters } from 'vuex';
    import EditProfile from './Edit.vue';

    export default {
        data() {
            return {
                // data
            }
        },
        created () {
            this.fetchData();
        },
        components: {
            EditProfile:EditProfile
        },
        computed: mapGetters([
            'getUserDetails'
        ]),
        methods: {
            fetchData: function () {
                var _this = this;
                // ajax call - then
                _this.$store.commit('setData', {
                    name: 'userDetails',
                    data: response.data.data.userDetails
                });
            }
        }
    }
</script>
这里一切正常

在带有编辑表单的子组件中,我按如下方式填充表单:

<template>
    <form>
        <label>Name</label>
        <input name="firstname" v-model="profile.firstname">
        <input name="lastname" v-model="profile.lastname">
        <button v-on:click="save">submit</button>
     </form>
</template>

<script>
import {mapGetters } from 'vuex';

export default {
    data() {
        return {
            profile:{}
        }
    },
    watch: {
        getUserDetails (newData){
            this.profile = newData;
        }
    },
    created (){
        this.profile = this.$store.getters.getUserDetails;
    },
    computed: mapGetters([
        'getUserDetails'
    ]),
    methods:{
        save (){
            var _this = this;
            // ajax call to POST this.profile then
            _this.$store.commit('setData', {
                name: 'userDetails',
                data: this.profile
            });
        }
    }
}
</script>

名称
提交
从“vuex”导入{mapGetters};
导出默认值{
数据(){
返回{
档案:{}
}
},
观察:{
getUserDetails(新数据){
this.profile=newData;
}
},
创建(){
this.profile=this.$store.getters.getUserDetails;
},
计算:mapGetters([
“getUserDetails”
]),
方法:{
保存(){
var_this=这个;
//ajax调用发布this.profile然后
_此.$store.commit('setData'{
名称:“userDetails”,
数据:这是我的个人资料
});
}
}
}

如果您正在寻找使用vuex的非绑定解决方案,则可以克隆该对象并使用v-model的本地版本,而不是在提交或提交时使用

在创建的生命周期功能中,执行以下操作:

created (){
    this.profile = Object.assign({}, this.$store.getters.getUserDetails);
},
为什么我认为它没有按预期为您工作:您正在接收一个对象,将其绑定到本地属性。然后,当您更改该本地属性时,它将由对象指针(/memory address)绑定到存储的对象。 创建一个新对象并根据该州用户配置文件对象的属性设置该新对象的属性应该可以做到这一点,因为新对象在内存中有自己的地址,将指向另一个地方

说明:

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,
    };
},
但是如果这些属性(firstName、lastName)是对象或数组(通过指向内存地址的指针访问的任何对象),那么这也不起作用


所以。。。在这种情况下,我最有可能自己做的事情是:

data() {
    return {
        firstName: '',
        lastName: ''
    }
},
这定义了本地属性。加载数据时,将使用Vuex存储中的配置文件数据填充本地值

created() {
    let profile = this.$store.getters.getUserDetails;
    if (profile.firstName && profile.lastName) {
        this.firstName = profile.firstName;
        this.lastName = profile.lastName;
    }
},
然后,在保存时,使用局部变量更新存储的值

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
        });
    }
}
我是从头开始写的,所以这里可能有错误或打字错误。。。但我希望至少我的逻辑是正确的-P,你明白了

Pro:在您准备好保存编辑的信息之前,您不会将其反映到其他任何地方

Con:如果您需要反映临时更改(可能在用户配置文件预览区域中),这可能有效,也可能无效,具体取决于应用程序的结构。在这种情况下,您可能需要将@input绑定或保存到state.temporaryUserProfile对象


我还是Vue.js的新手,两周前开始使用它。希望这是清楚和正确的:)

问题是由于使用带有MapGetter的v-model造成的-这会创建您描述的双向绑定。简单的解决方案是使用value:

:value="profile.firstName"

通过这种方式,表单只更改字段的本地副本,而不将更改推回到Vuex存储。

@AfikDeri解决方案很好,但它只创建一个浅副本(例如,如果您有嵌套对象,它将不起作用,这是常见的),要解决此问题,您可以序列化然后解析vuex状态对象
getUserDetails
,如下所示:

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

谢谢这已经足够好了,尽管看起来应该有一种更优雅的方式来实现这一点。未来的用户,请注意,它只是简单地复制JSON。理解这里的深度与浅层复制:不,不要在Vue中使用值,用户输入的值没有绑定,对象不会更新,因此您不知道输入的值,单向绑定应该在存储和组件之间完成