Maison >interface Web >Voir.js >Qu'est-ce que l'exposition dans Vue3.2 ? A quoi ça sert ?
À quoi sert le nouvel exposé de Vue3.2 ? L'article suivant vous donnera une bonne compréhension de l'outil d'exposition de Vue3.2. J'espère qu'il vous sera utile !
Avec la sortie de Vue 3.2, un nouvel outil de composition nous est fourni appelé expose
. (Partage de vidéos d'apprentissage : vue vidéo tutoriel) expose
。(学习视频分享:vue视频教程)
你是否曾经创建过一个需要向模板提供一些方法和属性的组件,但又希望这些方法对组件是私有的,不能被父类调用?
如果你在开发一个开源的组件或库,你有可能想保持一些内部方法的私有性。在Vue 3.2之前,这并不容易实现,因为所有在选项API中声明的方法或数据等都是公开的,所以模板可以访问它。
组合API也是如此。我们从setup
方法中返回的所有东西都可以被父类直接访问。
让我们看一个实际的例子。想象一下,我们有一个组件,它创建了一个计数器,每一秒都会更新这个计数器。
** 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>
从组合的角度来看,我希望父级组件能够在需要时直接调用reset
方法--但我希望保持terminate
函数和 counter
的引用只对组件可用。
如果我们把这个组件实例化到一个父类中,例如 App.vue,并给它附加一个 ref 引用,我们可以很容易地让父类调用 reset
方法,因为当我们从 setup
中返回它时,它已经和 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>
如果现在运行这个,并单击重置或终止按钮,两者都可以工作。
让我们明确说明我们要向父类暴露(expose
)的内容,以便只有 reset
函数可用。
** 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
函数中加入了 props
和 context
参数。我们需要有可用的上下文,因为这是 expose
函数的位置。我们也可以像这样使用重构: { expose }
。
接下来,我们使用 context.expose
来声明一个我们想要向实例化这个组件的父类公开的元素对象;在这个例子中,我们只打算让 reset
功能可用。
如果我们再次运行这个例子,并点击 "Terminate from parent" 按钮,我们会得到一个错误。
Uncaught TypeError: this.$refs.counter.terminate is not a function
terminate
功能不再可用,我们的私有API现在也无法访问了。
上面我们在 composition API
使用 exponse
,但在options API中也可以使用这个方法。我们可以把它改写成如下。
// MyCounter.vue export default { created () { ... }, data: () => ({ counter: null }), methods: { reset () { ... }, terminate () { ... } }, expose: ['reset'] }
注意,我们添加了一个新的选项API属性expose
,允许我们传入一个数组,其中字符串'reset'
是我们公开的函数的名称。
创建一个强大脸灵活的组件的方法是利用渲染函数的力量。这对Vue 3来说并不新鲜,但是随着composition API的建立,我们现在可以灵活地从setup
方法中直接返回组合API h
函数。
这就产生了一个问题,因为在我们的setup
函数中,整个return
语句只是包含组件正在创建的节点的 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导入了 h
,因为我们需要用它来创建我们的DOM元素。
为了说明问题,暂时注释了context.expose
方法。
现在的 return 语句复制了我们之前的 <template>
的DOM结构,如果我们运行这个例子,我们能够正确点击元素上的重置和终止按钮。
然而,如果我们现在点击 "Reset from parent"按钮,我们会遇到一个错误。
Uncaught TypeError: this.$refs.counter.reset is not a function
reset
方法不再被暴露,因为它没有被setup
函数返回。为了解决这个问题,我们需要取消对context.expose
setup
est directement accessible par la classe parent. 🎜reset
directement en cas de besoin -- mais je souhaite conserver terminate et <code>counter
ne sont disponibles que pour les composants. 🎜🎜Si nous instancions ce composant dans une classe parent, telle que App.vue, et y attachons une référence ref, nous pouvons facilement laisser la classe parent appeler la méthode reset
, car lorsque nous le faisons est renvoyé par setup
, il a été exposé avec terminate
. 🎜🎜App.vue🎜rrreee🎜Si vous l'exécutez maintenant et cliquez sur le bouton de réinitialisation ou d'arrêt, les deux fonctionneront. 🎜🎜Indiquons explicitement ce que nous voulons exposer (expose
) à la classe parent afin que seule la fonction reset
soit disponible. 🎜🎜** MyCounter.vue**🎜rrreee🎜Ici, nous avons ajouté les paramètres props
et context
à la fonction setup
. Nous devons avoir le contexte disponible car c'est là que se trouve la fonction expose
. Nous pouvons également utiliser un refactoring comme celui-ci : {exposer
. 🎜🎜Ensuite, nous utilisons context.expose
pour déclarer un objet élément que nous voulons exposer à la classe parent qui instancie ce composant, dans cet exemple, nous allons uniquement faire reset est disponible. 🎜🎜Si nous exécutons à nouveau cet exemple et cliquons sur le bouton "Terminer depuis le parent", nous obtiendrons une erreur. 🎜rrreee🎜 La fonctionnalité <code>terminate
n'est plus disponible et notre API privée est désormais inaccessible. 🎜exponse
dans l'API de composition
, mais Cette méthode peut également être utilisée dans l'API d'options. Nous pouvons le réécrire comme suit. 🎜rrreee🎜Notez que nous avons ajouté un nouvel attribut API d'options expose
qui nous permet de passer dans un tableau où la chaîne 'reset'
est le nom de la fonction que nous exposons . 🎜h
de l'API de composition directement à partir de la méthode setup
. 🎜🎜Cela crée un problème car dans notre fonction setup
, l'intégralité de l'instruction return
contient simplement le h
du nœud que le composant crée. . 🎜🎜Si nous choisissons d'exposer quelque chose à la classe parent à ce stade, nous rencontrerons le problème inverse de ce que nous avons vu auparavant. Rien n'est exposé car rien n'est renvoyé à l'exception des éléments DOM. 🎜🎜 Remplaçons le composant MyCounter.vue
pour utiliser cette méthode. 🎜rrreee🎜 Notez que nous avons importé h
depuis Vue en haut car nous en avons besoin pour créer nos éléments DOM. 🎜🎜Pour illustrer le problème, la méthode context.expose
est temporairement commentée. 🎜🎜L'instruction return copie désormais la structure DOM de notre précédent <template>
et si nous exécutons cet exemple, nous pouvons cliquer correctement sur les boutons de réinitialisation et d'arrêt de l'élément. 🎜🎜Cependant, si nous cliquons maintenant sur le bouton "Réinitialiser depuis le parent", nous rencontrerons une erreur. 🎜rrreee🎜La méthode reset
n'est plus exposée car elle n'est pas renvoyée par la fonction setup
. Pour résoudre ce problème, nous devons annuler l'appel à context.expose
et le rendre à nouveau disponible. 🎜La nouvelle méthode expose
est très intuitive et facile à mettre en œuvre dans nos composants. Cela résout certains problèmes de composition très importants qui auraient nécessité la réécriture d'un composant entier dans le passé. Ainsi, même s'il ne s'agit pas d'une API que vous utilisez quotidiennement, cela vaut la peine de la collecter dans nos dossiers et de ramasser la poussière.
Texte original en anglais : https://www.vuemastery.com/blog/understanding-vue-3-expose/
[Tutoriels vidéo associés recommandés : Tutoriel d'introduction à vuejs, Démarrer avec le front-end Web ]
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!