Vue 3组合式API自定义Hook设计模式谈

前言

之前我写了一篇《为什么说组合式API解决了mixins的痛点?》,介绍了一下如何用函数封装代码,这种封装没什么深奥的道理,它既不属于构造函数,也不属于面向对象,顶多就是个闭包。它类似于React里的自定义Hook。

为什么Vue 2没人提到这种简单的设计模式?

原因也很简单,Vue 2的数据响应式基于Vue实例,任何数据都是实例上的数据,所以只能引入另一个.vue文件,做一次选项合并,而不能把数据和方法独立成.js文件。现在Vue 3的数据响应式基于Proxy,不依赖Vue实例,当然就可以写独立.js文件然后引入了。

那么,函数封装的模式,是不是可以用在组合式API里呢?当然能,而且也是推荐做法。

题目

比如现在一个组件,引入了3个Dialog子组件,我要为它们提供title、opened状态、submitDisabled(用来控制按钮是否可点击)……等等,还要提供几个方法。这三个Dialog组件的样子和代码各异,不适合合并。

代码怎么写?

按照基础教程,你要写let aDialogTitle = ...let bDialogTitle = ...let cDialogTitle = ...,是不是想死?

于是你打算试试设计模式,写成let aDialog = {title: ..., opened: ...}let bDialog = {title: ..., opened: ...}let cDialog = {title: ..., opened: ...},这特么跟选项式API也没什么区别,干嘛还要用组合式API呢?

于是你甚至打算用构造函数……打住,没那么复杂,用闭包就可以了。

方案

基础代码是这样:

let aDialogTitle = ...;
let aDialogOpened = ...;

function openADialog() {
  //...
}

闭包写法是这样:

function useADialog() {
  let title = ...;
  let opened = ...;

  function openDialog() {
    //...
  }

  return reactive(ADialog: {title, opened, openDialog});
}