{%hackmd BJrTq20hE %} ###### tags: `Vue` `composition API` # 從composition API 開始VUE的生活-component、prop、emit ## component的使用 什麼是component?,在網頁中component是用來組成網頁的小元件,可以重複使用,在vue中component有兩種import方式。 1.先在src下的components資料夾中建立一個叫做TestComponentA.vue並在template中輸入\<h2>componentA\</h2> ### 全域component 絕大多數的情況下是不用使用到全域component,但是在圖片的處理中可以使用,例如接收不到圖片資料,可以使用Component所預設的圖片。 以下使是用全域component的範例,以TestComponentA作為例子 1.在main.js中import 要使用的component ```javascript= // import 的命名一般來說都會與import的檔名相同, // 記得所import Component要寫副檔名.vue不然會import不到東西。 import TestComponentA from '@/components/TestComponentA.vue' ``` 2.修改一下createApp(App).mount('#app') 為了使用全域component進行修改 ```javascript= // 原本為 createApp(App).mount('#app') // 修改為 const app = crearteApp(App) app.mount('#app') ``` 3.使用component()函式 在app.mount('#app')之前使用component()函是 範例如下 ```javascript= import { createApp } from 'vue' import App from './App.vue' import TestComponentA from '@/components/TestComponentA.vue' import './assets/main.css' const app = createApp(App) // 在component函式內第一個參數為命名,第二個參數是import的component。 app.component('TestComponentA', TestComponentA) app.mount('#app') ``` 4.可以在各個page或是各個component中使用全域component ```htmlembedded <template> <TestComponentA/> </template> ``` ### 區域component 這裡用TestComponentB作為範例 最常見的使用方式,使用的方法如下 1.在想要的頁面中import ```javascript= <script setup> import TestComponentB from '@/components/TestComponentB.vue' </script> ``` 2.在template中使用 ```htmlembedded= <template> <TestComponentB/> </template> ``` ### 動態component \<component :is="">搭配上computed可以在不同的條件下使用不同的component 以下範例的邏輯: 設定一個變數為num為0,點一按鈕num數字就會往上+1,當數字除3餘數為0時出現ComponentA、餘數為1時出現ComponentB、餘數為2時出現ComponentC ```javascript= <script setup> // 先imort所有用到的component import TestComponentA from '@/components/TestComponentA.vue' import TestComponentB from '@/components/TestComponentB.vue' import TestComponentC from '@/components/TestComponentC.vue' import { computed, ref } from 'vue' // 條件變數設定 const num = ref(0) // 條件變數增加數字的函式 function add(){ num.value ++ } // 對num.value進行監控,如果num.value改變就會按照條件return component並且重新渲染畫面 const componentComputed = computed(()=>{ switch (num.value % 3) { case 0: return TestComponentA break; case 1: return TestComponentB break; case 2: return TestComponentC break; default: TestComponentA break; } }) </script> ``` ```htmlembedded= <template> <button @click="add">click</button> <h2>{{num}}</h2> <component :is="componentComputed"/> </template> ``` 以下為結果    ## prop prop是父元件傳資料給子元件,在子元件中使用的方法,所傳的不只是資料,函式都可以傳遞。 以下為範例 ### 父元件 ```javascript=<script setup> import TestComponent from '@/components/TestComponent.vue' // orderList 與 函式callJack()都是要傳給子元件TestComponent const orderList = [ { name: 'Jack', order: '檸檬紅茶', price: 50 }, { name: 'Lucky', order: '珍珠奶茶', price: 70 }, { name: 'May', order: '紅茶拿鐵', price: 80 } ] function callJack(){ console.log('Jack') } </script> ``` 在子元件的標籤使用v-bind把資料傳入,要注意標籤內的屬性沒有大寫所以用-取代,以orderList為例就要寫成order-list。 ```htmlembedded= <template> <TestComponent :order-list="orderList" :call-jack="callJack"/> </template> ``` ### 子元件 會使用defineProps這個函式來接收父元件所傳的資料。 接收的方始有兩種一個是陣列,另一個是物件。 以下是使用陣列的方法,陣列的接收方法簡單,但是無法對錯誤的資料或是沒收到資料做出反應。 #### 使用陣列接收資料 ```javascript= <script setup> const props = defineProps(['orderList','callJack']) //接收到方法時的調用方式如下 props.callJack() </script> ``` #### 使用物件接收資料 使用物件接收資料不但可以驗證物間的類別,更可以在資料出錯時做出反應 ```javascript= <script setup> const props = defineProps({ orderList:{ type:Object, default:()=>({name:'訂單出錯',order:'訂單出錯',price:'價格出錯'}) }, callJack:{ type:Function, default:()=>{console.log('沒收到方法')} } }) //接收到方法時的調用方式如下 props.callJack() </script> ``` #### 使用物件接收資料的注意事項 1.在接收的資料是物件與陣列的時候default官方文件建議要用一個函式return,範例如下。 ```javascript= ojb:{ type:Object, // 以下的寫法是語法糖因為寫成()=>{}為函式 default:()=>({}) // 等於以下的寫法 default:()=>{return {}} }, arr:{ type:Array, default:()=>[] } ``` ```htmlembedded= <template> <h2>TestComponent</h2> <ul> <li v-for="item in props.orderList" :key="item.name">姓名:{{item.name}}訂購內容:{{item.order}}價格:{{item.price}}</li> </ul> </template> ``` ### 成功時會出現以下的畫面  ### 使用object接收資料失敗時有預設的畫面  ### 使用array接收資料失敗時的畫面  ## emit emit就是從子元件透過方法把資料傳遞給父元件,父元件在使用函式接住資料。 ### 子元件 emit出去的資料也能與pros一樣使用陣列或物件,使用陣列的好處就是簡單的資料送出,使用物件則可以對所送出去的資料做檢查在決定要不要送出。 在下面的範例要送出一個數字與字串到父元件 #### 以陣列方式送出的範例 ```javascript= <script setup> import { ref } from 'vue'; //送出去的"方法"並在defineEmits()內用陣列寫上父元件中的子元件v-on的方法也就是'sendNum'、'sendString' const emits = defineEmits(['sendNum','sendString']) // 要送出去的資料 const num = ref(100) // 要送出去的資料 const string = ref('Jay') function emitInfo(){ // 使用方法把資料送出 emits//這個是自己定義的在第四行('v-on的方法', 要送出的資料) emits('sendNum', num.value) emits('sendString', string.value) } emitInfo() </script> ``` #### 以物件方式送出 可以驗證送出去的資料是不是符合預期。 ```javascript= const emits = defineEmits( { sendNum: (payload) => { if (payloda === Number(payload)) { return true } else { console.log(sendNum不是數字) return false } }, sendString: (payload) => { if (payloda === String(payload)) { return true } else { console.log(sendStringsendNum不是字串) return false } } } ) // 要送出去的資料 const num = ref(100) // 要送出去的資料 const string = ref('Jay') function emitInfo(){ // 使用方法把資料送出 emits//這個是自己定義的在第四行('在子元件標籤v-on的方法', 要送出的資料) emits('sendNum', num.value) emits('sendString', string.value) } emitInfo() ``` ### 父元件 用來接資料的方法可以用函式表達式或一般的函示 ```javascript= <script setup> import TestComponent from '@/components/TestComponent.vue' import { ref } from '@vue/reactivity' const dataNum = ref(0) const dataString = ref("") // 用來接資料的方法 const getDataFromComponent = (data)=>{ dataNum.value = data } // 用來接資料的方法 function getStringDataFromComponent (data){ dataString.value = data } </script> ``` 在子元件的標籤v-on emits的方法與父元件接資料的方法 ```htmlembedded= <template> <TestComponent @send-num="getDataFromComponent" @send-string="getStringDataFromComponent" /> <h2>{{dataNum}}</h2> <h2>{{dataString}}</h2> </template> ``` ### emit成功的畫面  ### emit驗證失敗的畫面 驗證失敗資料就不會傳出並且出現警告資訊與驗證失敗的方法  參考資料 --- [Vue3 + Vite 快速上手 Get Startrd EP3 - components / props / emit](https://www.youtube.com/watch?v=ureFPVghH30)
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up