Vue3.2?中新出的Expose用法一覽
隨著Vue 3.2的發(fā)布,一個新的組合工具提供給我們,叫做 expose。
你是否曾經(jīng)創(chuàng)建過一個需要向模板提供一些方法和屬性的組件,但又希望這些方法對組件是私有的,不能被父類調(diào)用?
如果你在開發(fā)一個開源的組件或庫,你有可能想保持一些內(nèi)部方法的私有性。在Vue 3.2之前,這并不容易實現(xiàn),因為所有在選項API中聲明的方法或數(shù)據(jù)等都是公開的,所以模板可以訪問它。
組合API也是如此。我們從setup方法中返回的所有東西都可以被父類直接訪問。
組合 API
讓我們看一個實際的例子。想象一下,我們有一個組件,它創(chuàng)建了一個計數(shù)器,每一秒都會更新這個計數(shù)器。
** MyCounter.vue**
<template> <p>Counter: {{ counter }}</p> <button @click="reset">Reset</button> <button @click="terminate">??</button> </template> <script> import { ref } from 'vue' export default { setup () { const counter = ref(0) const interval = setInterval(() => { counter.value++ }, 1000) const reset = () => { counter.value = 0 } const terminate = () => { clearInterval(interval) } return { counter, reset, terminate } } } </script>
從組合的角度來看,我希望父級組件能夠在需要時直接調(diào)用reset?方法--但我希望保持terminate? 函數(shù)和 counter 的引用只對組件可用。
如果我們把這個組件實例化到一個父類中,例如 App.vue,并給它附加一個 ref 引用,我們可以很容易地讓父類調(diào)用 reset? 方法,因為當(dāng)我們從 setup? 中返回它時,它已經(jīng)和 terminate 一起被暴露了。
App.vue
<template> <MyCounter ref="counter" /> <button @click="reset">Reset from parent</button> <button @click="terminate">Terminate from parent</button> </template> <script> import MyCounter from '@/components/MyCounter.vue' export default { name: 'App', components: { MyCounter }, methods: { reset () { this.$refs.counter.reset() }, terminate () { this.$refs.counter.terminate() } } } </script>
如果現(xiàn)在運行這個,并單擊重置或終止按鈕,兩者都可以工作。
讓我們明確說明我們要向父類暴露(expose?)的內(nèi)容,以便只有 reset 函數(shù)可用。
** MyCounter.vue**
<script> import { ref } from 'vue' export default { setup (props, context) { const counter = ref(null) const interval = setInterval(() => { counter.value++ }, 1000) const reset = () => { counter.value = 0 } const terminate = () => { console.log(interval) clearInterval(interval) } context.expose({ reset }) return { counter, reset, terminate } } } </script>
這里,我們在setup?函數(shù)中加入了 props? 和 context? 參數(shù)。我們需要有可用的上下文,因為這是 expose? 函數(shù)的位置。我們也可以像這樣使用重構(gòu): { expose }。
接下來,我們使用 context.expose? 來聲明一個我們想要向?qū)嵗@個組件的父類公開的元素對象;在這個例子中,我們只打算讓 reset 功能可用。
如果我們再次運行這個例子,并點擊 "Terminate from parent" 按鈕,我們會得到一個錯誤。
Uncaught TypeError: this.$refs.counter.terminate is not a function
terminate 功能不再可用,我們的私有API現(xiàn)在也無法訪問了。
選項API
上面我們在 composition API? 使用 exponse,但在options API中也可以使用這個方法。我們可以把它改寫成如下。
// MyCounter.vue export default { created () { ... }, data: () => ({ counter: null }), methods: { reset () { ... }, terminate () { ... } }, expose: ['reset'] }
注意,我們添加了一個新的選項API屬性expose?,允許我們傳入一個數(shù)組,其中字符串'reset'是我們公開的函數(shù)的名稱。
組合API 渲染功能
創(chuàng)建一個強大臉靈活的組件的方法是利用渲染函數(shù)的力量。這對Vue 3來說并不新鮮,但是隨著composition API的建立,我們現(xiàn)在可以靈活地從setup?方法中直接返回組合API h 函數(shù)。
這就產(chǎn)生了一個問題,因為在我們的setup?函數(shù)中,整個return?語句只是包含組件正在創(chuàng)建的節(jié)點的 h 方法。
如果在這個時候我們選擇向父類 expose 一些東西,我們就會遇到與我們之前看到的相反的問題。沒有任何東西被暴露,因為除了DOM元素,沒有任何東西被返回。
讓我們重寫 MyCounter.vue 組件來使用這個方法。
<script> // The template has been deleted import { ref, h } from 'vue' export default { setup (props, context) { const counter = ref(0) const interval = setInterval(() => { counter.value++ }, 1000) const reset = () => { counter.value = 0 } const terminate = () => { clearInterval(interval) } // context.expose({ reset }) return () => h('div', [ h('p', `Counter: ${counter.value}`), h('button', { onClick: reset }, 'Reset'), h('button', { onClick: terminate }, 'Terminate') ]) } } </script>
注意,我們在頂部從Vue導(dǎo)入了 h,因為我們需要用它來創(chuàng)建我們的DOM元素。
為了說明問題,暫時注釋了context.expose方法。
現(xiàn)在的 return 語句復(fù)制了我們之前的 <template> 的DOM結(jié)構(gòu),如果我們運行這個例子,我們能夠正確點擊元素上的重置和終止按鈕。
然而,如果我們現(xiàn)在點擊 "Reset from parent"按鈕,我們會遇到一個錯誤。
Uncaught TypeError: this.$refs.counter.reset is not a function
reset?方法不再被暴露,因為它沒有被setup?函數(shù)返回。為了解決這個問題,我們需要取消對context.expose的調(diào)用,使其再次可用。
總結(jié)
新的 expose 方法是非常直觀的,而且很容易在我們的組件中實現(xiàn)。它清除了一些非常重要的組成問題,這些問題在過去甚至需要重寫一個完整的組件,所以即使它不是你日常使用的API,它也是值得收藏在我們文件夾中吃灰。
到此這篇關(guān)于Vue3.2 中新出的 Expose 是做啥用的?的文章就介紹到這了,更多相關(guān)Vue3.2 Expose 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue.JS實現(xiàn)垂直方向展開、收縮不定高度模塊的JS組件
這篇文章主要介紹了Vue.JS實現(xiàn)垂直方向展開、收縮不定高度模塊的JS組件,本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2018-06-06一文帶你了解什么是Vue的前端微服務(wù)架構(gòu)(Micro Frontends)
微前端架構(gòu)是一種將大型前端應(yīng)用拆分為多個小型、獨立的前端應(yīng)用的架構(gòu)風(fēng)格,每個小型前端應(yīng)用都可以獨立部署、獨立開發(fā)和獨立運行,下面我們就來學(xué)習(xí)一下它的相關(guān)使用吧2023-11-11TypeError:res.forEach?is?not?a?function報錯解決辦法
這篇文章主要給大家介紹了關(guān)于TypeError:res.forEach?is?not?a?function報錯的解決辦法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2023-07-07Vue3 directive自定義指令內(nèi)部實現(xiàn)示例
這篇文章主要為大家介紹了Vue3 directive自定義指令內(nèi)部實現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-12-12Vue3中是如何實現(xiàn)數(shù)據(jù)響應(yīng)式示例詳解
這篇文章主要介紹了Vue3中是如何實現(xiàn)數(shù)據(jù)響應(yīng)式示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-07-07vue中this.$message的實現(xiàn)過程詳解
Message在開發(fā)中的使用頻率很高,也算是Element-UI組件庫中比較簡單的,對于感興趣的朋友可以一起探討一下Message組件的實現(xiàn),本文詳細介紹了vue中this.$message的實現(xiàn)過程,感興趣的同學(xué)可以參考一下2023-04-04