作者:Marina Mosti
译者:前端小智
来源:vuemastery

有梦想,有干货,微信搜索 【大迁世界】 关注这个在凌晨还在刷碗的刷碗智。

本文 GitHub https://github.com/qq449245884/xiaozhi 已收录,有一线大厂面试完整考点、资料以及我的系列文章。

随着Vue 3.2的发布,一个新的组合工具提供给我们,叫做 expose

你是否曾经创建过一个需要向模板提供一些方法和属性的组件,但又希望这些方法对组件是私有的,不能被父类调用?

如果你在开发一个开源的组件或库,你有可能想保持一些内部方法的私有性。在Vue 3.2之前,这并不容易实现,因为所有在选项API中声明的方法或数据等都是公开的,所以模板可以访问它。

组合API也是如此。我们从setup方法中返回的所有东西都可以被父类直接访问。

组合 API

让我们看一个实际的例子。想象一下,我们有一个组件,它创建了一个计数器,每一秒都会更新这个计数器。

** 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函数中加入了 propscontext 参数。我们需要有可用的上下文,因为这是 expose 函数的位置。我们也可以像这样使用重构: { expose }

接下来,我们使用 context.expose 来声明一个我们想要向实例化这个组件的父类公开的元素对象;在这个例子中,我们只打算让 reset 功能可用。

如果我们再次运行这个例子,并点击 “Terminate from parent” 按钮,我们会得到一个错误。

Uncaught TypeError: this.$refs.counter.terminate is not a function

terminate 功能不再可用,我们的私有API现在也无法访问了。

选项API

上面我们在 composition API 使用 exponse,但在options API中也可以使用这个方法。我们可以把它改写成如下。

//  MyCounter.vueexport default {created () { ... },data: () => ({ counter: null }),methods: {reset () { ... },terminate () { ... }},expose: ['reset']
}

注意,我们添加了一个新的选项API属性expose,允许我们传入一个数组,其中字符串'reset'是我们公开的函数的名称。

组合API 渲染功能

创建一个强大脸灵活的组件的方法是利用渲染函数的力量。这对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的调用,使其再次可用。

总结

新的 expose 方法是非常直观的,而且很容易在我们的组件中实现。它清除了一些非常重要的组成问题,这些问题在过去甚至需要重写一个完整的组件,所以即使它不是你日常使用的API,它也是值得收藏在我们文件夹中吃灰。


代码部署后可能存在的BUG没法实时知道,事后为了解决这些BUG,花了大量的时间进行log 调试,这边顺便给大家推荐一个好用的BUG监控工具 Fundebug。

原文:https://www.vuemastery.com/blog/understanding-vue-3-expose/

Vue3.2 中新出的 expose 是做啥用的?相关推荐

  1. 在vue3+vite中引入高德开放平台API实现边界范围多边形的绘制

    在vue3+vite中引入高德开放平台API实现边界范围多边形的绘制 1,先去高德地图开放平台申请账号注册流程不再赘述; 2,在我的应用中创建key,选择web端Js点击提交生成; 3,生成后可以看到 ...

  2. vue3.0中setup使用(两种用法)

    这篇文章主要介绍了vue3.0中setup使用,本文通过两种用法给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下 一.setup函数的特性以及作用 可以确定的是 V ...

  3. 电路设计中三极管和MOS管做开关用时的区别

    在做电路设计中三极管和MOS管做开关用时候有什么区别工作性质: 1.三极管用电流控制,MOS管属于电压控制. 2.成本问题:三极管便宜,MOS管贵. 3.功耗问题:三极管损耗大. 4.驱动能力:MOS ...

  4. PHP中Header函数和PHP_AUTH_USER做用户验证

    php Header PHP_AUTH_USER PHP_AUTH_PW 用户验证 在php中,可以使用Header函数做一些有趣的事情,用户验证就是其中一个很有意思的功能.具体用法: Header( ...

  5. vue3.0中使用Element-plus默认英文组件修改为中文

    vue3.0中使用Element-plus默认英文组件修改为中文修改方法 说明:本方法Element-plus 1.0.2-beta.59 之前的版本可以,1.0.2-beta.59之后版本请看下一篇 ...

  6. 传统到敏捷的转型中,谁更适合做Scrum Master?

    摘要:本文主要讲述的是从传统到敏捷Scrum团队转型中,对Scrum Master这一角色的分析. 本文分享自华为云社区<传统到敏捷的转型中,谁更适合做Scrum Master?>,作者: ...

  7. [VUE3]vue2.x中slot-scope插槽在vue3.x中的写法(以elementPlus和AntDesign为例)

    [VUE3]vue2.x中slot-scope插槽在vue3.x中的写法 elementUI vue2.x的写法 <el-table-column label="测试" al ...

  8. vue2.x中slot-scope插槽在vue3.x中的新写法

    vue2.x中slot-scope插槽在vue3.x中的新写法 1.vue2.x的写法 <el-table-column label="测试" align="cen ...

  9. 怎么将计算机恢复到前一天的状况,excel表格恢复前一天数据-我想将excel表格中的两组数据做对比(数据是每天变......

    我想将excel表格中的两组数据做对比(数据是每天变... Office2003以上的版本"灾难恢复"已经做得很,每次开一个Office文档时,都会个对应的临时文件. 这个文件会实 ...

最新文章

  1. WinDbg安装与使用
  2. Linux配置协同工作目录,Linux学习二:文件权限与目录配置
  3. P1019 单词接龙 (DFS)
  4. Apache Kylin的核心概念
  5. LiveVideoStackCon2021音视频技术大会北京站Day2
  6. 一个能够保护个人收藏夹隐私的Chrome扩展
  7. 华为任职资格_看了华为的任职资格体系,你就明白员工为啥这么拼?
  8. redis+mysql几种用法
  9. 使用Python进行多项式Lo​​gistic回归
  10. 明尼苏达大学博导“约法十章”火了:没事不乱开会、合写论文不要催导师,复旦教授直呼值得学习...
  11. 【运维】linux shell 编程之函数使用
  12. GIS招聘 | 甘肃、海南、辽宁、内蒙古地震局
  13. Win系统 - 电脑一直停在正在关机的界面怎么办?
  14. iphone视频照片恢复
  15. 轮循与连接-- 细雪之舞
  16. word转pdf的几种方法
  17. 解决:win10打印机连上,但是控制面板显示未指定
  18. 10+编程语言实现云笔记
  19. 华硕Eee PC 1001HA拆机指南 如何拆机,看这里
  20. 多层路由器端口映射设置

热门文章

  1. mysql存储过程fetch into_存储过程fetch into
  2. 银行视频监控系统解决方案
  3. Android JNI调用OpenCV,长时间运行内存异常,导致闪退的log分析和解决---(ReferenceTable overflow (max=1024)造成的)
  4. HCIA物联网初级考试-第三章物联网行业应用与解决方案及物联网安全
  5. 自然常数e的c语言程序设计,关于自然对数 e
  6. CSDN的博客积分计算规则及博客排名规则
  7. 在网页上实现加入收藏夹或书签功能
  8. Hbase中的Column Family
  9. JedisConnectionException: java.net.ConnectException: Connection refused
  10. Nginx配置中的80端口