今天要來看看的是我們不可或缺的老朋友 : props & emit ~ (鏘鏘~
相信有基礎 vue 知識的大家都知道 在options API 怎麼用 props & emit 了吧?
因此今天主要的重點在於 : composition API 中怎麼在 setup 用 props ?
廢話不多說,直接進入重點 ————
首先還是複習一下 options API 的 props 是怎麼被取用的啦 ~
溫馨提示 : props 是將外層變數傳進內層使用的方法。
嗯,就是 porps 進來後直接透過 this 來取用 XD
但這樣的寫法有個小缺點,就是乍看之下,無論是元件本身的變數或是 props 進來的變數都是透過 this 來取用的,當專案一大,就比較難分辨哪個是本身變數,哪個是 props 進來的。
<div :name="person"></div>
// 這裡是內層 options API 寫法
data(){
return{
test:"123"
}
},
props:["name"],
mounted(){
console.log(this.name,this.test) //小花,123
}
而 composition API 的寫法,將 props 進來的東西都集中在 setup 的第一個參數裡面。我們如果開 console.log 來看,就會發現 setup 裡面的 props 其實是一個 proxy。
因此如果我們想在 setup 裡面運用 props,就需要透過解構賦值的方式取出 props 進來的物件,再 return 出去就可以使用囉 ~ 並且,解構賦值取出來的值 / 物件具有 雙向綁定 的特性。
但若我們把 props 進來的物件內的屬性 再解構賦值一次,那麼這個屬性的 value 就不具有雙向綁定的功能了。
// 這裡是內層 composition API 寫法
const card = {
template:`<div class="card">
<div class="card-body">
<h5 class="card-title">{{ ppl.name }} {{num}}</h5> // 小花 123
<div> {{ name }}</div> // 小花 >> 一樣從物件取得出來,但失去雙向綁定的作用。
</div>
</div>`,
props:["ppl","num"],
setup(props){
console.log(props) // proxy
const { ppl,num } = props
const {name} = ppl
return{
ppl,
num,
name
}
}
}
如果我們希望這個屬性的 value 也具有雙向綁定的功能,我們就需要用 ref
來定義他。
setup(props){
console.log(props) // proxy
const { ppl,num } = props
const { name } = ref(ppl.name)
return{
ppl,
num,
name
}
}
//這裡是外層
components:{ card },
setup(){
const person = ref({
name:"小花"
})
const num = ref("123")
return{
person,
num
}
}
setup 除了 Props 還有另外一個叫做 context 的參數,而這個 context 可以帶出幾個屬性或方法,分別為 :
// 官方文件的介紹
export default {
setup(props, context) {
// 透传 Attributes(非响应式的对象,等价于 $attrs)
console.log(context.attrs)
// 插槽(非响应式的对象,等价于 $slots)
console.log(context.slots)
// 触发事件(函数,等价于 $emit)
console.log(context.emit)
// 暴露公共属性(函数)
console.log(context.expose)
}
}
其實實際上的寫法跟 options API 也依然很相似,只是原本的 this.$emit
改成從 setup 的 context 取出 emit 方法 ~
<div @push-data="pushData"></div>
// 這裡是內層 composition API 寫法
const card = {
template:`<div class="card">
<div class="card-body">
<button type="text" class="btn btn-primary" @click="pushData"> 送出資料 </button>
</div>
</div>`,
// 這裡是透過解構的方式把 emit 從 context 中取出來
setup(props,{emit}){
function pushData(){
emit("push-data","由內向外傳遞的資料")
}
return{
pushData
}
}
}
在 html 用 v:on 連接之後,外層就能順利接收到內層 emit 出來的資料了。
//這裡是外層
components:{ card },
setup(){
function getData(text){
console.log(text) //由內向外傳遞的資料
}
return{
getData
}
}