欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

vue3的defineExpose宏函數(shù)是如何暴露方法給父組件使用

 更新時(shí)間:2024年05月29日 09:14:54   作者:前端歐陽  
當(dāng)子組件使用setup后,父組件就不能像vue2那樣直接就可以訪問子組件內(nèi)的屬性和方法,這個(gè)時(shí)候就需要在子組件內(nèi)使用defineExpose宏函數(shù)來指定想要暴露出去的屬性和方法,本文介紹vue3的defineExpose宏函數(shù)是如何暴露方法給父組件使用,需要的朋友可以參考下

前言

眾所周知,當(dāng)子組件使用setup后,父組件就不能像vue2那樣直接就可以訪問子組件內(nèi)的屬性和方法。這個(gè)時(shí)候就需要在子組件內(nèi)使用defineExpose宏函數(shù)來指定想要暴露出去的屬性和方法。這篇文章來講講defineExpose宏函數(shù)是如何暴露出去這些屬性和方法給父組件使用。注:本文中使用的vue版本為3.4.19

看個(gè)demo

父組件index.vue的代碼如下:

<template>
  <ChildDemo ref="child" />
  <button @click="handleClick">調(diào)用子組件的validate方法</button>
</template>
<script setup lang="ts">
import ChildDemo from "./child.vue";
import { ref } from "vue";
const child = ref();
function handleClick() {
  console.log(child.value.validate);
  child.value.validate?.();
}
</script>

上面的代碼很簡單,通過ref拿到子組件的實(shí)例賦值給child變量。然后在按鈕的click事件中打印出子組件的validate方法和執(zhí)行validate方法。

再來看看子組件child.vue不使用defineExpose宏的例子,代碼如下:

<template></template>
<script setup>
function validate() {
  console.log("執(zhí)行子組件validate方法");
}
</script>

在瀏覽器中點(diǎn)擊父組件的button按鈕,可以看到控制臺(tái)中打印的是undefined,并且子組件內(nèi)的validate方法也沒有執(zhí)行。因?yàn)樽咏M件使用了setup,默認(rèn)是不會(huì)暴露setup中定義的屬性和方法。如下圖:

我們再來看看子組件child.vue使用defineExpose宏的例子,代碼如下:

<template></template>
<script setup>
function validate() {
  console.log("執(zhí)行子組件validate方法");
}
defineExpose({
  validate,
});
</script>

在瀏覽器中點(diǎn)擊父組件的button按鈕,可以看到控制臺(tái)中打印的不再是undefined,子組件內(nèi)的validate方法也執(zhí)行了。如下圖:

加我微信heavenyjj0012回復(fù)「666」,免費(fèi)領(lǐng)取歐陽研究vue源碼過程中收集的源碼資料,歐陽寫文章有時(shí)也會(huì)參考這些資料。同時(shí)讓你的朋友圈多一位對vue有深入理解的人。

編譯后的代碼

首先需要在瀏覽器中找到編譯后的使用defineExpose宏的child.vue文件,在network面板中找到child.vue,然后右鍵點(diǎn)擊Open in Sources panel就可以在source面板中找到編譯后的child.vue。如下圖:

為了要在瀏覽器中debug,我們還需要在設(shè)置中關(guān)閉瀏覽器的javascript source map,如下圖:

現(xiàn)在我們來看看編譯后的child.vue文件,代碼如下:

const _sfc_main = {
  __name: "child",
  setup(__props, { expose: __expose }) {
    function validate() {
      console.log("執(zhí)行子組件validate方法");
    }
    __expose({
      validate,
    });
    const __returned__ = { validate };
    return __returned__;
  },
};
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
  return null;
}
_sfc_main.render = _sfc_render;
export default _sfc_main;

從上面可以看到_sfc_main對象中的setup對應(yīng)的就是我們源代碼<script setup>中的內(nèi)容,并且defineExpose宏函數(shù)也不在了,變成了一個(gè)__expose方法(defineExpose宏函數(shù)如何編譯成__expose方法我們會(huì)在下一篇文章講)。如下圖:

expose方法

__expose方法打個(gè)斷點(diǎn),刷新頁面此時(shí)斷點(diǎn)停留在__expose方法上面。點(diǎn)擊step into進(jìn)入到__expose方法內(nèi)部,如下圖:

