Vue 中的 Props 與 Data 細微差異,你知道嗎?

做者:Michael Thiessenhtml

譯者:前端小智前端

來源:mediumvue

點贊再看,養成習慣react

本文 GitHub github.com/qq449245884… 上已經收錄,更多往期高贊文章的分類,也整理了不少個人文檔,和教程資料。歡迎Star和完善,你們面試能夠參照考點複習,但願咱們一塊兒有點東西。git

Vue提供了兩種不一樣的存儲變量:propsdatagithub

這些方法一開始可能會讓人感到困惑,由於它們作的事情很類似,並且也不清楚什什麼時候使用props,什麼時候使用data面試

那麼propsdata有什麼區別呢?bash

data是每一個組件的私有內存,能夠在其中存儲須要的任何變量。props是將數據從父組件傳遞到子組件的方式。微信

在本文中,咱們將學習到:數據結構

  • 什麼是props,爲何這些數據只向下流動,而不是向上

  • data 選項的用途

  • 響應式是什麼

  • 如何避免 propsdata 之間的命名衝突

  • 如何將 propsdata 結合使用

什麼是 props

在Vue中,props(或properties)是咱們將數據從父組件向下傳遞到其子組件的方式。

當咱們使用組件構建應用程序時,最終會構建一個稱爲樹的數據結構。 相似於家譜,具備:

  • 父母
  • 孩子
  • 祖先
  • 子孫

數據從根組件(位於最頂端的組件)沿着樹向下流動。就像基因是如何代代相傳的同樣,父組件也會將本身的props傳給了他們的孩子。

在Vue中,咱們在代碼的<template>中向組件添加了一些props

<template>
  <my-component cool-prop="hello world"></my-component>
</template>
複製代碼

在這個例子中,咱們傳遞一個名爲color-prop prop,其值爲「hello world」。咱們可以從my-component內部訪問這個值。

然而,當咱們從組件內部訪問props時,咱們並不擁有它們,因此咱們不能更改它們(就像你不能改變你父母給你的基因同樣)。

注意:雖然能夠更改組件中的屬性,但這是一個很是糟糕的主意。最終還會更改父類正在使用的值,這可能會致使不少混淆。

可是有些狀況咱們須要改變變量,因此 data 就派上用場了。

什麼是 data ?

data是每一個組件的內存,這是存儲數據和但願跟蹤的任何其餘變量的地方。

若是咱們正在構建一個計數器應用程序,咱們將須要跟蹤計數,所以咱們將向咱們的data添加一個count:

<template>
  <div>
    {{ count }}
    <button @click="increment">+</button>
    <button @click="decrement">-</button>
  </div>
</template>
------------------------------------------
export default {
  name: 'Counter',
  data() {
    return {
      // Initialized to zero to begin
      count: 0,
    }
  },
  methods: {
    increment() {
      this.count += 1;
    },
    decrement() {
      this.count -= 1;
    }
  }
}
複製代碼

此處的data是私有的,僅供組件自己使用,其餘組件不能訪問它。

注意:理論上是其它組件是不能訪問這些數據,但實際是能夠的。可是出於一樣的緣由,這樣作是很是糟糕的

若是須要向組件傳遞數據,可使用props向下傳遞數據(傳遞給子組件),或者使用事件向上傳遞數據(傳遞給父組件)。

props 和 data 都是響應式的

使用 Vue,咱們不須要過多地考慮組件何時會更新,Vue 會自動幫咱們作好,由於 Vue 是響應式的。

咱們沒必要每次更改 data 都調用setState,只需更改data便可! 只要要更新具備響應式的屬性(props,computed 及 data 中的任何值),Vue 就會知道它什麼時候發生變化。

回到計數器應用程序,咱們仔細看看這裏面的方法

methods: {
  increment() {
    this.count += 1;
  },
  decrement() {
    this.count -= 1;
  }
}
複製代碼

咱們所要作的就是更新count,Vue 會檢測到這個變化,而後用新值從新渲染咱們的應用程序

Vue 的響應系統有不少細微的差異,若是你想要高效地使用Vue,理解它是很是重要的。若是你想更深刻地瞭解Vue的響應系統,這裏有更多要了解的東西。

避免命名衝突

Vue所作的另外一件事是,使開發工做變得更好一點。

咱們在組件上定義一些 propsdata

export default {
  props: ['propA', 'propB'],
  data() {
    return {
      dataA: 'hello',
      dataB: 'world',
    };
  },
};
複製代碼

