2‐2 元件之間的溝通傳遞 - daniel-qa/Vue GitHub Wiki
p.s 這裡的外層,指的是一開始 Vue.createApp() 的資料
p.s 跟 function 傳參數的方式類似
前面一個小節我們快速介紹了 Vue.js 元件系統的特性,以及元件內部的基本結構。 那麼在這個小節中,我們繼續對元件與元件之間各種傳遞資料的方式來做說明。
前面我們提到,Vue.js 每個元件的實體狀態、模板等作用範圍都應該要是獨立的, 這意味著我們不能(也不應該)在子元件的模組「直接」去修改父元件,甚至是另一個元件的資料,
這樣除了元件因為耦合程度過高維護不易,也可能產生難以追蹤的錯誤。
- 複利用這個元件: 我們希望這個元件可以根據「外部」傳入的資料來反映出不同的結果。
因為不能直接取用,那麼上下層元件之間,要從外部引進資料,就需要透過 props 屬性來引用外部的狀態。
使用方式很簡單,我們只要在自訂的子元件上使用上一章介紹過的 v-bind
指令:
<div id="app">
<!-- 這是外層元件的msg -->
<h3>{{ msg }}</h3>
<!-- 這裡的 v-bind: parent-msg 可以簡寫為:parent-msg
<my-component v-bind: parent-msg="msg"></my-component>
</div>
const app = Vue.createApp({
data () {
return {
msg:"這是外層元件的msg"
}
}
});
app.component('my-component', {
template:
<div class="component">
<div> 從 props 來的 parentMsg ==> {{ parentMsg }} </div>
<div> 自己的 msg ==> {{ msg }} </div>
</div>",
props: ["parentMsg"],
data () {
return {
msg:'這是子元件的msg'
}
}
});
app.mount('#app');
像這樣,我們可以在內層元件內透過 props
屬性宣告要從「外部」引用進來的屬性名稱,
並且在外層模板使用內層元件標籤時,以 v-bind
指令來將資料傳遞進來。
另外,這裡要特別注意的是, props
與子元件命名的情況一樣,若我們是以 HTML 作為模板的時候,因為 HTML 不分大小寫的關係,像 parentMsg
這樣的駝峰式寫法,在模板裡要轉換成連字號 (kebab-case) parent-msg
來使用。
在內層元件 (或稱子元件) 宣告 props
屬性,最簡單的方式就是透過「陣列」的型態,
app.component('my-component', {
props: ['props1', 'props2', 'props3', ...],
//下略...
});
這樣我們就可以透過 HTML 標籤內的屬性將外層的狀態引入至對應 Props
<my-component
:props1="..."
:props2="..."
:props3="..."></my-component>
當然,若是我們希望允許多種不同格式的 prop
,則可以透過陣列的形式來指定:
props:{
something:{
type: [String, Number]
}
}
這裡有一個簡單的 Vue 組件範例,展示如何通過 props 傳遞一個物件。
首先,假設我們要建立一個名為 UserProfile 的組件,該組件會接收一個用戶資料的物件作為 prop。
UserProfile.vue
<template>
<div class="user-profile">
<h2>{{ user.name }}</h2>
<p>Email: {{ user.email }}</p>
<p>Age: {{ user.age }}</p>
</div>
</template>
<script>
export default {
name: 'UserProfile',
props: {
user: {
type: Object,
required: true,
},
},
};
</script>
<style scoped>
.user-profile {
border: 1px solid #ccc;
padding: 16px;
border-radius: 8px;
}
</style>
- 使用該組件
在父組件中,我們可以這樣使用 UserProfile 組件,並傳遞一個用戶物件:
<template>
<div>
<UserProfile :user="userData" />
</div>
</template>
<script>
import UserProfile from './UserProfile.vue';
export default {
components: {
UserProfile,
},
data() {
return {
userData: {
name: 'John Doe',
email: '[email protected]',
age: 30,
},
};
},
};
</script>