進(jìn)入到__expose方法內(nèi)部,我們發(fā)現(xiàn)__expose方法是在一個(gè)createSetupContext函數(shù)中定義的。在我們這個(gè)場景中createSetupContext函數(shù)簡化后的代碼如下:

function createSetupContext(instance) {
  const expose = (exposed) => {
    instance.exposed = exposed || {};
  };
  return Object.freeze({
    // ...省略
    expose,
  });
}

我們先來看看函數(shù)中的instance變量,我想你通過名字應(yīng)該已經(jīng)猜到了他就是當(dāng)前vue實(shí)例對象。如下圖:

在vue實(shí)例對象中有我們熟悉的data方法、directives和componens屬性等。

expose函數(shù)內(nèi)部做的事情也很簡單,將子組件需要暴露的屬性或者方法組成的對象賦值給vue實(shí)例上的exposed屬性。

父組件訪問子組件的validate方法

在vue3中想要訪問子組件需要使用特殊的 ref attribute,在我們這個(gè)例子中就是使用<ChildDemo ref="child" />。這樣使用后就可以使用child變量訪問子組件,其實(shí)在這里child變量的值就是一個(gè)名為getExposeProxy函數(shù)的返回值(后面的文章中會(huì)去詳細(xì)講解ref attribute是如何訪問子組件)。

getExposeProxy函數(shù)的代碼如下:

function getExposeProxy(instance) {
  if (instance.exposed) {
    return (
      instance.exposeProxy ||
      (instance.exposeProxy = new Proxy(proxyRefs(markRaw(instance.exposed)), {
        get(target, key) {
          if (key in target) {
            return target[key];
          } else if (key in publicPropertiesMap) {
            return publicPropertiesMap[key](instance);
          }
        },
        has(target, key) {
          // ...省略
        },
      }))
    );
  }
}

前面我們講過了defineExpose宏函數(shù)中定義了想要暴露出來的屬性和方法,經(jīng)過編譯后defineExpose宏函數(shù)變成了__expose方法。執(zhí)行__expose方法后會(huì)將子組件想要暴露的屬性或者方法組成的對象賦值給vue實(shí)例上的exposed屬性,也就是instance.exposed。

在上面的getExposeProxy函數(shù)中就是返回了instance.exposedProxy對象,當(dāng)我們使用child.value.validate訪問子組件的validate方法,其實(shí)就是訪問的是instance.exposed對象中的validate方法,而instance.exposed中的validate方法就是defineExpose宏函數(shù)暴露的validate方法。如下圖:

總結(jié)

父組件想要訪問子組件暴露的validate方法主要分為下面四步:

  • 子組件使用defineExpose宏函數(shù)聲明想要暴露validate方法。
  • defineExpose宏函數(shù)經(jīng)過編譯后變成__expose方法。
  • 執(zhí)行__expose方法將子組件需要暴露的屬性或者方法組成的對象賦值給子組件vue實(shí)例上的exposed屬性,也就是instance.exposed。
  • 父組件使用ref訪問子組件的validate方法,也就是訪問child.value.validate。其實(shí)訪問的就是上一步的instance.exposed.validate方法,最終訪問的就是defineExpose宏函數(shù)中暴露的validate方法。

