Vue Context 參數(shù) - Composition API

這幾天整理的一下過往的文章和筆記,備份到了 Github 上,地址?? blog。

如果我的內(nèi)容幫助到了您,歡迎點個 Star ?????? 鼓勵鼓勵 :) ~~ ??


在 Composition API 中,我們沒有 this 與 Options API 中相同的引用。

在 Options API 中,我們可以調(diào)用 console.log(this) 的任何選項并獲得對組件本身的引用,讓我們可以訪問它的 props、computeddata 等。

Vue3 允許我們使用 Composition API,這些功能都位于 setup 函數(shù)內(nèi)。這意味著 setup 是我們聲明響應式數(shù)據(jù)、方法和計算屬性的地方。

import { ref } from 'vue'
export default {
  props: {
    lastName: String
  },
  setup() {
    // 沒有 this,我們?nèi)绾问褂?props?
    const createdMethod = () => {
      console.log('created')
    }
    const name = ref('hello')

    createdMethod()

    return {
      createdMethod,
      name
    }
  }
}

setup 在我們的組件實例實際創(chuàng)建之前運行,并且由于我們的 setup 函數(shù)是我們實際上為組件定義所有內(nèi)容的地方,因此不再使用 this。

如何訪問組件屬性?

Composition API 為我們提供了訪問重要組件信息(如 propsslot)的替代方法。

setup 函數(shù)有參數(shù)讓我們訪問一些組件屬性:propscontext。

  • props — 在我們的組件中包含定義的 props
  • context — 是一個 Javascript 對象,它公開了三個組件屬性

這三個屬性是:

  • context.attrs – 傳遞給我們組件的props 屬性
  • context.slots – 具有我們所有模板插槽渲染功能的對象
  • context.emit – 我們的組件發(fā)出事件的方法

讓我們更深入地了解其中的每一個。

context.attrs

假設我們有一個自定義組件,它接受一個名為 value 的 prop。

export default {
  props: {
    value: String,
  },
  setup(props, context) {
    console.log(context.attrs)
  }
}

然后在父組件中,我們向它傳遞幾個屬性。

<template>
  <custom-component
    :value="value"
    test="hi"
    @close="close"
  />
</template>

將打?。?/p>

context

可以看到,它包含除了我們聲明的 props 之外的所有內(nèi)容。這包括事件監(jiān)聽器和 HTML 屬性之類的東西。

這里的一個重要說明是 attrs 不是響應式的。這意味著如果我們想應用副作用來響應 attrs 值的變化,我們應該改用 onUpdated 生命周期鉤子。

context.slots

context.slots讓我們可以訪問每個 slotrender 方法。當我們編寫自己的自定義渲染函數(shù)而不使用模板代碼時,這很有用。

Vue 建議在大多數(shù)用例中使用模板,但如果你真的想使用 JavaScript 的全部功能,我們可以創(chuàng)建自己的渲染函數(shù)。

Vue 文檔中使用自定義 render 方法的一個很好的例子是,如果我們正在創(chuàng)建一個組件,該組件根據(jù) prop 的值渲染具有不同級別標題的插槽值。

<template>
  <div>
    <h1 v-if="level == 1">
      <slot />
    </h1>
    <h2 v-if="level == 2">
      <slot />
    </h2>
    <h3 v-if="level == 3">
      <slot />
    </h3>
    <h4 v-if="level == 4">
      <slot />
    </h4>
    <h5 v-if="level == 5">
      <slot />
    </h5>
    <h6 v-if="level == 6">
      <slot />
    </h6>
  </div>
</template>

<script>
  export default {
      props: {
          level: Number
      }
  }
</script>

在這段代碼中,我們對所有 6 個標題選項使用 v-ifv-else-if 條件。正如您所看到的,有很多重復的代碼,而且看起來非?;靵y。

相反,我們可以使用 render 函數(shù)以編程方式生成我們的標題。使用 Composition API setup 函數(shù),它看起來像這樣。

import { h } from 'vue'
export default {
  props: {
    level: Number
  },
  setup(props, context) {
    return () => h('h' + props.level, {})
  }
}

但是,我們?nèi)绾巫屛覀兊牟宀圻M行渲染?

這就是 context.slots 發(fā)揮作用的地方。

通過讓我們訪問每個插槽的渲染函數(shù),我們可以輕松地將插槽添加到渲染函數(shù)中。每個插槽都可以通過其名稱訪問,并且由于我們沒有明確命名插槽,因此將其命名為 default。

import { h } from 'vue'
export default {
  props: {
    level: Number
  },
  setup(props, context) {
    return () => h('h' + props.level, {}, context.slots.default())
  }
}

現(xiàn)在,如果我們使用像這樣的簡單父組件來運行它

<template>
  <child-component :level="1"> 
    Hello World
  </child-component>
</template>

這是我們完成的 DOM 的樣子。

image

因此,您可能不會經(jīng)常使用 context.slots,但是當您編寫復雜的 JavaScript 渲染函數(shù)時,它是一個強大的功能。

注意:根據(jù) Vue 文檔,render 函數(shù)的優(yōu)先級高于根據(jù) template 選項或掛載元素的 DOM 內(nèi) HTML 模板編譯的渲染函數(shù)。

context.emit

context.emit 將替換 this.$emit 作為我們從組件發(fā)出事件的方式。

這對于向父組件發(fā)送任何類型的事件(帶或不帶數(shù)據(jù))非常有用。

假設我們有一個關閉按鈕,它發(fā)出一個名為 close 的事件。

<template>
  <div>
    <button @click="close">X</button>
  </div>
</template>

<script>
  export default {
    setup (props, context) {
      const close = () => {
        context.emit('close')
      }
      return {
        closeModal
      }
    }
  }
</script>

然后在我們的父組件中,我們可以使用 v-on/@ 指令監(jiān)聽這個 close 事件。

<modal-component @close="handleClose" />

我們在 setup 中無權訪問什么

到目前為止,我們已經(jīng)看到了 Composition API 如何使我們能夠訪問四個不同的屬性:props、attrsslotsemit。

但是由于 setup 在創(chuàng)建我們的組件實例之前運行,我們將無法訪問這三個組件屬性:

  • data
  • computed
  • methods

例如,這些是我們在 setup 自身內(nèi)部聲明的屬性,但我們沒有內(nèi)置方法來訪問所有 data 屬性的列表。

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容