iT邦幫忙

2022 iThome 鐵人賽

DAY 14
0
自我挑戰組

程式小白的 vue.js 學習筆記系列 第 14

Day 14 : 【Composition API 5】 props & emit

  • 分享至 

  • xImage
  •  

今天要來看看的是我們不可或缺的老朋友 : props & emit ~ (鏘鏘~
相信有基礎 vue 知識的大家都知道 在options API 怎麼用 props & emit 了吧?
因此今天主要的重點在於 : composition API 中怎麼在 setup 用 props ?
廢話不多說,直接進入重點 ————


首先還是複習一下 options API 的 props 是怎麼被取用的啦 ~

溫馨提示 : props 是將外層變數傳進內層使用的方法。

options API 寫法

嗯,就是 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 寫法

而 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
    }
}

emit

setup 除了 Props 還有另外一個叫做 context 的參數,而這個 context 可以帶出幾個屬性或方法,分別為 :

  1. attrs
  2. slots
  3. emit
  4. expose
    — 詳見官方文件 - Setup 上下文
// 官方文件的介紹
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
    }
}

上一篇
Day 13 : 【Composition API 4】 computed + watch = WatchEffect (?)
下一篇
Day 15 : 【Composition API 6】$refs、Provider 與 inject
系列文
程式小白的 vue.js 學習筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言