当Vue遇上Hooks,太润了

在这里插入图片描述

前言

Vue 中的 Hooks 也算是三年前的东西了,想当时在 React 中写 Hooks 函数算是比较流行的写法。Vue 中一直是 options 配置化写法,所有的钩子和数据都在一个对象中给你提供了,你只需要将你的数据和处理逻辑放到对应的框里面去。这也是Vue一直以来流行的原因之一了。简单。现在 Vue 也支持 Hooks 写法了,而且在工作中也用的比较多。

Mixins的痛点

Vue2 中如果要在组件层面进行功能模块的封装大多使用的是 Mixins 进行功能模块的封装。Mixins:混入。主要功能是将公共的函数方法加入到需要的组件中,可以将每个组件的生命周期或者是公共方法进行封装,组件在各自的生命周期内执行时。首先会执行 Mixins 中指定钩子的方法,然后执行组件中的方法。

// 创建 Mixin 对象
const myMixin = {
  data() {
    return {
      message: 'Hello, Mixins!'
    }
  },
  methods: {
    sayHello() {
      console.log(this.message);
    }
  }
}

// 应用 Mixin 到组件
const myComponent = Vue.extend({
  mixins: [myMixin],
  created() {
    this.sayHello(); // 输出 "Hello, Mixins!"
  }
})

如上所示。使用 Mixins 有一些优点,例如:

  • 提高代码复用性和可维护性。
  • 在多个组件之间共享和重用代码。

Mixins 的缺点最让我无法忍受:

  • 方法与属性难以追溯。
export default {
  mixins: [ a, b, c, d, e, f, g ], // 这表示它混入了很多能力
  mounted() {
    console.log(this.name)
    // 懵逼??!这个 this.name 来自于谁?
  }
}
  • 命名冲突和重复代码。
    当我想要复用两个使用 mixin 写的两个功能( a-name.js, b-name.js ),当然,正常看来直接引入就可以使用了,但是当这两个 mixin 写法的功能 心意相通 的时候定义了几个相同的变量时,我们心里就开始崩溃了(:tw-1f631:)。这时我就非常想要怀疑 mixin 是一种合理的共享复用功能的方法吗?

为什么使用 Hooks

“高度聚合,可阅读性提升”。伴随而来的便是 “效率提升,bug变少”。

对于 Vue 中的hooks ,有以下的定义:

在 vue 组合式API里,以 “use” 作为开头的,一系列提供了组件复用、状态管理等开发能力的方法。

hooks 在 Vue 中完全解决了mixin 写法的痛点。代码没有痛点,处处都是晴天 。Vue3 中的 hooks 相比于 Vue2 中的 mixin:

  • 方法和属性好追溯吗?这可太好了,谁产生的,哪儿来的一目了然。
  • 会有重名、覆盖问题吗?完全没有!内部的变量在闭包内,返回的变量支持 as 别名。
  • 多次使用?我直接梅开N度。
// 单个引入 变量 的写法
const { myName, getAge } = useUser();

// 梅开二度的写法
const { myName as firstName, get as firstGetAge } = useUser();

const { myName as secondName, get as secondGetAge } = useUser();

Hooks 基础用法示例

这是一个最简单的 useFoo hooks 实现的🌰。

// src/hooks/useFoo.ts
export function useFoo() {
    let message = '我是 useFoo 中的 message';

    function test() {
        console.log('useFoo 的 test');
    }
    return {
        message,
        test
    };
}

// App.vue
<script setup>
import { useFoo } from "./hooks/useFoo";
const { message: fooMessage, test } = useFoo();
</script>

<template>{{ fooMessage }}<button @click="test">按钮</button></template>

Hooks 搭配长步骤页面使用的示例

需求:

实现一个长步骤页面(一个步骤都是一个页面组件,每一步都有相对独立的逻辑处理,不同的场景下有不同的步骤组合)。

最初的实现:

将全部逻辑写到一个组件中,每一个步骤都通过 el-steps key 来控制,通过 v-if 来控制不同步骤下不同组件的现实。当然这样做也能实现,但是也需要将每一步骤的逻辑理清楚,不然写着写着一头雾水,真实手在前面写,脑子在后面追。而且当我写完了一个场景后,又提出一个新场景,然而步骤之间的组合却不相同,所以这种将所有步骤写在一个组件中的方法是行不通了。

使用hooks写法将逻辑分离

将每一个步骤拆分成一个步骤,一个步骤写成一个hooks,在不同的场景下,可以将其按照需求复用。

定义如下 hooks 函数
在这里插入图片描述

按照设计定义类似如下不同步骤,每个步骤拥有标识 key,每个步骤有上图所示独立的处理逻辑 hooks

// 上传
  const steps1 = [
    {
      title: '上传文件',
      key: 'upload-data-set',
    },
    {
      title: '预览数据',
      key: 'data-set-design',
    },
    {
      title: '数据集设置',
      key: 'create-data-set',
    },
  ];

  // 替换
  const steps2 = [
    {
      title: '上传文件',
      key: 'upload-data-set',
    },
    {
      title: '预览数据',
      key: 'data-set-design',
    },
    {
      title: '字段匹配',
      key: 'data-field-replace',
    },
  ];

接下来,只需要在每个步骤hooks中,对应的逻辑即可,以 useFieldUpload 为🌰:

// useFieldUpload.ts

import { computed, h, ref, watch } from 'vue';
import { useFieldPage } from './useFilePage';
// ...

export const useFileUpload = () => {
  
  // ... 逻辑
  
  return {
    // ...
  };
};

在 hooks 中使用 useRouter useRoute

useRouter 和useRoute 只能在 vue 的setup 函数中使用,如果需要在 hooks 中使用,直接引入相应的 hooks 会出现 undefined。 所以我们可以在写hooks 中,可以在定义时传入相应的配置值。
举个例子:

在这里插入图片描述

贴一些好用的Hooks库

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值