2017-06-27 8 views
6

私の親ビューコンポーネントでは、私はuserオブジェクトを持っています。親データを変更せずにpropを編集するVueJS正しい方法

私は小道具として子コンポーネントへのユーザーオブジェクトことを渡す場合:

<child :user="user"></child> 

と私の子コンポーネントで、私はuser.nameを更新し、それは同様の親に更新されます。

親コンポーネントにあるユーザーオブジェクトに変更が反映されずに子コンポーネント内のユーザーオブジェクトを編集したいとします。

これを実現するには、オブジェクトをクローンするよりも良い方法がありますか?JSON.parse(JSON.stringify(obj))

答えて

11

JSONオブジェクトを使用する必要はありません。

const child = { 
    props:["user"], 
    data(){ 
    return { 
     localUser: Object.assign({}, this.user) 
    } 
    } 
} 

使用localUser(または何でもあなたはそれを呼びたい)あなたの子供の内部。

編集

私は上記のコンセプトを実証するために、この質問に別の答えのために作成したフィドルを変更していたし、@のuser3743266が

を尋ねた私はこれでグリップに自分自身を来て、そして私ですこれを見つけるのは非常に です。あなたの例はうまくいきます。子では、 という要素をデータに作成して、小道具のコピーを取り、子は をコピーします。面白くて便利ですが、... 親が 親を変更した場合、ローカルコピーが更新されるとわかりません。 v-ifsを削除して、すべてが と表示され、編集コンポーネントが複製されるように、私はあなたのフィドルを修正しました。 1つの コンポーネントで名前を変更すると、もう1つは孤立して変更されません。

現在のコンポーネントは次のようになります。私は、ユーザーのローカルコピーを使用するための設計上の決定をしたので

Vue.component('edit-user', { 
    template: ` 
    <div> 
    <input type="text" v-model="localUser.name"> 
    <button @click="$emit('save', localUser)">Save</button> 
    <button @click="$emit('cancel')">Cancel</button> 
    </div> 
    `, 
    props: ['user'], 
    data() { 
    return { 
     localUser: Object.assign({}, this.user) 
    } 
    } 
}) 

user3743266が正しい@、コンポーネントが自動的に更新されません。 プロパティuserが更新されますが、localUserは更新されません。この場合、の場合は、プロパティが変更されたときにローカルデータを自動的に更新したい場合は、ウォッチャーが必要です。

Vue.component('edit-user', { 
    template: ` 
    <div> 
    <input type="text" v-model="localUser.name"> 
    <button @click="$emit('save', localUser)">Save</button> 
    <button @click="$emit('cancel')">Cancel</button> 
    </div> 
    `, 
    props: ['user'], 
    data() { 
    return { 
     localUser: Object.assign({}, this.user) 
    } 
    }, 
    watch:{ 
    user(newUser){ 
     this.localUser = Object.assign({}, newUser) 
    } 
    } 
}) 

ここでは、fiddleが更新されています。

これにより、ローカルデータが更新または発行される時期を完全に制御できます。たとえば、ローカル状態を更新する前に条件をチェックすることができます。

watch:{ 
    user(newUser){ 
     if (condition) 
     this.localUser = Object.assign({}, newUser) 
    } 
    } 

私が他の場所で述べたように、あなたは、オブジェクトのプロパティが変更可能であることの利点を活用することがあります時間がありますが、あなたはより多くの制御が必要になる場合があります。このような時もあります。

+0

@ user3743266いくつかの説明を追加しました。 – Bert

+1

とてもいいです。とても面白かったです。ありがとうございました。 Vueは私のおばあちゃんを揺るがす。私はEvanあなたが現実には30人のロケット科学者のチームであると思います。 – bbsimonbb

+1

本当ですか?私は、このスレッドとあなたの答えは、価値のトンを持っていると言うでしょう。このような質問は、vueを使用するすべての人に潜在的に関連しています。それを残すと、長くて驚くべき人生を送ることができます。 – bbsimonbb

0

According to thisの場合、子供は親のデータを変更することはできません。しかしhereの場合、親が子としてプロパティとして反応データを渡すと、それは参照渡しであり、親は子の変更を見ることがわかります。これはおそらくほとんどの時間を必要としているのですか?親が明示的に共有しているデータのみを変更しています。子供にuserの独立したコピーを持たせたい場合は、JSON.parse(JSON.stringify())でこれを行うことができますが、Vue注入プロパティをシリアル化することに注意してください。あなたはいつそれをしますか?小道具は反応的であることを覚えておいてください。親はいつでも新しいユーザーを送って、ローカルの変更を一掃できますか?

おそらく、子供に自分のコピーを持たせたい理由を教えてください。子供はそのコピーで何をしようとしていますか?子のユーザが親のユーザから体系的に導出された場合(すべてのテキストまたは何かを大文字にする)、計算されたプロパティを見てください。

+1

ほとんどの場合、あなたが望むものではありません。プロパティ値が変更された場合、ローカルデータは消去されません(特にそうしない限り)。子に変更を加えることを望まない理由はいくつでもあります*親に反映される* 。誰かが変更をキャンセルしたい場合を考えてみましょう。プロパティで渡されたデータを変更する場合は、これらの変更をすべて取り消すための追加の解決策が必要です。最初にコピーを作成し、$を出したときにのみ親に変更を加えると、いつでもキャンセルできます。 – Bert

+0

あなたは、データが消去されないと言っていますが、反応するデータを子供にプロパティとして渡すと、これは私の[jsfiddle](https://jsfiddle.net/bbsimonbb/32xoy9Lw/7/)で行われます。親と子は一つの真実を共有していますか?元に戻すシナリオをどのように実装しますか? – bbsimonbb

+0

私はデータのプロパティと同じように* data *と言っていましたが、プロパティ自体はそうではありませんでした。私はあなたの[フィドル](https://jsfiddle.net/32xoy9Lw/10/)を更新しました。子供が意図したときだけ変更を出すため、子供の変更を簡単に取り消すことができます。ユーザープロパティを直接編集してキャンセルする場合は、元の状態を保存して復元する必要があります。私は便利だとあなたに同意する*あなたはオブジェクトと配列のプロパティを変更することができますが、* maintainable *も少なくなります。プロパティを変更するときは注意が必要です。あなたのデフォルトであってはなりません。 – Bert

0

は、あなたはちょうどあなたがローカルで編集可能と作成方法

data() { 
return { localUserData: {name: '', (...)} 
} 
(...) 
created() { 
    this.localUserData.name = this.user.name; 
} 

にあなたが編集しているデータの明確なそれを維持する。この方法は値をロードしたい情報とデータ変数を持つことができます。必要に応じて、ユーザーの小道具が変更された場合にlocalDataを更新するウォッチャーが必要な場合があります。

関連する問題