iT邦幫忙

2024 iThome 鐵人賽

DAY 11
0
JavaScript

歡迎參加我的原生JS畢業典禮系列 第 11

【Day10】組件間溝通—Vue Prop&Emit

  • 分享至 

  • xImage
  •  

引用Vue Components的原則,是透過父元件上import的方式,父元件中也可能存在許多子元件…這樣一個串一個的關係就成了樹狀結構的「元件樹」。今天我們要來學的就是在這個元件樹上面,組件彼此是如何傳遞資料的?

Props子組件接口

我們有一個計次按鈕的組件,希望它透過不同頁面引入時呈現不同的文字顏色,這時候就可以在按鈕組件中定義一個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>
  • Props是單向數據流只讀不寫特性,當我們定義名稱(型別也可以定義)後,內容都交由外部決定
  • Props可以同時接收多個型別的參數
//AboutView.vue 外部給值
<CountTest color="green"/> //直接在呼叫的標籤上指定color顏色

https://ithelp.ithome.com.tw/upload/images/20240925/20169356jrAzzSYhu2.png
我們試著傳遞更多內容:

//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>

https://ithelp.ithome.com.tw/upload/images/20240925/201693564B6C7VZTVI.png
傳值校驗
上面我們只指定了每個項目該有的型別,但是針對數據的校驗還能做進一步的檢查,詳見: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事件監聽

當子組件發生變化時,就會透過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 事件發射


上一篇
【Day9】組件化概念—Vue Components註冊與使用
下一篇
【Day11】Vue生命週期—Lifecycle Hooks ft.Composition API
系列文
歡迎參加我的原生JS畢業典禮12
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言