哈喽,各位掘金的 “码” 上少年!今天咱们不聊风花雪月,来聊聊 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