1. useEffect
相当于vue中的哪些生命周期
在 React 中的表现,相当于 Vue 生命周期中的多个阶段,具体取决于你怎么使用它。我们可以根据不同用法来精确对应:
✅ 一张对照表:useEffect
对应 Vue 生命周期
useEffect 写法 |
对应 Vue 生命周期 | 说明 |
---|---|---|
useEffect(() => {}, []) |
onMounted |
组件挂载时执行(只执行一次) |
useEffect(() => fn) |
onMounted + onUpdated |
每次 render 后都会执行 |
useEffect(() => {}, [dep]) |
watch(dep) + onMounted |
依赖变化时执行,类似监听 |
useEffect(() => { return fn }, []) |
onUnmounted |
组件卸载前清理 |
useEffect(() => { return fn }, [dep]) |
watch(dep) + 清理副作用 |
监听变化 + 清理旧副作用 |
📌 对应示例解释
useEffect(() => {}, [])
⟶ 相当于 Vue 的onMounted
useEffect(() => {
console.log('组件挂载完成');
}, []);
等同于:
onMounted(() => {
console.log('组件挂载完成');
});
useEffect(() => {}, [count])
⟶ 相当于 Vue 的watch(count, fn)
useEffect(() => {
console.log('count 变化');
}, [count]);
等价于 Vue 的:
watch(count, () => {
console.log('count 变化');
});
useEffect(() => { return () => {...} }, [])
⟶ 相当于 Vue 的onUnmounted
useEffect(() => {
return () => {
console.log('组件即将卸载');
};
}, []);
等价于:
onUnmounted(() => {
console.log('组件即将卸载');
});
useEffect(() => {...})
(无依赖) ⟶ 类似onMounted + onUpdated
每次渲染都会执行一次:
useEffect(() => {
console.log('组件 render 完成');
});
Vue 中:
onMounted(() => {...})
onUpdated(() => {...})
总结一句话:
useEffect
是一个统一处理副作用逻辑的钩子函数,它可以根据依赖配置,实现 Vue 中的mounted
、updated
、watch
和unmounted
等生命周期行为。
2. Vue 2、Vue 3 和 React 组件通信
✅ Vue2、Vue3、React 组件通信方法总览
分类 | 方法名 | Vue2 | Vue3 | React | 适用场景 |
---|---|---|---|---|---|
父 → 子 | props |
✅ 支持 | ✅ 支持 | ✅ 支持 | 常见传值 |
子 → 父 | $emit / defineEmits |
✅ $emit |
✅ defineEmits |
✅ 通过回调函数 | 子传父方法、数据 |
兄弟组件 | EventBus / 状态管理 | ✅ EventBus | ✅ 状态管理 | ✅ 状态提升或 context | 无直接关系组件 |
跨层通信 | provide/inject | ✅ ✅ | ✅ ✅ | ✅ Context API | 跨多层级传值 |
全局共享 | Vuex / Pinia / Redux | ✅ Vuex | ✅ Pinia | ✅ Redux / Zustand | 跨组件共享数据 |
模板引用 | $refs / ref |
✅ $refs |
✅ ref() |
✅ ref + useRef |
访问子组件或DOM |
路由传参 | params / query |
✅ ✅ | ✅ ✅ | ✅ React Router | 页面跳转传参 |
插槽传值 | slots / scopedSlots | ✅ ✅ | ✅ 新写法 | ✅ children props | 内容分发 |
自定义 hooks | —— | — | ✅ 可封装 | ✅ useXXX 自定义hook |
抽象传值逻辑 |
🔸 一、Vue2 组件通信方法
✅ 1. props(父传子)
<!-- Parent.vue -->
<Child :msg="message" />
<!-- Child.vue -->
props: ['msg']
✅ 2. $emit(子传父)
<!-- Child.vue -->
this.$emit('sendData', data)
<!-- Parent.vue -->
<Child @sendData="handleData" />
✅ 3. EventBus(兄弟通信)
// bus.js
export default new Vue()
// 组件 A 发出
this.$bus.$emit('eventName', data)
// 组件 B 接收
this.$bus.$on('eventName', (data) => { ... })
✅ 4. provide / inject(跨层传值)
// 祖先组件
provide: {
themeColor: 'blue'
}
// 子孙组件
inject: ['themeColor']
🔸 二、Vue3 组件通信方法
✅ 1. props(父传子)& defineProps
<script setup>
const props = defineProps(['msg'])
</script>
✅ 2. defineEmits(子传父)
<script setup>
const emit = defineEmits(['submit'])
emit('submit', data)
</script>
✅ 3. provide / inject(组合式 API)
// 父组件
provide('theme', 'dark')
// 子组件
const theme = inject('theme')
✅ 4. 状态管理 Pinia(替代 Vuex)
// store.js
export const useCounter = defineStore('counter', {
state: () => ({ count: 0 })
})
// 在任意组件中
const counter = useCounter()
console.log(counter.count)
🔸 三、React 组件通信方法
✅ 1. props(父传子)
<Child title="Hello" />
function Child({ title }) {
return <h1>{title}</h1>
}
✅ 2. 回调函数(子传父)
<Child onSubmit={handleSubmit} />
function Child({ onSubmit }) {
onSubmit('data from child')
}
✅ 3. 状态提升(兄弟通信)
兄弟组件都将共享的 state 提升到最近公共父组件,由它负责管理。
✅ 4. Context(跨层传值)
// 创建上下文
const ThemeContext = createContext('light')
// Provider 包裹组件树
<ThemeContext.Provider value="dark">
<Child />
</ThemeContext.Provider>
// 子孙组件使用
const theme = useContext(ThemeContext)
✅ 5. Redux / Zustand(全局状态)
// Redux 示例
dispatch({ type: 'SET_USER', payload: user })
const user = useSelector(state => state.user)
✅ 6. useRef(访问 DOM 或子组件)
const inputRef = useRef()
<input ref={inputRef} />
✅ 7. children + 插槽式传参
<MyComponent>
<div>我就是 slot 的内容</div>
</MyComponent>
📌 总结思维导图(结构化理解)
父子通信:
- props(父传子)
- emit / 回调函数(子传父)
跨层通信:
- provide/inject(Vue)
- Context(React)
兄弟通信:
- EventBus / 状态提升 / 状态管理
全局共享:
- Vuex / Pinia / Redux
插槽通信:
- slot / scoped slot(Vue)
- children props(React)
访问组件或 DOM:
- $refs / ref() / useRef()