vue3 自定义hooks / 可组合函数

vue3 composition api下mixins的替代方式(自定义hooks / 可组合函数)

传统方式下封装的mixins在引入文件里都是通过this来调用属性或方法,
而在vue3的composition API下this是undefined,实际上这两者就是冲突的,
只能封装一套全新的方式来使用类似mixins的功能。

我们称这种全新的方式为自定义hooks(注:写这篇文章时vue官方还没有这个概念,基本靠自己摸索,参照react的习惯而称之为自定义hooks,现在已经有了官方定义:可组合函数)。

一、mixins方式的痛点

传统的mixins有很多让人诟病的地方,mixins 的深度合并非常隐式,这让代码逻辑更难理解和调试,具体表现为如下几点:

  • mixins 容易冲突:因为每个特性的属性都被合并到同一个组件中,组件内同名的属性或方法会把mixins里的覆盖掉。
  • 可重用性有限:我们不能向 mixins 传递任何参数来改变它的逻辑,这降低了它们在抽象逻辑方面的灵活性。
  • 数据来源不清晰:组件里所使用的mixins里的数据或方法在当前组件代码里搜索不到,易造成错误的解读,比如被当成错误代码或冗余代码而误删。

二、传统mixins方式示例

myMixins.ts:

export default {
  data () {
    return {
      aa: 1
    }
  },

  mounted () {
    this.testFn()
  },

  methods: {
    testFn () {
      console.log('testFn')
    }
  }
}

index.vue:

<template>
  <div>{{ aa }}</div>
</template>

<script lang="ts">
import { defineComponent, onMounted } from 'vue'
import myMixins from './myMixins'

export default defineComponent({
  mixins: [myMixins],
  mounted () {
    console.log('index mounted')
  }
})
</script>

如上所示,封装的myMixins实际上只做了两件事,一是在mounted钩子函数里执行testFn方法,二是暴露一个aa的变量给外部使用;index.vue里引入后在dom里使用了aa。

这算是mixins最典型的两个用途,一是自己执行一些公共逻辑,外部引入时不用管,二是定义一些data变量给外部引入后使用。

三、自定义hooks方式示例

1、代码封装

先上代码,myHooks.ts:

import { ref, onMounted } from 'vue'

export default function () {
  const aa = ref(1)

  function testFn () {
    console.log('testFn')
  }

  onMounted(() => {
    testFn()
  })

  return {
    aa
  }
}

index.vue:

<template>
  <div>{{ aa }}</div>
</template>

<script lang="ts">
import { defineComponent, onMounted } from 'vue'
import myHooks from './myHooks'

export default defineComponent({
  setup () {
    const { aa } = myHooks()

    onMounted(() => {
      console.log('index mounted')
    })

    return {
      aa
    }
  }
})
</script>

可以看到,这里没有再使用mixins属性来引入逻辑代码,本质上只是封装了一个ts文件引入使用而已,这样使用后,数据来源清晰可见,代码引用有依有据。

2、为什么导出的是function

  • 因为导出为对象的话就意味着在import导入时就执行了封装的逻辑,而我们封装的逻辑是用composition api包装了的的特殊代码,这些代码只能在setup里才能正常使用,所以需要导出一个函数,这样就可以在组件setup里调用该函数来指定执行时机。
  • 导出为function还有一个用途是方便传参,这样可以在不同的组件引用时做一些差异化逻辑处理。

3、封装建议

  • 导出的function只需要return组件里要引用的数据;对于组件里不需要引用的就不需要return,组件里只调用导入的函数即可。
  • 组件里的自定义hooks调用代码最好放在setup里第一行位置,这样比较明确,不容易被遗漏。
  • 响应式api的使用风格保持统一,其实这也是整个项目风格统一的问题,对于setup里定义的数据做响应式处理,要么都用ref,要么都用reative,保持统一,这样在使用时不至于有的带.value有的不带。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值