日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

徹底搞清楚Vue3的DefineExpose宏是如何暴露方法給父組件使用

來源: 責編: 時間:2024-05-28 09:07:05 160觀看
導讀前言眾所周知,當子組件使用setup后,父組件就不能像vue2那樣直接就可以訪問子組件內的屬性和方法。這個時候就需要在子組件內使用defineExpose宏函數來指定想要暴露出去的屬性和方法。這篇文章來講講defineExpose宏函數

前言

眾所周知,當子組件使用setup后,父組件就不能像vue2那樣直接就可以訪問子組件內的屬性和方法。這個時候就需要在子組件內使用defineExpose宏函數來指定想要暴露出去的屬性和方法。這篇文章來講講defineExpose宏函數是如何暴露出去這些屬性和方法給父組件使用。注:本文中使用的vue版本為3.4.19。ZEd28資訊網——每日最新資訊28at.com

看個demo

父組件index.vue的代碼如下:ZEd28資訊網——每日最新資訊28at.com

<template>  <ChildDemo ref="child" />  <button @click="handleClick">調用子組件的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拿到子組件的實例賦值給child變量。然后在按鈕的click事件中打印出子組件的validate方法和執行validate方法。ZEd28資訊網——每日最新資訊28at.com

再來看看子組件child.vue不使用defineExpose宏的例子,代碼如下:ZEd28資訊網——每日最新資訊28at.com

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

在瀏覽器中點擊父組件的button按鈕,可以看到控制臺中打印的是undefined,并且子組件內的validate方法也沒有執行。因為子組件使用了setup,默認是不會暴露setup中定義的屬性和方法。如下圖:ZEd28資訊網——每日最新資訊28at.com

圖片圖片ZEd28資訊網——每日最新資訊28at.com

我們再來看看子組件child.vue使用defineExpose宏的例子,代碼如下:ZEd28資訊網——每日最新資訊28at.com

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

在瀏覽器中點擊父組件的button按鈕,可以看到控制臺中打印的不再是undefined,子組件內的validate方法也執行了。如下圖:ZEd28資訊網——每日最新資訊28at.com

圖片圖片ZEd28資訊網——每日最新資訊28at.com

編譯后的代碼

首先需要在瀏覽器中找到編譯后的使用defineExpose宏的child.vue文件,在network面板中找到child.vue,然后右鍵點擊Open in Sources panel就可以在source面板中找到編譯后的child.vue。如下圖:ZEd28資訊網——每日最新資訊28at.com

圖片圖片ZEd28資訊網——每日最新資訊28at.com

為了要在瀏覽器中debug,我們還需要在設置中關閉瀏覽器的javascript source map,如下圖:ZEd28資訊網——每日最新資訊28at.com

圖片圖片ZEd28資訊網——每日最新資訊28at.com

現在我們來看看編譯后的child.vue文件,代碼如下:ZEd28資訊網——每日最新資訊28at.com