若是要在方法內部訪問它們,則沒必要使用this.props.propAthis.data.dataA。 Vue 讓咱們徹底省略了 propsdasta,只剩下了更整潔的代碼。

咱們可使用this.propAthis.dataA訪問它們:

methods: {
  coolMethod() {
    // Access a prop
    console.log(this.propA);

    // Access our data
    console.log(this.dataA);
  }
}
複製代碼

所以,若是咱們不當心在dataprops中使用相同的名稱,則會遇到問題。

若是發生這種狀況,Vue 會給你一個警告,由於它不知道你想訪問哪一個。

export default {
  props: ['secret'],
  data() {
    return {
      secret: '1234',
    };
  },
  methods: {
    printSecret() {
      // 咱們想要哪個?
      console.log(this.secret);
    }
  }
};
複製代碼

當咱們同時使用propsdata時,Vue 的神奇之處就產生了。

props 和 data 一塊兒使用

既然咱們已經看到了 propsdata 的不一樣之處,讓咱們來看看爲何咱們須要兩個,經過創建一個基本的應用程序。

咱們將使用名爲ContactInfo的組件顯示此信息:

// ContactInfo
<template>
  <div class="container">
    <div class="row">
      Email: {{ emailAddress }}
      Twitter: {{ twitterHandle }}
      Instagram: {{ instagram }}
    </div>
  </div>
</template>
-------------------------------------
export default {
  name: 'ContactInfo',
  props: ['emailAddress', 'twitterHandle', 'instagram'],
};
複製代碼

ContactInfo組件接受 props:emailAddresstwitterHandleinstagram,並將其顯示在頁面上。

咱們的我的資料頁面組件ProfilePage以下所示:

// ProfilePage
<template>
  <div class="profile-page">
    <div class="avatar">
      <img src="user.profilePicture" />
      {{ user.name }}
    </div>
  </div>
</template>
-------------------------------------------------
export default {
  name: 'ProfilePage',
  data() {
    return {
      // In a real app we would get this data from a server
      user: {
        name: 'John Smith',
        profilePicture: './profile-pic.jpg',
        emailAddress: 'john@smith.com',
        twitterHandle: 'johnsmith',
        instagram: 'johnsmith345',
      },
    }
  }
};
複製代碼

咱們的ProfilePage組件目前顯示用戶的配置文件圖片及其名稱,它還有用戶數據對象。

咱們如何從父組件(ProfilePage)向下獲取數據到子組件(ContactInfo)

咱們必須使用 props 傳遞數據。

首先,咱們須要將ContactInfo組件導入ProfilePage組件

// Import the component
import ContactInfo from './ContactInfo.vue';

export default {
  name: 'ProfilePage',

  // Add it as a dependency
  components: {
    ContactInfo,
  },

  data() {
    return {
      user: {
        name: 'John Smith',
        profilePicture: './profile-pic.jpg',
        emailAddress: 'john@smith.com',
        twitterHandle: 'johnsmith',
        instagram: 'johnsmith345',
      },
    }
  }
};
複製代碼

其次,咱們必須在<template>中添加組件:

// ProfilePage
<template>
  <div class="profile-page">
    <div class="avatar">
      <img src="user.profilePicture" />
      {{ user.name }}
    </div>

    <!-- Add component in with props -->
    <contact-info
      :email-address="emailAddress"
      :twitter-handle="twitterHandle"
      :instagram="instagram"
    />

  </div>
</template>
複製代碼

如今ContactInfo須要的全部用戶數據都將沿着組件樹向下流動,並從ProfilePage進入ContactInfo

咱們將數據保存在ProfilePage而不是ContactInfo中的緣由是ProfilePage頁面的其餘部分須要訪問user對象。

因爲數據只向下流,這意味着咱們必須將數據放在組件樹中足夠高的位置,以便它能夠向下流到須要去的全部位置。


代碼部署後可能存在的BUG無法實時知道,過後爲了解決這些BUG,花了大量的時間進行log 調試,這邊順便給你們推薦一個好用的BUG監控工具 Fundebug

原文:medium.com/js-dojo/vue…


交流

文章每週持續更新,能夠微信搜索「 大遷世界 」第一時間閱讀和催更(比博客早一到兩篇喲),本文 GitHub github.com/qq449245884… 已經收錄,整理了不少個人文檔,歡迎Star和完善,你們面試能夠參照考點複習,另外關注公衆號,後臺回覆福利,便可看到福利,你懂的。

相關文章
相關標籤/搜索