Hooks 在 React 与 Vue 中的应用
1.Hooks 的定义
React :Hooks 是一些可以在函数组件里“钩入” React state 及生命周期等特性的函数。
Vue :Hooks 是组合式 API 中的一系列提供了组件复用、状态管理等开发能力的方法。
从定义上来看,React 与 Vue 描述相似,都对 Hooks 的使用范围进行了限定且实现的功能也差不多。
2.Hooks 使用规则
2.1 命名规范
始终都以 use 开头,使用useXXX小驼峰 形式对其进行命名,因为在调用 hooks 函数时,用于
接收函数所返回的变量及方法,只在组件首次渲染的时候被创建,在下一次重新渲染时对数据进行更新。
2.2 使用范围
1)只能在函数最外层调用,不能在循环、条件判断或子函数中调用
2)对于 React 而言只能在函数组件和自定义 Hook 中调用 Hooks,而在 Vue 语法中只能在组合式 API 中调用
3. 产生的背景条件
3.1 组件状态的复用困难
在 class 组件模式下,很难实现状态逻辑的复用。虽然 Vue2 中的 mixin 可以实现,
但存在着this 的指向不明确、多组件方法或属性出现同名覆盖等众多弊端。
案例演示:
当组件实例创建时,需要创建一个 state 属性:count,并随机给此 count 属性附一个初始值。
除此之外,还得提供一个 setCount 方法。你可以在组件其他地方读取和修改此状态属性。
更重要的是: 这个逻辑要可以复用,在各种业务组件里复用此逻辑。
代码示例:
引入 Hooks 之前
使用 vue2 中 mixin 语法实现
//混入文件1:count1-mixin.js
export default {
data() {
return {
count: 0,
};
},
methods: {
setCount(count) {
this.count = count;
},
},
};
//混入文件2:count2-mixin.js
export default {
data() {
return {
count: 0,
age: 24,
[key]: "",
};
},
methods: {
setCount(count) {
this.count = count;
},
setAge(age) {
this.age = age;
},
},
};
// 混入文件3(动态生成mixin):getName-mixin.js
function getNameMixin(key, funcKey) {
return {
data() {
return {
[key]: ''
}
},
methods: {
[funcKey]: function(v) {
this.[key] = v
}
}
}
}
// 控制函数组件control-component.vue
<template>
<div>{{ count }}</div>
<template>
<script>
import countMixin1 from './count1-mixin';
import countMixin2 from './count2-mixin';
import getNameMixin from './getName-mixin';
export default {
mixins: [countMixin1,countMixin2,getNameMixin],
// 通过mixins, 你可以直接获得所有引入的文件中所定义的状态和方法还有生命周期中的事件等
mounted() {
setTimeout(() => {
this.setCount(this.count++)
}, 3000)
console.log(this.age)
// 此时很难判断this的指向
}
}
<script>
从上述代码可以看出,当 mixin 混入多个类组件时,存在如下弊端,
a:不能确定 this 的指向,难以追溯方法与属性的来源
b:多个类组件中,可能同时定义了相同的方法或属性,产生同名覆盖现象
c:动态生成 mixin,可实现逻辑的复用,但同时增加了程序的复杂性,降低了可读性。
引入 Hooks 后
使用vue 组合式API语法实现
setup(){
const useCount=(porps)=>{
let count=props
const setCount(){
count++
}
return [count,setCount]
}
const useAge=(porps)=>{
let age=props
const setAge(){
age=age+12
}
return [age,setAge]
}
const useAge=(key, funcKey)=>{
let [key]=v
[funcKey]: function(v) {
this.[key] = v
}
return [age,setAge]
}
// 实现状态传递
const { count, setCount } = useCount(0);
const { count, setAge } = useAge(12);
const { name, setName } = useName('张三',);
// 实现逻辑复用
const { name : firstName, setName : setFirstName } = useName({firstName:'张三',setFirstName:});
const { name : secondName, setName : setSecondName } = useName();
}
3.2 代码的组织分散化
react与vue通过使用hooks语法可将分散在data()、method()、created()等等各种声明周期内的代码块
根据各自功能属性进行整合在一起,使代码数据更具模块化,直观化。
3.3 友好的渐进式
无论是 vue 还是 react,都只是提供了 Hooks API,并表明其优缺点。并不一定要去使用它,你可以在编写项目时,
选择性的使用class组件或Hooks组件,或者同时使用都可,但几年来Hooks收到了各开发者的广泛关注,使用的人越来越多,已经掀起了使用Hooks的热潮。
4.Hooks 使用
使用须知:
在 react 项目中, react 的版本需要高于 16.8.0,才能使用 hook
而在 vue 项目中, vue3.x 是最好的选择,但 vue2.6+ 配合 @vue/composition-api,也可以使用。
4.1 React 中使用(仅支持函数式组件)
// reactHook.js
import { useState, useEffect } from "React";
export default () => {
// 通过 useState 可以创建一个 状态属性 和一个赋值方法
const [name, setName] = useState("");
// 通过 useEffect 可以对副作用进行处理
useEffect(() => {
console.log(name);
}, [name]);
// 通过 useMemo 能生成一个依赖 name 的变量 message
const message = useMemo(() => {
return `hello, my name is ${name}`;
}, [name]);
return <div>{message}</div>;
4.2 Vue 中使用(依赖组合式 API)
// vueHook.js
<template>
<div>
{{ message }}
</div>
</template>
<script setup>
import { computed, ref } from 'vue'
// 定义了一个 ref 对象
const name = ref('')
// 定义了一个依赖 name.value 的计算属性
const message = computed(() => {
return `hello, my name is ${name.value}`
})
</script>
5.自定义 Hook
在自定义 Hook 时,它不需要具有特殊的标识。可自由的决定它的参数和返回的值。它就像一个正常的函数。
但为了遵循 Hook 的规则,它的名字应该始终以 use 开头。
5.1 在react 中 Hook的定义及使用
//定义
function useComponent(props) {
const [isPlay, setIsPlay] = useState(false);
// ...
return isPlay;
}
//使用
function Component(props) {
const isPLay = useComponent(props.statu);
if (isPLay === false)
{
return "未挂载";
}
return "挂载成功";}
5.1 在vue 中 Hook的定义及使用
//定义 Component1.vue
import { ref, watch } from "vue";
export const useCount = () => {
const count = ref(0);
const x = ref(0);
const y = ref(0);
const setCount = () => {
count.value = count.value + 1;
};
watch([x, y], ([newX, newY], [oldX, oldY]) => {
console.log("newX+newY="+newX+newY);
console.log("oldX+oldY="+oldX+oldY);
});
return {
count,
x,
y,
setCount,
};
};
//使用 ControlComponent.vue
<script>
import { useCount } from "./Component1.vue";
export default {
setup() {
const { count, x, y, setCount } = useCount();
return { count, x, y, setCount };
},
};
</script>
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)