vuejsでコンポーネントの初期データをリセットする適切な方法はありますか?


92

特定の開始データのセットを持つコンポーネントがあります。

data: function (){
    return {
        modalBodyDisplay: 'getUserInput', // possible values: 'getUserInput', 'confirmGeocodedValue'
        submitButtonText: 'Lookup', // possible values 'Lookup', 'Yes'
        addressToConfirm: null,
        bestViewedByTheseBounds: null,
        location:{
            name: null,
            address: null,
            position: null
        }
}

これはモーダルウィンドウのデータなので、表示されたらこのデータから始めたいと思います。ユーザーがウィンドウからキャンセルした場合、すべてのデータをこれにリセットしたいと思います。

データをリセットするメソッドを作成して、すべてのデータプロパティを手動で元に戻すことができることはわかっています。

reset: function (){
    this.modalBodyDisplay = 'getUserInput';
    this.submitButtonText = 'Lookup';
    this.addressToConfirm = null;
    this.bestViewedByTheseBounds = null;
    this.location = {
        name: null,
        address: null,
        position: null
    };
}

しかし、これは本当にずさんなようです。つまり、コンポーネントのデータプロパティに変更を加えた場合は、resetメソッドの構造を更新することを忘れないようにする必要があります。それは小さなモジュラーコンポーネントなので、それは絶対に恐ろしいことではありませんが、それは私の脳の最適化部分を悲鳴を上げさせます。

私がうまくいくと思った解決策は、readyメソッドの初期データプロパティを取得し、その保存されたデータを使用してコンポーネントをリセットすることです。

data: function (){
    return {
        modalBodyDisplay: 'getUserInput', 
        submitButtonText: 'Lookup', 
        addressToConfirm: null,
        bestViewedByTheseBounds: null,
        location:{
            name: null,
            address: null,
            position: null
        },
        // new property for holding the initial component configuration
        initialDataConfiguration: null
    }
},
ready: function (){
    // grabbing this here so that we can reset the data when we close the window.
    this.initialDataConfiguration = this.$data;
},
methods:{
    resetWindow: function (){
        // set the data for the component back to the original configuration
        this.$data = this.initialDataConfiguration;
    }
}

しかし、initialDataConfigurationオブジェクトはデータとともに変化しています(これは、readメソッドではinitialDataConfigurationデータ関数のスコープを取得しているがあります。

スコープを継承せずに初期構成データを取得する方法はありますか?

私はこれを考えすぎていますか?これを行うためのより良い/より簡単な方法がありますか?

初期データをハードコーディングすることが唯一のオプションですか?


モーダルを表示するためにv-showまたはv-ifを使用していますか?
Rwd 2016

私はcssにブートストラップを使用しているので、表示と非表示にjqueryを利用する組み込みのモーダルを使用しています。したがって、基本的に、コンポーネントのウィンドウ部分は常にそこにあり、非表示になっています。
クリスシュミッツ

回答:


125
  1. コンポーネントの外部の関数に初期データを抽出します
  2. その関数を使用して、コンポーネントに初期データを設定します
  3. その機能を再利用して、必要に応じて状態をリセットします。

// outside of the component:
function initialState (){
  return {
    modalBodyDisplay: 'getUserInput', 
    submitButtonText: 'Lookup', 
    addressToConfirm: null,
    bestViewedByTheseBounds: null,
    location:{
      name: null,
      address: null,
      position: null
    }
  }
}

//inside of the component:
data: function (){
    return initialState();
} 


methods:{
    resetWindow: function (){
        Object.assign(this.$data, initialState());
    }
}


5
それはそれをしました。ありがとう!私は答えに小さな編集を加えましたが、それはvueコンポーネントが単なるオブジェクトではなくデータに対して返される関数を必要とするためです。あなたの回答の概念は間違いなく機能し、正しいです。編集は、vuejsがコンポーネントを処理する方法を説明するためだけのものです。
クリスシュミッツ

3
あなたはデータプロパティの関数について正しいです、それは私がだらしないことでした。編集していただきありがとうございます。
Linus Borg

13
エラーが発生するようになりました:[Vue warn]: Avoid replacing instance root $data. Use nested data properties instead.
Sankalp Singha 2016

34
@SankalpSingha Vue 2.0では、これを行うことができなくなりました。Object.assign代わりに使用できます。作業コードは次のとおり
CodinCat

3
この問題の場合-[Vue警告]:インスタンスルート$ dataの置き換えは避けてください。代わりにネストされたデータプロパティを使用して、this。$ data.propName = "newvalue";を試してください。
スタニスラフオスタペンコ2018

32

data現在のコンポーネントインスタンスのコンポーネントをリセットするには、次のことを試してください。

Object.assign(this.$data, this.$options.data())

個人的には、ダイアログのさまざまな部分を埋めるためにスロットを利用する抽象的なモーダルコンポーネントがあります。モーダルを抽象化するカスタマイズされたモーダルラップの場合、スロットで参照されるデータは親コンポーネントスコープに属します。カスタマイズされたモーダルが表示されるたびにデータをリセットする抽象モーダルのオプションは次のとおりです(ES2015コード)。

watch: {
    show (value) { // this is prop's watch
      if(value) {
        Object.assign(this.$parent.$data, this.$parent.$options.data())
      }
    }
}

もちろん、モーダル実装を微調整することもできます。上記は、いくつかのcancelフックで実行される場合もあります。

$parent子からのオプションの変更は推奨されないことに注意してください。ただし、親コンポーネントが抽象モーダルをカスタマイズするだけで、それ以上のものがない場合は正当化されると思います。


1
この手法により、VueJSの警告が表示されるようになりました。stackoverflow.com/questions/40340561/を
Kivi Shapiro

7
注意、これはコンテキストをにバインドしませんdata。あなたが使用している場合はthis、あなたにdata方法あなたとコンテキストを適用することができますObject.assign(this.$data, this.$options.data.apply(this))
IFNOT

location.reload()に対するこれらの方法の利点は何ですか?
カルロス

29

注意、Object.assign(this.$data, this.$options.data())コンテキストをdata()にバインドしません。

したがって、これを使用してください:

Object.assign(this.$data, this.$options.data.apply(this))

ccこの答えはもともとここにありました


3

警告に悩まされている場合、これは別の方法です。

const initialData = () => ({})

export default {
  data() {
    return initialData();
  },
  methods: {
    resetData(){
      const data = initialData()
      Object.keys(data).forEach(k => this[k] = data[k])
    }
  }
}

$ dataをいじる必要はありません。


2

子コンポーネント内でデータを元の状態にリセットする必要がありました。これが私にとってうまくいったことです。

親コンポーネント、子コンポーネントのメソッドの呼び出し:

     <button @click="$refs.childComponent.clearAllData()">Clear All</button >

     <child-component ref='childComponent></child-component>

子コンポーネント:

  1. 外部関数でデータを定義し、
  2. データオブジェクトの機能への割り当ておよび機能外への割り当て
  3. 親コンポーネントによって呼び出されるclearallData()メソッドを定義する

    function initialState() {
       return { 
         someDataParameters : '',
         someMoreDataParameters: ''
              }
      }
    
    export default {
       data() {
        return initialState();
      },
        methods: {
      clearAllData() {
      Object.assign(this.$data, initialState());
    },
    
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.