const _sfc_main = {  __name: "child",  setup(__props, { expose: __expose }) {    function validate() {      console.log("執行子組件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對應的就是我們源代碼<script setup>中的內容,并且defineExpose宏函數也不在了,變成了一個__expose方法(defineExpose宏函數如何編譯成__expose方法我們會在下一篇文章講)。如下圖:ZEd28資訊網——每日最新資訊28at.com

圖片圖片ZEd28資訊網——每日最新資訊28at.com

expose方法

給__expose方法打個斷點,刷新頁面此時斷點停留在__expose方法上面。點擊step into進入到__expose方法內部,如下圖:ZEd28資訊網——每日最新資訊28at.com

圖片圖片ZEd28資訊網——每日最新資訊28at.com

進入到__expose方法內部,我們發現__expose方法是在一個createSetupContext函數中定義的。在我們這個場景中createSetupContext函數簡化后的代碼如下:ZEd28資訊網——每日最新資訊28at.com

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

我們先來看看函數中的instance變量,我想你通過名字應該已經猜到了他就是當前vue實例對象。如下圖:ZEd28資訊網——每日最新資訊28at.com

圖片圖片ZEd28資訊網——每日最新資訊28at.com

在vue實例對象中有我們熟悉的data方法、directives和componens屬性等。ZEd28資訊網——每日最新資訊28at.com

在expose函數內部做的事情也很簡單,將子組件需要暴露的屬性或者方法組成的對象賦值給vue實例上的exposed屬性。ZEd28資訊網——每日最新資訊28at.com

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

在vue3中想要訪問子組件需要使用特殊的 ref attribute,在我們這個例子中就是使用<ChildDemo ref="child" />。這樣使用后就可以使用child變量訪問子組件,其實在這里child變量的值就是一個名為getExposeProxy函數的返回值(后面的文章中會去詳細講解ref attribute是如何訪問子組件)。ZEd28資訊網——每日最新資訊28at.com

getExposeProxy函數的代碼如下:ZEd28資訊網——每日最新資訊28at.com

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宏函數中定義了想要暴露出來的屬性和方法,經過編譯后defineExpose宏函數變成了__expose方法。執行__expose方法后會將子組件想要暴露的屬性或者方法組成的對象賦值給vue實例上的exposed屬性,也就是instance.exposed。ZEd28資訊網——每日最新資訊28at.com

在上面的getExposeProxy函數中就是返回了instance.exposed的Proxy對象,當我們使用child.value.validate訪問子組件的validate方法,其實就是訪問的是instance.exposed對象中的validate方法,而instance.exposed中的validate方法就是defineExpose宏函數暴露的validate方法。如下圖:ZEd28資訊網——每日最新資訊28at.com

圖片圖片ZEd28資訊網——每日最新資訊28at.com

總結

父組件想要訪問子組件暴露的validate方法主要分為下面四步:ZEd28資訊網——每日最新資訊28at.com

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

點擊下方卡片關注我,給自己一個進階vue的機會。ZEd28資訊網——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-91161-0.html徹底搞清楚Vue3的DefineExpose宏是如何暴露方法給父組件使用

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 從基礎概念到進階思考,完整的遞歸思維學習

下一篇: Python 操作系統交互的 15 個實用命令

標簽:
  • 熱門焦點
  • 6月安卓手機好評榜:魅族20 Pro蟬聯冠軍

    性能榜和性價比榜之后,我們來看最后的安卓手機好評榜,數據來源安兔兔評測,收集時間2023年6月1日至6月30日,僅限國內市場。第一名:魅族20 Pro好評率:95%5月份的時候魅族20 Pro就是
  • Raft算法:保障分布式系統共識的穩健之道

    1. 什么是Raft算法?Raft 是英文”Reliable、Replicated、Redundant、And Fault-Tolerant”(“可靠、可復制、可冗余、可容錯”)的首字母縮寫。Raft算法是一種用于在分布式系統
  • CSS單標簽實現轉轉logo

    轉轉品牌升級后更新了全新的Logo,今天我們用純CSS來實現轉轉的新Logo,為了有一定的挑戰性,這里我們只使用一個標簽實現,將最大化的使用CSS能力完成Logo的繪制與動畫效果。新logo
  • 如何正確使用:Has和:Nth-Last-Child

    我們可以用CSS檢查,以了解一組元素的數量是否小于或等于一個數字。例如,一個擁有三個或更多子項的grid。你可能會想,為什么需要這樣做呢?在某些情況下,一個組件或一個布局可能會
  • 三萬字盤點 Spring 九大核心基礎功能

    大家好,我是三友~~今天來跟大家聊一聊Spring的9大核心基礎功能。話不多說,先上目錄:圖片友情提示,本文過長,建議收藏,嘿嘿嘿!一、資源管理資源管理是Spring的一個核心的基礎功能,不
  • 這款新興工具平臺,讓你的電腦效率翻倍

    隨著信息技術的發展,我們獲取信息的渠道越來越多,但是處理信息的效率卻成為一個瓶頸。于是各種工具應運而生,都在爭相解決我們的工作效率問題。今天我要給大家介紹一款效率
  • 一個注解實現接口冪等,這樣才優雅!

    場景碼猿慢病云管理系統中其實高并發的場景不是很多,沒有必要每個接口都去考慮并發高的場景,比如添加住院患者的這個接口,具體的業務代碼就不貼了,業務偽代碼如下:圖片上述代碼有
  • 為什么你不應該使用Div作為可點擊元素

    按鈕是為任何網絡應用程序提供交互性的最常見方式。但我們經常傾向于使用其他HTML元素,如 div span 等作為 clickable 元素。但通過這樣做,我們錯過了許多內置瀏覽器的功能。
  • 共享單車的故事講到哪了?

    來源丨??素斀浥c共享充電寶相差不多,共享單車已很久沒有被國內熱點新聞關照到了。除了一再漲價和用戶直呼用不起了。近日多家媒體再發報道稱,成都、天津、鄭州等地多個共享單
Top 主站蜘蛛池模板: 轮台县| 台湾省| 攀枝花市| 秭归县| 邵阳市| 新化县| 保定市| 大连市| 郯城县| 宜阳县| 治县。| 罗甸县| 镇平县| 宿松县| 大安市| 墨脱县| 扬州市| 和硕县| 濮阳市| 噶尔县| 会同县| 安康市| 章丘市| 习水县| 乳山市| 玉门市| 赣州市| 平南县| 外汇| 岳阳市| 庆元县| 攀枝花市| 乃东县| 安康市| 阜阳市| 图们市| 富裕县| 都匀市| 巴彦淖尔市| 育儿| 乐陵市|