Vue.js
ItIron2020
昨天我們介紹了vue組件的概念,在之後你會慢慢了解到一個vue打造的應用程式,其實就是由一堆組件疊加起來的東西,彼此之間有很明確的上下關係,就像是一個掛在支架上的葡萄一樣,每一粒葡萄與其他葡萄向下相連,最終結實累累的一整串! 我們昨天雖然做到了將todo-list組件化,但目前的內容完全寫死,我們希望的是可以告訴那個組件現在要render怎麼樣的資料,這就需要props屬性的幫忙了,我們馬上開始吧!
還記得我們昨天的進度嗎? 我們最終順利地用v-for配合新註冊的組件印出了四個代辦事項,但內容卻不太正確。
我們在父層(也就是一開始的vue實體)有著四個不同的代辦事項,我們希望能將這些todos傳進子層(也就是新建立的todo-list組件),讓它能根據傳進去的資料印出對應的結果,為此我們有幾件事情要做。
我們一步一步來吧!GOGOGO
首先一樣請你先打開今天的demo。
我們要做的第一步就是在我們註冊的組件中加入props屬性,設定props屬性可以讓這個元件接受來自父層傳入的資料,我知道這聽起來有些難懂,看完以下的說明就會比較有概念了!
完整的props寫法分為幾個部分
props: ['todo']
你自然也可以多傳幾個參數給子層,只要你需要的話
props: ['todo', 'paramA', 'paramB']
你也可以進一步給傳入的資料增加一些選項,此時則必須改為物件形式
props: {
todo : {
type: Object // 指定傳進來的參數必須是物件,否則報錯
}
}
同時可以設定這個參數是否是必須值以及是否需要default value
props: {
todo : {
type: Object,
required: true, // 此欄位必填
default: {} // 預設值為空物件
}
}
利用以上的手法,你可以預先設定傳進來的參數需要滿足哪些條件,這樣就可以先預防一些可能的錯誤! 到這邊你應該對於props的概念仍相當模糊,但只要跟著做完實作,我相信會有基本的了解,先不用緊張?
請你先在原本的程式碼中,加入以下的部分。
Vue.component("todo-list", {
template: `
<div class="todo-wrapper">
<div class="todo-title">
Write Article
</div>
<div class="todo-icons">
<i class="fa fa-check" aria-hidden="true"></i>
<i class="fa fa-trash-alt" aria-hidden="true"></i>
</div>
</div>
`,
props: {
todo : {
type: Object,
required: true
}
}
});
上方的寫法就是希望傳進來的參數為一個物件、且必定需要這個參數,任何一個條件沒滿足就會報錯!
現在我們設定好資料傳遞的格式了,我們先複習一下傳進來的todo物件長什麼樣子,我們才有辦法去修改我們的template
{
title: "Get dressed",
isComplete: false
}
這樣就很清楚我們要修改的兩個部分
<div class="todo-title">Write Article</div>
<div class="todo-wrapper">
// 略
</div>
請你將原本template的內容改為以下
Vue.component("todo-list", {
template: `
<div :class="[todo.isComplete? 'success':'error','todo-wrapper']"> // 這裡
<div class="todo-title">
{{todo.title}} // 還有這裡
</div>
<div class="todo-icons">
<i class="fa fa-check" aria-hidden="true"></i>
<i class="fa fa-trash-alt" aria-hidden="true"></i>
</div>
</div>
`,
props: {
todo : {
type: Object,
required: true
}
}
});
我們傳進來的todo物件有兩個屬性可以讓我們使用,分別是title & isComplete,我們分別修改在template中對應的部分,你可以想像我們在子元件的data屬性中多了一個todo讓我們使用,那剩下的應該就相當好懂囉!
最後我們只要在父層利用v-bind將資料傳遞給子層,注意一下我們傳入的方式為
v-bind:傳入的prop名稱(你剛在子層設計的)="傳入的變數"
請你將使用todo-list的部分修改為以下
<todo-list v-for="todo in todos" :key="todo.id" :todo="todo"></todo-list>
我們先利用v-for迭代todos陣列,接著把每一個迭代到的物件傳進子層,上方的寫法你可以改寫為以下的寫法做一個比較,你會更清楚哪一個是prop,哪一個是迭代到的物件。
<todo-list v-for="item in todos" :key="item.id" :todo="item"></todo-list>
最後你會不意外的看到我們預期的結果,一個漂亮的todo list!
我們今天介紹了props屬性與最基本的父子層資料傳遞,props在一開始接觸實確實很容易讓人困惑,你只要把它想成從父層那邊拿個data屬性來用,其他的部分就跟你平常用data屬性內的變數進行渲染或計算沒有任何差別!
這是一個實務上極端常見的技巧,你也可以試著利用今天的範例多傳一些參數進子層操作,應該會再更有概念一些! 那我們就明天見囉!
此文章同步發布於個人部落格,有興趣的大大也可以來參觀一下:D