到此這篇關(guān)于vue3的defineExpose宏函數(shù)是如何暴露方法給父組件使用的文章就介紹到這了,更多相關(guān)vue3 defineExpose宏函數(shù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 解決vue無法加載文件D:\Program Files\nodejs\node_global\vue.ps1,因?yàn)樵诖讼到y(tǒng)上禁止運(yùn)行腳本

    解決vue無法加載文件D:\Program Files\nodejs\node_global\vue.ps1,

    這篇文章主要給大家介紹了關(guān)于解決vue無法加載文件D:\Program Files\nodejs\node_global\vue.ps1,因?yàn)樵诖讼到y(tǒng)上禁止運(yùn)行腳本的相關(guān)資料,這個(gè)報(bào)錯(cuò)是由于在系統(tǒng)上禁止運(yùn)行腳本導(dǎo)致的,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2024-01-01
  • vue使用pdfjs顯示PDF可復(fù)制的實(shí)現(xiàn)方法

    vue使用pdfjs顯示PDF可復(fù)制的實(shí)現(xiàn)方法

    這篇文章主要介紹了vue使用pdfjs顯示PDF可復(fù)制的實(shí)現(xiàn)方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-12-12
  • webpack+vue-cil 中proxyTable配置接口地址代理操作

    webpack+vue-cil 中proxyTable配置接口地址代理操作

    這篇文章主要介紹了webpack+vue-cil 中proxyTable配置接口地址代理操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-07-07
  • 解決node-sass安裝報(bào)錯(cuò)無python等情況

    解決node-sass安裝報(bào)錯(cuò)無python等情況

    在國內(nèi)安裝node-sass常因無法穩(wěn)定連接GitHub而失敗,解決方法包括手動(dòng)下載對應(yīng)的binding.node文件并放入緩存目錄,操作步驟詳細(xì),適合非Python用戶,無需額外環(huán)境配置
    2024-10-10
  • vue.js 輸入框輸入值自動(dòng)過濾特殊字符替換中問標(biāo)點(diǎn)操作

    vue.js 輸入框輸入值自動(dòng)過濾特殊字符替換中問標(biāo)點(diǎn)操作

    這篇文章主要介紹了vue.js 輸入框輸入值自動(dòng)過濾特殊字符替換中問標(biāo)點(diǎn)操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-08-08
  • 使用Vue.js報(bào)錯(cuò):ReferenceError: “Vue is not defined“ 的原因與解決方案

    使用Vue.js報(bào)錯(cuò):ReferenceError: “Vue is not d

    在前端開發(fā)中,ReferenceError: "Vue is not defined" 是一個(gè)常見的錯(cuò)誤,該錯(cuò)誤通常發(fā)生在項(xiàng)目中未正確引入 Vue.js 框架或代碼配置存在問題時(shí),本篇文章將詳細(xì)分析該錯(cuò)誤的成因,并提供多種解決方案,幫助開發(fā)者快速排查問題,需要的朋友可以參考下
    2024-12-12
  • vue3的介紹和兩種創(chuàng)建方式詳解(cli和vite)

    vue3的介紹和兩種創(chuàng)建方式詳解(cli和vite)

    這篇文章主要介紹了vue3的介紹和兩種創(chuàng)建方式(cli和vite),vue3對比vue2帶來的性能提升有很多優(yōu)勢,總體來說Vue 3在性能、開發(fā)體驗(yàn)和代碼組織方面都有所改進(jìn),使得它更加適合于大型、復(fù)雜的應(yīng)用程序開發(fā),需要的朋友可以參考下
    2023-04-04
  • vant自定義引入iconfont圖標(biāo)及字體的方法步驟

    vant自定義引入iconfont圖標(biāo)及字體的方法步驟

    因?yàn)関antUI給的圖標(biāo)非常少,為了滿足自己的需求,就應(yīng)該找到一種方法來向vant添加自己自定義的圖標(biāo),對于自定義圖標(biāo)我第一時(shí)間想到的就是阿里的iconfont矢量圖庫,這篇文章主要給大家介紹了關(guān)于vant自定義引入iconfont圖標(biāo)及字體的方法步驟,需要的朋友可以參考下
    2023-09-09
  • Vue命令式組件的編寫與應(yīng)用小結(jié)

    Vue命令式組件的編寫與應(yīng)用小結(jié)

    這篇文章主要介紹了Vue命令式組件的編寫與應(yīng)用小結(jié),在這篇文章中,我會(huì)帶你了解命令式組件的基本概念,并通過一些簡單的示例來展示它們是如何工作的,需要的朋友可以參考下
    2024-03-03
  • vue3中事件處理@click的用法詳解

    vue3中事件處理@click的用法詳解

    @click指令用于監(jiān)聽元素的點(diǎn)擊事件,并在觸發(fā)時(shí)執(zhí)行相應(yīng)的處理函數(shù),在Vue3中,事件處理就可以通過@click指令來實(shí)現(xiàn),下面我們就來看看如何在Vue3中處理點(diǎn)擊事件吧
    2023-08-08

最新評論