引用Vue Components的原則,是透過父元件上import的方式,父元件中也可能存在許多子元件…這樣一個串一個的關係就成了樹狀結構的「元件樹」。今天我們要來學的就是在這個元件樹上面,組件彼此是如何傳遞資料的?
我們有一個計次按鈕的組件,希望它透過不同頁面引入時呈現不同的文字顏色,這時候就可以在按鈕組件中定義一個Prop
當作接口,接收外部傳來的資料:
//CountTest.vue
<script setup>
import { ref } from 'vue'
const count = ref(0)
const props = defineProps(['color']) //定義Props中有一個color
</script>
<template>
<div>
<text>
<button @click="count++" :style="{'color':props.color}">互動的次數{{count}}</button>
</text>
</div>
</template>
//AboutView.vue 外部給值
<CountTest color="green"/> //直接在呼叫的標籤上指定color顏色
我們試著傳遞更多內容:
//CountTest.vue
<script setup>
...
const props = defineProps({ //把型別都定義好
color: String,
fontSize: String,
msg: String,
state:Boolean
})
</script>
<template>
<div>
<text>{{props.msg}} <input type="checkbox" :checked="props.state"></text>
//顯示外部傳來的文字,checkbox判斷布林值
<br>
<button @click="count++" :style="{'color':props.color,'font-size':props.fontSize}">
互動的次數{{count}}
</button>
//改變文字顏色和大小
</div>
</template>
//AboutView.vue 外部給值
<script setup>
import {ref} from 'vue'
import CountTest from '@/components/CountTest.vue'
const answer = ref({
color: 'green',
fontSize: '18px',
msg: '這裡是About頁面嗎?',
state: true
}) //把回傳內容包成物件
</script>
<template>
<div class="about">
<CountTest v-bind="answer" /> //用v-bind方式回傳
</div>
</template>
傳值校驗
上面我們只指定了每個項目該有的型別,但是針對數據的校驗還能做進一步的檢查,詳見:Prop 校驗
//CountTest.vue
const props = defineProps({
color: {},
fontSize: String,
msg: String,
state:Boolean
})
//CountTest.vue
const props = defineProps({
//型別為字串,必傳
color:
{
type: String,
required: true
},
//型別為多種類,字串或數字
fontSize: [String, Number],
//型別為字串,必傳、有預設文字
msg: {
type: String,
required: true,
default:'能夠讀取頁面嗎?'
},
//Boolean轉換,更貼近原生js寫法;不回傳checked為false不會報錯
checked:Boolean
})
不符合規範的話就會在console.log中跳出警告:
[Vue warn]: Invalid prop: type check failed for prop "color". Expected String with value "null", got Null
at...
當子組件發生變化時,就會透過Emit把事件發送給父組件;可以看作是子組件的主動投遞事件訊息、也是父組件的監聽接口:
//CountTest.vue 子組件
const emit = defineEmits(['someEvent']) //新增監聽事件
const changeCount = function () { //透過click觸發監聽
emit('someEvent','從子組件傳來消息')
}
...
<button @click="changeCount"></button>
//AboutView.vue 父組件
const newMsg = ref('')
const handleEvent = (msg) => { //響應式資料接值
newMsg.value = msg
}
...
<CountTest @some-event="handleEvent" /> //監聽some-event事件
<text>{{newMsg}}</text> //傳過來的值show在這裡
參考資料
Vue-Prop
Vue-組件事件
Vue 程式札記 : emit 事件發射