• <var id="gzb7d"><strong id="gzb7d"></strong></var>
    <td id="gzb7d"></td>

    1. <acronym id="gzb7d"></acronym>
      瀏覽器部落:-綠色安全純凈官方版!

      Vue中用props給data賦初始值時遇到的問題及處理辦法

      時間:2021-3-25作者:未知來源:瀏覽器部落人氣:

      網頁的本質就是超級文本標記語言,通過結合使用其他的Web技術(如:腳本語言、公共網關接口、組件等),可以創造出功能強大的網頁。因而,超級文本標記語言是萬維網(Web)編程的基礎,也就是說萬維網是建立在超文本基礎之上的。超級文本標記語言之所以稱為超文本標記語言,是因為文本中包含了所謂“超級鏈接”點。
      本篇文章給大家帶來的內容是關于Vue中用props給data賦初始值時遇到的問題及解決方法,有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。

      前段時間做一個運營活動的項目,上線后產品反饋頁面埋點不對,在排查過程中發現,問題竟然是由于Vue中的data初始值導致,而data的初始值來自于props。為方便描述,現將問題抽象如下:

      一、現象

      代碼:

      <!DOCTYPE html>
      <html>
      <head>
          <meta charset="UTF-8">
          <title>用props初始化data中變量</title>
          <script src="https://cdn.bootcss.com/vue/2.5.16/vue.min.js"></script>
      </head>
      <body>
      <div id="app">
          <user-info :user-data="user"></user-info>
      </div>
      <script>
          //全局組件
          let userInfo = Vue.component('userInfo' ,{
              name: 'user-info',
              props: {
                  userData: Object
              },
              data() {
                return {
                    userName: this.userData.name
                }
              },
              template: `
                  <div>
                      <div>姓名:{{userName}}</div>
                      <div>性別:{{userData.gender}}</div>
                      <div>生日:{{userData.birthday}}</div>
                  </div>
              `
          });
      
          //Vue實例
          new Vue({
              el: '#app',
              data: {
                  user: {
                      name: '',
                      gender: '',
                      birthday: ''
                  }
              },
              created(){
                 this.getUserData();
              },
              methods:{
                  getUserData(){
                      setTimeout(()=>{
                          this.user = {
                              name: '于永雨',
                              gender: '男',
                              birthday: '1991-7'
                          }
                      }, 500)
                  }
              },
              components: {
                  userInfo
              }
          });
      </script>
      </body>
      </html>

      代碼解讀:

      1. 根組件data中有一個對象:user,包含三個屬性:name、gender、birthday,初始值都為空字符串

      2. 模擬api異步請求,500毫秒后對user的重新賦值,三個屬性都不再為空

      3. 聲明一個子組件userInfo,props中有一個對象userData,用于接收父組件的user;data中有一個變量userName,初始值來自于userData.name

      結果:

      868320973-5bf9e66f0cf35_articlex.jpg

      頁面初始化后,姓名、性別、生日都顯示為空,500毫秒后性別和生日顯示正常結果,僅姓名沒有變化。

      為什么會這樣呢?

      我最初的想法:user.name是String,屬于基本數據類型,用它給子組件data中userName賦值,屬于基本數據類型賦值,所以當父組件中user.name變化時,子組件中userName并不會隨之變化。

      是這樣的嗎?于是我決定將user.name改為對象,通過引用數據類型賦值,然后觀察是否符合預期。代碼如下:

      <!DOCTYPE html>
      <html>
      <head>
          <meta charset="UTF-8">
          <title>用props初始化data中變量-對象形式</title>
          <script src="https://cdn.bootcss.com/vue/2.5.16/vue.min.js"></script>
      </head>
      <body>
      <div id="app">
          <user-info :user-data="user"></user-info>
      </div>
      <script>
          //全局組件
          let userInfo = Vue.component('userInfo' ,{
              name: 'user-info',
              props: {
                  userData: Object
              },
              data() {
                return {
                    userName: this.userData.name
                }
              },
              template: `
                  <div>
                      <div>姓名:{{userName.text}}</div>
                      <div>性別:{{userData.gender}}</div>
                      <div>生日:{{userData.birthday}}</div>
                  </div>
              `
          });
      
      
          //Vue實例
          new Vue({
              el: '#app',
              data: {
                  user: {
                      name: {text: ''},
                      gender: '',
                      birthday: ''
                  }
              },
              created(){
                 this.getUserData();
              },
              methods:{
                  getUserData(){
                      setTimeout(()=>{
                          this.user = {
                              name: {text: '于永雨'},
                              gender: '男',
                              birthday: '1991-7'
                          }
                      }, 500)
                  }
              },
              components: {
                  userInfo
              }
          });
      </script>
      </body>
      </html>

      運行結果:姓名仍然沒有值,和第一次結果一樣!!!

      二、原因

      那么,原因到底是什么呢?百思不得解,后來和小伙伴們討論時,有人提出:會不會因為data在初始化時深拷貝?

      我覺得這種解釋比較靠譜,于是去收集證據,首先去Vue官網翻了一下關于data的文檔,其中:

      434540271-5bfbb5132e9c1_articlex.png

      當看到"遞歸地"那個詞,基本上就能斷定上面的推論是正確的,因為深拷貝的核心原理就是遞歸

      原來,Vue初始化時會遞歸地遍歷data所有的屬性,并使用Object.defineProperty把這些屬性全部轉為getter/setter,用于實現雙向綁定。官方文檔在Reactivity in Depth一章明確有說:

      2191340175-5bfbb8747f671_articlex.png

      還順便解釋了一下為什么Vue不支持IE8的原因:IE8不支持Object.defineProperty。

      三、解決辦法

      既然因為data深拷貝的原因,data無法隨著props的變化而更新,我們很自然的就想到Vue中有監聽作用的兩個功能:watch、computed
      修改代碼如下,觀察結果:

      <!DOCTYPE html>
      <html>
      <head>
          <meta charset="UTF-8">
          <title>解決方案:watch、computed</title>
          <script src="https://cdn.bootcss.com/vue/2.5.16/vue.min.js"></script>
      </head>
      <body>
      <div id="app">
          <user-info :user-data="user"></user-info>
      </div>
      <script>
          //全局組件
          let userInfo = Vue.component('userInfo' ,{
              name: 'user-info',
              props: {
                  userData: Object
              },
              data() {
                return {
                  userName: this.userData.name
                }
              },
              computed: {
                  computedUserName(){
                      return this.userData.name
                  }
              },
              watch: {
                  'userData.name': function (val) {//監聽props中的屬性
                      this.userName = val;
                  }
              },
              template: `
                  <div>
                      <div>姓名(watch):{{ userName }}</div>
                      <div>姓名(computed):{{ computedUserName }}</div>
                      <div>性別:{{ userData.gender }}</div>
                      <div>生日:{{ userData.birthday }}</div>
                  </div>
              `
          });
      
      
          //Vue實例
          new Vue({
              el: '#app',
              data: {
                  user: {
                      name: '',
                      gender: '',
                      birthday: ''
                  }
              },
              created(){
                 this.getUserData();
              },
              methods:{
                  getUserData(){
                      setTimeout(()=>{
                          this.user = {
                              name: '于永雨',
                              gender: '男',
                              birthday: '1991-7'
                          }
                      }, 500)
                  }
              },
              components: {
                  userInfo
              }
          });
      </script>
      </body>
      </html>

      運行結果

      1450334126-5bfbc2256a927_articlex.png

      完美!!!

      四、總結:關于Vue中props的要點

      事后又仔細翻了一下關于props的文檔:

      246091987-5bfbbb263f05f_articlex.png

      大概梳理一下:

      1.props是單向數據流:父組件的數據變化,通過props實時反應在子組件中,反之不然

      2.不允許在子組件中直接操作props

      3.可以變相操作props

      (1)在data中聲明局部變量,并用props初始化,弊端:局部變量不隨著props更新而更新

      (2)在computed中對props值轉換后輸出

      以上就是Vue中用props給data賦初始值時遇到的問題及解決方法的詳細內容,更多請關注php中文網其它相關文章!


      網站建設是一個廣義的術語,涵蓋了許多不同的技能和學科中所使用的生產和維護的網站。




      關鍵詞:Vue中用props給data賦初始值時遇到的問題及處理辦法




      Copyright © 2012-2018 瀏覽器部落(http://www.atelierescobar.com) .All Rights Reserved 網站地圖 友情鏈接

      免責聲明:本站資源均來自互聯網收集 如有侵犯到您利益的地方請及時聯系管理刪除,敬請見諒!

      QQ:1006262270   郵箱:kfyvi376850063@126.com   手機版 

      国产乱子伦漫画,猫咪www免费人成在线观看,国产真实哺乳吃奶在线观看,超乳专区爆乳国产