vueのデータページを変更して再レンダリングしない問題を解決します(Vueの配列とオブジェクトが変更された後、ビューがリフレッシュされません)


vueレンダリングメカニズムとデータ修正ページが更新されない問題を解決する方法
本文は原理を言わないで、ただ乾物が分かりやすくて学びやすいことを話して、(知識を学ぶことができると感じて、面倒に編集者にほめてもらいます!)
まず第一に、vueの下部はdataオブジェクトを人に伝える、Objectを使用する.definePropetyは、getterとsetterに変換するので、vueはIE 8をサポートしない.
1.Objectを簡単に紹介します.definePropety,
Object.defineProperty(obj, prop, descriptor)
//  
obj
           。
prop
            。
descriptor
             
  var obj = {}
  Object.defineProperty(obj, 'name', {
    get: function() {
      console.log('     '+name);
      return name;
    },
    set: function(value) {
      console.log('  '+value)
      name = value;
    }
  });
    obj.name ='  ';//    
    obj.name//       

上記から簡単に発見できます.このオブジェクトのname属性に値を割り当てるとsetメソッドがトリガーされ、name属性を取得するとgetメソッドがトリガーされます.
  • そのためvueにdataに書かれている属性はgetterとsetterに変換できます.言い換えれば応答式です.他の定義がdata以外のデータは、応答できないレンダリングです.データページを変更してもリフレッシュされないことを意味します.だから、ページにレンダリングするデータは、dataに書かなければなりません.必要ではありません.thisに定義できます.
    var vm = new Vue({
      data:{
        a:1
      }
    })
    
    // `vm.a`      
    
    vm.b = 2
    // `vm.b`       
    
    3.簡単に説明すると、リフレッシュしない例をいくつか挙げます.もちろん、上記も1つ目です.オブジェクトの属性vueを変更すると、dataで宣言する属性だけが応答になります.宣言しないのは応答しない
    <template>
      <div>
          <div v-for='item in list'>{{item}}</div>
          <button @click='click'>  </button>
          <button @click='hadelClick'>    </button>
      </div>
    </template>
    <script>
      export default({
        data(){
          return{
            list:{a:'a',b:'b'},
          }
        },
        methods: {
              click() {
              //          
               this.list.c='c'
    
              },
              hadelClick(){
                //     ,  vue   $set       
                this.$set(this.list,'d','d')
              }
            }
      })
       
    </script>
    
    です.もちろん、複数の属性を追加する場合はObjectを使用します.assign()は、すべての列挙可能な属性の値を1つ以上のソースオブジェクトからターゲットオブジェクトにコピーし、ターゲットオブジェクトに戻るために使用されます.(簡単に言えば、第1のパラメータにマージされる)
    this.list = Object.assign({},this.list,{c:'c',d:'d'})
    
    第2のタイプ:配列オブジェクトの属性
    <template>
      <div>
          <div v-for='item in list'>{{item.a}}</div>
          <button @click='click'>  </button>
          <button @click='hadelClick'>    </button>
      </div>
    </template>
    <script>
      export default({
        data(){
          return{
            list:[{a:'vue'},{a:'react'},{a:'js'}],
          }
        },
        methods: {
              click() {
                //                   ,        (      ,     )
                this.list[0] = {a:'css'} //     
                console.log(this.list)  //[{a:'css'},{a:'react'},{a:'js'}]
              },
              hadelClick(){
                //     ,  vue   $set       
                this.$set(this.list[1],'a','css')
                console.log(this.list)//[{a:'css'},{a:'css'},{a:'js'}]
              }
            }
      })
       
    </script>
    
    を変更する前に述べたように、vueはdataのデータを遍歴し、オブジェクトをsetterとgetterに変換します.したがって、配列の中でも例外ではないので、上記の操作
    click(){
    	this.list[0].a = css //      setter。        
        }
    }
    
    はvueの中で配列の操作がリフレッシュされないことが多く、1つはインデックスによって値を付与することであり、1つは配列の長さを修正することであり、どのように解決するのか.vue公式にもメソッド配列のAPIが与えられ、元の配列を変えることができるものは更新をトリガーすることができる.
  • push()
  • pop()
  • shift()
  • unshift()
  • splice()
  • sort()
  • reverse()

  • 2つ目は、新しい配列を返すことであり、この配列は参照アドレスに根本的に変更され、このような付与操作は更新をトリガすることができる(これはリフレッシュしない構想を処理し、参照アドレスを変更し、更新を再付与することである)簡単に言えば、配列のAPIは元の配列で変更を直接受信する配列であり、
      <template>
      <div>
          <div v-for='item in list'>{{item.a}}</div>
          <button @click='click'>     </button>
          <button @click='hadelClick'>      </button>
      </div>
    </template>
    <script>
      export default({
        data(){
          return{
           list:[{a:'vue'},{a:'react'},{a:'js'}],
          }
        },
        methods: {
              click() {
               //        
                  this.list.push({a:'css'})
              },
              hadelClick(){
            //              
                this.list =  this.list.map(item=>{
                      item.a = 'css'
                      return item
                    })
            }
      })
       
    </script>
    
    最後に解決策(以上が定まらない場合)を提供する対象と配列はすべて引用伝達であり、新しい配列になるには、ソースを変更する必要があり、第1種
    let arr = []//   
    this.list.forEach(item=>{  //       
        //      ,     arr 
        arr.push(item)
    })
    this.list = arr //                
    
    第2種
    //              ,     
    //    :
    let arr = this.list.slice(0);//   ,(        )
    arr.forEach(item=>{
        //      
    })
    //    
    this.list =  arr
    
    もちろん、ここでは簡単に説明しますが、深いコピーの詳細については、別のブログjs配列の深いコピーを参照してください.上記の詳細は実行できませんが、データが不足して修正されている場合は、this.$forceUpdate()メソッド(強制リフレッシュ)
    //this.$forceUpdate();//    
    
    
    <template>
      <div>
          <div v-for='item in list'>{{item.a}}</div>
          <button @click='click'>  </button>
          <button @click='hadelClick'>    </button>
      </div>
    </template>
    <script>
      export default({
        data(){
          return{
            list:[{a:'vue'},{a:'react'},{a:'js'}],
          }
        },
        methods: {
              click() {
                this.list[0] = {a:'css'} //     
                console.log(this.list)  //[{a:'css'},{a:'react'},{a:'js'}]
              },
              hadelClick(){
                this.list[0] = {a:'css'} //     
                console.log(this.list)  //[{a:'css'},{a:'react'},{a:'js'}]
                  this.$forceUpdate();//    
              }
            }
      })
       
    </script>