vue3 Hooks 和 mixin 区别

2021/06/11 vue 共 1960 字,约 6 分钟

背景

因为项目需要,写了自定义的hooks,写完之后发现,写法和mixin没有任何区别,只是在用的时候,语法有区别。那时候我就在想有了mixin为啥还要有hooks呢?他们在功能上是一样的,只是语法不一样。我很好奇为啥会这样

mixins 的信息

就是一个简单js文件,可以把逻辑相同的抽离出去,包括生命周期等函数,目的是方便逻辑复用。使用方法很简单,就一句话的事 mixins:[mixinsName]

在一定程度上,这个可以帮我们解决很大的问题,重复的东西不需要写多次,一般场景使用都没有任何问题。

但是事情总有但是,当项目发展到了一定的程度 mixins 限制了业务发展,而且让业务变得难以维护,比如说

  1. 变量来源不明确(隐式传入),不利于阅读,使代码变得难以维护。组件里可以引入多个mixin,并直接隐式调用mixin里的变量/方法,这会让我们有时候混乱 这些变量/方法 分别是哪个mixin里的?

  2. 多个mixins的生命周期会融合到一起运行,但是同名属性、同名方法无法融合,可能会导致冲突。

  3. mixins和组件可能出现多对多的关系,复杂度较高(即一个组件可以引用多个mixins,一个mixins也可以被多个组件引用)

  4. Mixin 很容易发生冲突:因为每个 mixin 的 property 都被合并到同一个组件中,所以为了避免 property 名冲突,你仍然需要了解其他每个特性。

  5. 可重用性有限:我们不能向 mixins 传递任何参数来改变它的逻辑,这降低了它们在抽象逻辑方面的灵活性。

遇到问题总是要解决,于是 vue3 引入了自定义hooks来解决这个问题

vue3 自定义hooks

自定义hook的作用类似于vue2中的mixin技术,但是他成功的解决了mixin的痛点,很清楚复用功能代码的来源, 更清楚易懂,而且可以给暴露出来的方法函数传递参数,利用的是Vue3的组合API封装的可复用的功能函数。

投入实际开发中后,觉得很棒,很有意思。然后查看文档,文档里面提到了,建议我们使用自定义hook替换

没有截图代码,没有对比,我懒了。后面的参考文章里面提到了,可以看看

import { reactive } from 'vue'
export interface PaginationParam {
  total: number
  current: number
  pageSize: number
  hideOnSinglePage: boolean
}
export function usePagination(): PaginationParam {
  return reactive<PaginationParam>({
    total: 0,
    current: 1,
    pageSize: 20,
    hideOnSinglePage: true,
  })
}

使用方式
import { usePagination } from '@/hooks/usePagination'
const pagination = usePagination()

// pagination 就和 mixin差不多一个意思了

vue3的hooks不仅可以做数据共享,还能做组件挂载,比如

import { type ComponentPublicInstance, createApp, nextTick } from 'vue'
import Toast, { type ToastOptions } from 's/Toast.vue'

interface ToastInstance extends ComponentPublicInstance {
  show: (options: ToastOptions) => void
}

let p: Promise<void> | null = null
let instance: ToastInstance | null = null

async function init(): Promise<void> {
  const app = createApp(Toast)
  const container = document.createElement('div')
  return nextTick(() => {
    instance = app.mount(container) as ToastInstance
    const $reader = document.body
    $reader?.appendChild(container)
  })
}

export function useToast(options: ToastOptions): void {
  if (!p) {
    p = init()
  }
  p?.then(() => instance?.show(options))
}

参考资料

vue3.0 composition api下mixins的替代方式(自定义hooks)

Vue2/Vue3中的代码逻辑复用对比(mixins、自定义hook)

Mixin


在技术的历史长河中,虽然我们素未谋面,却已相识已久,很微妙也很知足。互联网让世界变得更小,你我之间更近。

在逝去的青葱岁月中,虽然我们未曾相遇,却共同经历着一样的情愫。谁的青春不曾迷茫或焦虑亦是无奈,谁不曾年少过

在未来的日子里,让我们共享好的文章,共同学习进步。有不错的文章记得分享给我,我不会写好的文章,所以我只能做一个搬运工

我叫 sunseekers(张敏) ,千千万万个张敏与你同在,18年电子商务专业毕业,毕业后在前端搬砖

如果喜欢我的话,恰巧我也喜欢你的话,让我们手拉手,肩并肩共同前行,相互学习,互相鼓励

文档信息

Search

    Table of Contents