Vue3 Hooks:听说你想“抄”React的作业? 但这回抄对了!
2025-01-08 09:51 阅读(140)

哈喽,各位掘金的 “码” 上少年!今天咱们不聊风花雪月,来聊聊 Vue 3 的 Hooks 这个“磨人的小妖精”。 啥?你问我为啥要聊 Hooks? 哎呦喂,这你就不懂了吧,这可是 Vue 3 的一大亮点,直接把 React 的 “钩子” 给 “借鉴” 了过来,但别急着吐槽,这次 Vue 可是“抄”对了,而且抄得还挺香!

从 “组件思维” 到 “功能思维”:这波操作有点骚!

以前我们写 Vue 组件,脑子里想的都是 “我要一个按钮,这个按钮要干嘛干嘛”, 这种“组件思维”就像是拿着一把锤子,看啥都像钉子。 现在有了 Hooks, 我们的思维方式就要转变成 “我要一个功能,这个功能可以在多个组件里复用”。 就像开挂一样,一下子从“组件思维”跳跃到了“功能思维”,是不是感觉自己瞬间升华了?

内存泄漏:别让你的代码“漏气”!

敲黑板!划重点!内存泄漏这个问题,就好比你家的水龙头没关紧,水一直流,最后水费单让你肉疼。在 Vue 中,如果你在组件里监听了一些事件,组件销毁时没把这些监听器给移除掉,那你的代码就会一直“耗内存”,慢慢地,你的应用就会变得卡顿,就像老牛拉破车一样。这可不是闹着玩的,所以记住,要及时清理战场,才能保证代码不“漏气”!


Tips:  就像我们代码里的onUnmounted函数一样, 组件卸载前,别忘了把事件监听给移除掉,不然你就等着被“内存泄漏”找上门吧!


ES6 模块化:让代码不再“孤单”!

在 Vue 3 的世界里,我们离不开 ES6 模块化,它就像是 “代码的社交圈”,让代码不再“孤单”。


import from:  就像从别人家借东西,import Obj from export default 就像借了别人家整套家具,而 import { A, B } from export 则像是借了别人家的几样“宝贝”。

export:  就像把自己的东西分享给别人,export default 是把自己的“传家宝”都拿出来,而 export 则是分享自己的“小物件”。


Hooks 编程风格:让代码更“优雅”!

Hooks 的出现,带来了函数式编程的清风,让代码更优雅,更易于维护。


useXXX 开头:  就像是武林秘籍的 “招式名”,一眼就知道这是个 Hook 函数。

响应式业务和 UI 分离:  Hooks 把 “状态” 和 “UI” 分开管理,就像把你的 “衣服” 和 “杂物” 分开收纳,让家里更整洁。

组件复用性高:  有了 Hooks,我们就可以把一些常用的 “功能” 封装起来,就像 “乐高” 一样,可以自由组合,大大提高了代码的复用性。

UI组件开发工程师:  有了Hooks之后,组件拆分为 UI界面 和 业务逻辑,UI组件开发工程师,可以更加专注于UI界面的开发,不用理会复杂的业务逻辑。


代码实战:Show Me The Code!

好了,说了这么多,也该上点干货了!我们来分析一下你提供的代码片段。

第一个例子:组件切换,展示鼠标位置

<script setup>
import mousepos from './components/MousePos.vue'
import { ref } from 'vue'
const showMouse = ref(true)
const toggleMouse = () =>{
    showMouse.value = !showMouse.value
}
</script>

<template>
  <div>
    <mousepos v-if="showMouse"/>
    <button @click="toggleMouse">切换显示</button>
  </div>
</template>

这个例子就像是一个“开关”,控制着 mousepos 组件的显示与隐藏。通过 v-if 指令,我们可以在 showMouse 为 true 时渲染 mousepos 组件,为 false 时则卸载该组件。这个 v-if 就相当于一个“清理工”,在组件卸载前把占用的内存都给释放了,防止内存泄漏。

第二个例子:使用 reactive 实现鼠标位置

<template>
  <div>
    <p>
      Mouse X: {{ mousePos.x }}
    </p>
    <p>
      Mouse Y: {{ mousePos.y }}
    </p>
  </div>
</template>

<script setup>
import {
  reactive,
  onMounted,    
  onUnmounted
} from 'vue'

const mousePos = reactive({
  x: 0,
  y: 0
})
const mousePosHandler=(e) =>{
    mousePos.x = e.clientX
    mousePos.y = e.clientY
    console.log('我还在'); // 看看自己是不是还活着!
}

onMounted(() =>{
  window.addEventListener('mousemove',mousePosHandler)
})
onUnmounted(() =>{
  window.removeEventListener('mousemove',mousePosHandler)
})
</script>

当组件没有被销毁时,这个我还在就会随着鼠标的改变而打印。

这个例子中,我们用 reactive 创建了一个响应式的 mousePos 对象,用来存储鼠标的位置。onMounted 和 onUnmounted 分别在组件挂载和卸载时执行, 负责添加和移除鼠标移动事件监听器,避免内存泄漏。

第三个例子:使用自定义 Hook useMouse 实现鼠标位置

注意:这个代码实现的功能是与上面的相同的。

<template>
  <div>
    <p>Mouse X: {{ x }}</p>
    <p>Mouse Y: {{ y }}</p>
  </div>
</template>

<script setup>
import { useMouse, useMemo } from '../hooks/useMouse.js';
import Hook from '../hooks/useMouse.js';
const { x, y } = useMouse();
useMemo();
console.log(Hook);
</script>

对应的 useMouse.js 文件:

import { ref, onMounted, onUnmounted } from 'vue'
export function useMouse() {
  const x = ref(0),
    y = ref(0);

  function update(e) {
    x.value = e.pageX;
    y.value = e.pageY;
  }
  onMounted(() => {
    window.addEventListener('mousemove', update);
  });
  onUnmounted(() => {
    window.removeEventListener('mousemove', update);
  });
  return { x, y };
}

export function useMemo() {
  console.log('Use Memo');
}
export default {
  name: 'useMouse'
}

这里我们是使用的ref来修饰响应式数据,在这里暂时体现不出来两者之间的优缺性,想要了解可以看看小编之前的文章响应式与父子组件交互

这个例子中,我们将鼠标位置的逻辑封装到了 useMouse 这个自定义 Hook 中,这样就可以在其他组件中直接复用这个 Hook,就像点外卖一样,方便快捷!


Tips:  注意看 useMouse 这个 Hook, 里面用了 ref 来定义响应式的数据,并且在 onMounted 和 onUnmounted 生命周期函数里添加和移除事件监听,完美避免了内存泄漏问题!


总结:Hooks,真香!

总而言之,Vue 3 的 Hooks 就像是一把“瑞士军刀”,让我们的代码更加灵活,更加模块化。它不仅“借鉴”了 React 的优秀特性,还结合了 Vue 本身的特点,让开发体验更上一层楼。

说了这么多, 你是不是也觉得 Hooks 真香?那就赶紧动手试试吧,相信你一定会爱上它!

希望这篇文章能让你对 Vue 3 的 Hooks 有更深入的了解,如果你觉得还不错,记得点赞收藏哦!我们下期再见!


作者:answerball

链接:https://juejin.cn