1. 前言说明
由于Vue的学习成本低,曲线更加平滑,操心事情少等特点,很受新入坑的小伙伴学习。
很多小伙伴都会深受Vue的思想的影响,在学习React的时候会问出:
当学了React以后,你是不是经常有这样的疑惑:
那是因为Vue这个大保姆帮我们做了很多很多。。。
这里就给大家罗列出一些经常用到的功能的实现,便于大家快速适应React开发。
2. 模板语法中的语法糖
2.1 template逻辑块包裹
- 空标签
<>
<div className={styles.logTitle}>错误描述</div>
<ul>
<li className={styles.logError}>{installErr}</li>
</ul>
</>
- Fragment
<Fragment>
<div className={styles.logTitle}>错误描述</div>
<ul>
<li className={styles.logError}>{installErr}</li>
</ul>
</Fragment>
2.1 v-if/v-else-if
- 简单判定使用
三元表达式
{curAppState === AppInstallStepState.FAILED ? (
<>
<div className={styles.logTitle}>错误描述</div>
<ul>
<li className={styles.logError}>{installErr}</li>
</ul>
</>
) : null}
- 复杂逻辑写
render***函数
const renderOper = (renderState: AppInstallStepState) => {
let operTxt;
let operDom;
if (isActive) {
operDom = (
<>
<Icon type="check-circle" style={{ color: 'green', fontSize: '50px' }} />
<div>当前版本</div>
</>
);
} else {
switch (renderState) {
case AppInstallStepState.NOT_STARTED: {
operTxt = '安装';
break;
}
case AppInstallStepState.RUNNING: {
operTxt = '正在安装';
break;
}
case AppInstallStepState.FAILED: {
operTxt = '重新安装';
break;
}
case AppInstallStepState.SUCCESS: {
operTxt = '安装';
break;
}
default: {
operTxt = '安装';
}
}
operDom = (
<Button type="primary" disabled={isLocked} loading={renderState === AppInstallStepState.RUNNING} onClick={handleInstall}>
{operTxt}
</Button>
);
}
return operDom;
};
...
...
...
<div>{renderOper(curAppState)}</div>
2.3 v-for
- 利用
map函数既遍历又返回的特点
<Steps
current={getStepIndex()}
progressDot={customDot}
className={styles.installSteps}
>
{stepList.map((curStep: IInstallStepAttr) => (
<Steps.Step title={curStep.stepName} description="" />
))}
</Steps>
2.4 @onXXX($on) / $emit
- 通过props传递回调函数
- 一般约定回调函数使用
onXXX的命名方式,提高可阅读性 - 需要考虑结合
useCallback+useMemo来减少不必要的子组件渲染
2.5 :class
- className结合插件
classNames
<div
className={classNames({
[style.transferArea]: true,
[style.vertical]: direction === 'vertical',
})}
>
2.6 插槽
- 通过
props.children拿到默认插槽 - 通过
props.childrenXXX拿到具名插槽,类似传递props - 通过
props.childrenXXX拿到作用域插槽,类似传递props,子组件返回JSX.Element,并附带参数
2.7 Computed
- 使用useMemo实现(非hooks手段目前不知)
const [message, setMessage] = useState('hello')
const reversedMessage = useMemo(() => (
message.split('').reverse().join('')
), [message])
2.8 Watch
- 使用
useEffect实现, 第二个参数为监听的对象(数组包裹) - 每次都是
immediate:true,即初始化就会触发监听 - 无法做到
deep:true,即若监听的是对象,只会观察对象的指针是否发生改变,通常结合immutability-helper来实现对象的监听
useEffect(() => {
if ([AppInstallStepState.RUNNING].includes(curAppState) && curHistoryId) {
pollingGetAppProgress(curHistoryId);
}
}, [curHistoryId]);
2.9 :is
- 和
v-if一致
2.10 $set
- React不是自动更新,都是需要调用
setXXX的才行 - 若是更新非基本类型,地址不变时,不会
rerender - 推荐使用immutibility-helper
2.11 $.nextTick
React没有这个概念,这个概念的前提是数据会自动合并更新React的hooks写法,需要自己setState后,配合useEffect使用来达到这个目的- 非hooks写法的第三个参数可以做到阻塞执行后面函数中的逻辑
2.12 css隔离
官方不内置,需要自己选择喜欢的插件
- css modules插件
react中采用的是在class上添加hash值来实现css隔离,编译后的class上会有hash值vue中采用的是css渲染时,根据dom上的data-v-xxx来实现css隔离,编译后class上没有hash值- 使用
css modules无法很好实现v-deep的效果,只能通过:global来进行全局覆盖 - 个人写的粗略的总结
import styles from './index.module.less';
...
...
...
<Col span={4}>
<div className={styles.versionTag}>{tagName}</div>
</Col>
2.13 keep-alive缓存组件
官方不内置,需要自己选择喜欢的插件
2.14 vue-router
官方不内置,需要自己选择喜欢的插件
2.15 Vuex
官方不内置,需要自己选择喜欢的插件