从写React Hooks到Vue3 JSX
前言
本人写了2年多的React hooks,最近新单位用的框架是Vue3所以转为Vue3技术栈,仅此记录本人从React开发转为Vue3开发的短期内自学的核心要点。鉴于本人水平有限,难以避免错误或者遗漏,请大佬们多多指教。
React业务代码日常使用jsx去写,Vue3则是template,当然也可以使用jsx,本文所有示例代码都是Vue+jsx的。
1. 状态变量
1.1 变量声明
React通过const [count, onChange] = useState()
来创建一个状态变量,vue则通过const count = ref()
或者const countContainer = reactive({count: null})
来创建变量,考虑到一开始接触vue3,ref和reactive的处理方式不同,会显著增加大脑负担,建议新手直接全部用ref声明变量,并用类似count.value
来调用。
1.2 变量改变
React可通过调用变更函数onChange(newCount)
来改变原count的值,在vue中可以直接通过赋值进行改变,count.value = newCount
2. 父子组件传值
React的父子组件传值,直接通过给子组件加属性就可以完成。
考虑如下React组件:
const [count, onChange] = useState();
return <Child count={count} onChange={onChange} />
比如父组件声明需要传递给子组件的变量,子组件通过props.count
和props.onChange
取值即可,但是Vue相对来说复杂得多。
对比如下Vue父组件场景:
const count = ref();
const onChange = (v) => {count.value = v};
return () => <Child count={count.value} onChange={onChange} />
子组件要通过声明props和emits来取值:
export default defineComponent({
props: ["count"],
emits: ["change"],
setup: (props, {emit, attrs}) => {
const changeCount = () => {
emit('change', props.count + 1)
}
return () => <button onClick={changeCount}>加1</button>
}
})
这里Vue会自动截取带on的函数名,从onChange -> change。
还有一种是Vue双向绑定的写法,父组件用v-model绑定属性,子组件用update去改变状态。
例如,父组件给子组件绑定方法:
<Child v-model:count={count.value} />
子组件的处理方式:
export default defineComponent({
props: ["count"],
emits: ["update:count"],
setup: (props, {emit, attrs}) => {
const changeCount = () => {
emit("update:count", props.count + 1)
}
return () => <button onClick={changeCount}>加1</button>
}
})
3. 组件刷新
React默认在props改变时,会自动刷新组件,调用组件函数来刷新所有状态,Vue没有这个机制(这也意味着useCallback和useMemo在Vue中不需要对应的方法)。如果props有变化,需要相对应的状态变量一起变化,需要通过监听来改变其他的状态。
考虑如下React场景:
const countRelated = props.count + 1;
return <div>{countrelated}</div>
Vue需要这样来使用:
const countRelated = ref(0);
watch(() => props.count, (val) => {
countReacted.value = val;
});
return () => <div>{countRelated.value}</div>
包括当使用React的useEffect用于监听变量改变,也应该用Vue的watch去写。
4. 副作用
React的useEffect会在3个情况下触发,组件渲染完成/依赖项变化/组件销毁,这里Vue需要分别对3种情况进行处理,分别是onMounted/watch/beforeUnmount。
考虑如下React场景:
const Ele = ({id}) => {
const getDetail = async () => {};
useEffect(() => {
// 依赖型变化
getDetail(id);
}, [id]);
useEffect(()=> {
// 组件渲染完毕
let timer = setInterval(() => {
console.log(1);
}, 1000);
// 组件销毁
return () => {
clearInterval(timer);
timer = null;
}
}, []);
return <div />
}
对应Vue代码:
export default defineComponent({
props: ["id"],
setup: (props, {emit, attrs}) => {
const timer = ref();
const getDetail = async () => {};
watch(() => props.id, (val) => {
// 依赖项变化
getDetail(val)
}, { immediate: true });
onMounted(()=>{
// 组件渲染完毕
timer.value = setInterval(() => {
console.log(1)
}, 1000)
});
beforeUnmount(()=>{
clearInterval(timer.value)
timer.value = null
});
return () => <div />
}
})
总结
React hooks和Vue3 组合API在写法上非常相似,React hooks最核心的api均可在Vue找到对应处理方法,只要注意到少许的不同点,切换技术栈的速度可以相当快。
转载自:https://juejin.cn/post/7235091963313717309