iT邦幫忙

2021 iThome 鐵人賽

DAY 9
0
Modern Web

我的Vue學習筆記系列 第 9

Day9-元件溝通傳遞(part1)

元件之所以很強大是他還有個資料傳遞功能,讓各個元件互相溝通,今天就要來研究他到底要怎麼傳資料!

props引用外部資料

在元件上用v-bind將props的資料傳遞進來。

Day08有提及關於命名的方式,props用法也一樣,HTML模板呼叫時要改用連字號寫法,parentMsg在模板中轉換為parent-msg


Untitled

在沒有v-bind綁定的時候template中的{{ parentMsg }}就只會顯示「msg」而已,以純文字的形式呈現(即便裡面是數字也是string)

<my-component parent-msg="msg"></my-component>

props設定

指定資料格式

屬性有以下(寫在type裡面時字首大寫)

  • String
  • Number
  • Boolean
  • Array
  • Object
  • Date
  • Function
  • Symbol
props:{
    'props-num':{
        type: Number,
    }
},

也可以指定多種格式

props:{
    'item':{
        type: [Number,String]
    }
},

設定預設值

加上default屬性就可以設定預設值,可以是陣列、物件或是字串。

props:{
    'item':{
        type: [Number,String],
				default:'Hello'
    }
},

自訂驗證規則

若以上驗證都不符合需求,可以自己創一個validator來驗證。

props:{
    'item':{
        type: Number,
				validator: value => value > 0
    }
},

props物件

這邊將程式分區塊放在一起來理解。

Untitled

實做之後發現當input內的質改變時,外層物件也被更改了,元件之間相互汙染,為了避免這樣的問題應該先將物件屬性弄成原始型別後再傳資料出去,類似建立副本的概念,這樣就不會汙染其它元件了。

<my-component 
	v-for="student in students" 
	:name="student.name" 
	:age="student.age" 
	:gender="student.gender">
</my-component>

//簡化
<my-component 
	v-for="student in students" 
	:="student">
</my-component>
app.component('my-component', {
    template: `
    <div class="info-card">
        <label>name:<input type="text" v-model="name"></label>
        <label>age:<input type="text" v-model="age"></label>
        <label>gender:<input type="text" v-model="gender"></label>
    </div>
    `,
    props: ['name', 'age', 'gender']
})

看到現在覺得非常混亂,所以做了一張圖讓兩種寫法做比較,使用原始型別方式才不會改道記憶體中的資料。

JavaScript 引擎會將原始型別強制轉型為 對應的物件型別 : 舉例來說,var a = 1 中,你可以改變變數 a 的內容,但你沒有任何手段可以把儲存 1 這個值的記憶體位置寫入其他內容。更多詳細的內容將在之後介紹 JavaScript傳值還是傳址時討論。—-JavaScript - 原始型別概述

Untitled

雙向綁定/單向資料流

就元件最佳的方式應該是不會汙染父層的單向資料流,所以應該在元件裡面也做一個專屬於仔元件的data

app.component('my-component', {
	  props: ['name', 'age', 'gender'],
	  data() {
	      return {
	          componentName: this.name,
	          componentAge: this.age,
	          componentGem: this.gender
	      }
	  },
	  template: `
	  <div class="info-card">
	      <label>name:<input type="text" v-model="componentName"></label>
	      <label>age:<input type="text" v-model="componentAge"></label>
	      <label>gender:<input type="text" v-model="componentGem"></label>
	  </div>
	  `
})

上一篇
Day07-生命週期
下一篇
Day10-元件溝通傳遞(part2)
系列文
我的Vue學習筆記30

尚未有邦友留言

立即登入留言