web-dev-qa-db-ja.com

Vue.jsで親と孫の間で双方向のデータバインディングを行う方法

私は問題に直面し、クッキーで解決しましたが、クッキーなしで問題を解決したいと思います。 app-headerというコンポーネントがあり、outmodalという別のコンポーネントがあります。さて、私の最初のVueインスタンスにはコンポーネントapp-headerが必要です。

var vue = new Vue({
    el : "html",
    data : {
        title       : "Site Title",
        description : "description of page",
        keywords    : "my keywords",
        view        : "home",
        login       : "login"
    },
    components:{
        "app-header" :require("../../components/header"),
        "app-footer" :require("../../components/footer"),
        "home"       :require("../../views/home")
    },
});

アプリヘッダーのコード

var Vue     = require("vue");

Vue.partial("login",require("../../partials/login.html"));
Vue.partial("logged",require("../../partials/logged.html"));

module.exports = {
    template    : require("./template.html"),
    replace     : true,
    components  : {
        outmodal : require("../outmodal")
    },
    props : ['login']
}

アウトモーダルのコード

var Vue = require("vue");
Vue.partial("loginModal",require("../../partials/loginModal.html"));

module.exports = {
    template    : require("./template.html"),
    replace     : true,
    props       : ['name'],
    data        : function () {
            return  {
                userLogin : { mail  :   "", password    :   "", remember    :   ""}
            }

    },
    methods : {
        formSubmit : function(e){
                e.preventDefault();
                this.$http.post("http://example.com/auth/login",{ "email": this.userLogin.mail , "password": this.userLogin.password },function(data,status,request){
                    $.cookie("site_token",data.token,{expires : 1})
                }).error(function(data,status,request){

                });

        }
    }, ready  : function(){
        console.log("it works")
    }
}

アウトモーダルコンポーネントでは、APIに接続してログインを確認します。ログインが成功する場合は、Vueインスタンスでログイン変数の値を変更します。したがって、これらのファイル間でデータバインディングを行う方法はわかりません。

どうすれば解決できますか?私

24

私が見つけたベストソリューション

0.12の場合

http://012.vuejs.org/guide/components.html#Inheriting_Parent_Scope

1.0の

http://v1.vuejs.org/guide/components.html#Parent-Child-Communication

2.0の

https://vuejs.org/v2/guide/components.html#Composing-Components (親から子への一方向のバインドに小道具を使用)

17

それを行うにはいくつかの方法がありますが、他の答えで言及されているものもあります:

  1. コンポーネントの小道具 を使用します
  2. v-model attribute を使用します
  3. sync modifier を使用します
  4. Vuex を使用

双方向バインディングの場合、ドキュメントから引用されている、維持が困難な一連の突然変異を引き起こす可能性があることに留意してください。

残念ながら、真の双方向バインディングはメンテナンスの問題を引き起こす可能性があります。子コンポーネントは、親と子の両方で明白な突然変異のソースなしで親を突然変異させることができるためです。

使用可能なメソッドの詳細は次のとおりです。

1。)コンポーネントに小道具を使用する

小道具は使いやすく、最も一般的な問題を解決する理想的な方法です。
how Vue変更を監視する =すべてのプロパティはオブジェクトで使用可能である必要があります。そうでない場合、それらはリアクティブではありません。 Vueはそれらを観察可能にし終わった 'set' を使用する必要があります。

 //Normal usage
 Vue.set(aVariable, 'aNewProp', 42);
 //This is how to use it in Nuxt
 this.$set(this.historyEntry, 'date', new Date());

オブジェクトはコンポーネントと親の両方に反応します:

オブジェクト/配列を小道具として渡すと、双方向の同期が自動的に行われます。子のデータを変更し、親のデータを変更します。

Propsを介して単純な値(文字列、数値)を渡す場合、 。sync修飾子 を明示的に使用する必要があります

-> https://stackoverflow.com/a/35723888/1087372 から引用したとおり

2。)v-model属性を使用

V-model属性は、親と子の間の簡単な双方向バインディングを可能にする構文糖衣です。同期修飾子が行うのと同じことを行い、バインディングに特定の小道具と特定のイベントを使用します

この:

 <input v-model="searchText">

これと同じです:

 <input
   v-bind:value="searchText"
   v-on:input="searchText = $event.target.value"
 >

ここで、小道具はvalueであり、イベントはinputでなければなりません

3。)sync修飾子を使用します

同期修飾子も構文シュガーであり、v-modelと同じです。ただし、使用されているものによってプロップとイベントの名前が設定されるだけです。

親では、次のように使用できます。

 <text-document v-bind:title.sync="doc.title"></text-document>

子からイベントを発行して、親に変更を通知できます。

 this.$emit('update:title', newTitle)

4。)Vuexを使用

Vuexは、すべてのコンポーネントからアクセス可能なデータストアです。変更をサブスクライブできます。

Vuexストアを使用すると、データ変更のフローを簡単に確認でき、明示的に定義されます。 vue developer tools を使用することにより、変更を簡単にデバッグおよびロールバックできます。

このアプローチにはもう少し定型的なものが必要ですが、プロジェクト全体で使用すると、変更がどこからどのように行われるかを定義するはるかにクリーンな方法になります。

スタートガイド を参照してください

4
SanBen

これがより正確であることがわかりました。 https://vuejs.org/v2/guide/components.html#sync-Modifier 2.3.0以降のみ。正直なところ、まだ十分ではありません。 「双方向」データバインディングの簡単なオプションである必要があります。したがって、これらのオプションはどれも優れていません。

代わりにvuexを使用してみてください。それらには、そのような目的のためのより多くのオプションがあります。 https://vuex.vuejs.org/en/state.html

2
Martian2049