乐趣区

关于前端:掌握-Vue3-中的-expose

本文首发于微信公众号:大迁世界, 我的微信:qq449245884,我会第一工夫和你分享前端行业趋势,学习路径等等。
更多开源作品请看 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.vue


export 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。

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

原文:https://www.vuemastery.com/bl…

交换

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

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

退出移动版