筆記內容:學習在 Vue 的單文件組件中如何管理數據。
目錄:
眾所周知,Vue是一個響應式的前端組件框架。響應式即是當業務邏輯中的數據發生改變的時候視圖中的內容也會跟着改變。

<script> export default { data(){ return{ classmates:[ {id: 1, name: "可頌"}, {id: 2, name: "小許"}, {id: 3, name: "柯柯"}, ] }; }, render(){ return( <div class="hello"> { this.classmates.map((p, index) => ( <div key={p.id}> {`${index}.${p.name}`} </div> ))} </div> ); } } </script>
如上,data 函數返回了一個包含 classmates 數組的對象,當在創建一個 vue 的時候會將 data 函數返回的對象中的所有屬性都加入到響應式系統中。
Q:data 為什么是函數?
A:只有返回一個生產 data 的函數,這個組件產生的每一個實例才能維持一份被返回對象的獨立的拷貝。JS 中的對象都是通過引用關聯的,如果使用的是同一個對象,那么可能會引用到同一個對象,數據可能就會發生紊亂。( Vue官網的解釋:https://cn.vuejs.org/v2/guide/components.html#data-%E5%BF%85%E9%A1%BB%E6%98%AF%E4%B8%80%E4%B8%AA%E5%87%BD%E6%95%B0 )
Prop 是約定了從父組件向子組件傳參的一個接口,可以通過 Prop 從父組件向子組件傳遞參數。
例子:
實現通過 Prop 從父組件 App.vue 傳遞參數給子組件 PropChild.vue
父組件 App.vue :
注冊、引入、使用子組件 PropChild.vue。在模板上使用子組件 PropChild 時,傳遞參數給子組件的 parentName。

<template> <div> <prop-child parent-name="2"></prop-child> </div> </template> <script> import PropChild from "./components/PropChild"; export default { components:{ PropChild } } </script>
子組件 PropChild.vue:
子組件聲明了一個 props,這個 props 是 parentName,然后模板插值打印出來 parentName(得到父組件通過prop傳遞過來的參數后)。

<template> <div> father {{ parentName }} </div> </template> <script> export default { props: ["parentName"] }; </script>
頁面表現:
成功渲染輸出 2
說明:
在父組件 App.vue 里引入、注冊、使用子組件 PropChild。在子組件 PropChild.vue 里聲明 props parentName,渲染 parentName。在父組件 App.vue 中使用 parentName,命名方式為烤肉串式命名即 parent-name,在父組件向子組件傳遞參數 2 (語句:<prop-child parent-name="2"></prop-child>)。
注意:
通過 props 從父組件向子組件傳遞了參數后,如果想要在子組件修改 props ,有人可能會嘗試通過生命周期的鈎子 mounted 改,但是這會報錯,因為 Vue 從 Vue2 開始是單向數據流的。
從前面的例子可以知道,在 Vue2 里面父組件 props 的更新會流到子組件,但是反過來不行,這樣子做的目的主要是防止子組件意外地改變父組件的狀態從而導致應用數據難以理解,為什么這樣說呢?因為 JS 中的對象是通過引入傳入的,在對於一個數組或者對象類型的 props 來說,在子組件中去改變數組或者對象本身將影響到父組件之間的狀態,如果組件層級比較多的時候,或者說這個數據被多個組件共享的時候,我們很難琢磨到組件是被哪里修改的。
Vue 官網中 Prop 驗證的部分:https://cn.vuejs.org/v2/guide/components-props.html#Prop-%E9%AA%8C%E8%AF%81
例子
父組件 App.vue :

<template> <div> <prop-child parent-name="nana"></prop-child> </div> </template> <script> import PropChild from "./components/PropChild"; export default { components:{ PropChild } } </script>
子組件 PropChild.vue :

<template> <div> father {{ parentName }} </div> </template> <script> export default { props: { parentName: { // 基礎的類型檢查 (`null` 和 `undefined` 會通過任何類型驗證) type: String, // 必填的字符串 required: true, // 帶有默認值的字符串 default: "nana", // 自定義驗證函數 validator(value){ // 這個值必須匹配下列字符串中的一個 const nameEnums = ["nana", "mona"]; return nameEnums.indexOf(value) !== -1; } } } }; </script>
頁面表現:
父組件傳入的參數是 “nana”,通過Prop驗證,控制台沒有報錯。
如果將 App.vue 代碼第 3 行傳入的參數改為 “nana” 或 “mona” 以外的值,Prop驗證將不通過,控制台會報錯。
計算屬性和偵聽器的筆記:https://www.cnblogs.com/xiaoxuStudy/p/13230664.html
數組操作的筆記:https://www.cnblogs.com/xiaoxuStudy/p/13230631.html