react版本:^17.0.2
typescript版本:^4.5.2
craco-alias:^3.0.1
craco-antd:^1.19.0
craco-less:^1.20.0
craco/craco:^6.4.2
react-router-dom:^6.0.2
react项目的创建以及使用ant design pro深色主题的方法参考另一篇博文:React和ant design pro v5开发相关合集_dap769815768的博客-CSDN博客
1.单行文本超出部分用省略号代替:
div{
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
width: 200px;
}
该方法只有在单行情况下才会生效,也就是white-space: nowrap;时。针对多行文本,相对比较复杂,需要计算每个文字在当前样式下的宽度,然后再根据所在div的实际宽度进行针对性处理。目前还没有特别好的方法。
2.safari浏览器不支持flex布局模式下的的gap属性,目前没有特别好的方法支持,官方直到14.1版本才会支持,这个链接有说:Safari 14.1 Adds Support for Flexbox Gaps | CSS-Tricks
很多第三方组件都有space这个组件,就是让一些子元素隔开相邻的距离,并且兼容safari,它们是怎么做的呢,以阿里巴巴的ant design为例,它首先检测浏览器是否支持gap属性,如果不支持,则在子组件外面套一层div,然后给div设置paddingBottom或者paddingRight,下面的代码是以React框架实现的space组件:
import React from 'react';
const Index:React.FC<{gap: number,direction:string,style?:any}>=(props)=>{
const {gap,direction,children,style}=props;
const count=React.Children.count(children);
return (
<div style={{
display: 'flex',
flexFlow:direction==='vertical'?'column':'row',
...style
}}>
{
(count===0||count===1)?children:
React.Children.map(children,
(child,index)=>{
if(index===count-1){
return(<div>{child}</div>);
}
else {
return(
// 这里套一层
<div
style={{paddingBottom:direction==='vertical'?gap:0,
paddingRight:direction==='vertical'?0:gap}}>
{child}
</div>
);
}
})
}
</div>
);
}
export default Index;
3.顶部固定工具栏:
div{
position: fixed;
top: 0;
width: 100%;
height: 50px;
}
此时div是脱离文档流的,这样就会遮挡内容部分,所以要求内容部分设置marginTop或者padingTop:
.appBody{
margin-top: 50px;
}
4.input属性的placeholder颜色,要兼容各种浏览器,则需要进行针对性设置:
.searchInput::-webkit-input-placeholder {
/* WebKit browsers */
color: #6e757c;
}
.searchInput:-moz-placeholder {
/* Mozilla Firefox 4 to 18 */
color: #6e757c;
}
.searchInput::-moz-placeholder {
/* Mozilla Firefox 19+ */
color: #6e757c;
}
.searchInput:-ms-input-placeholder {
/* Internet Explorer 10+ */
color: #6e757c;
}
5.input输入框,去除聚焦时的边框样式:
.searchInput:focus{
outline: 0;
}
注意这里不再是border了。如果要设置颜色等属性,和设置border是一样的。
6.css的margin属性默认是不占用元素的实际大小的,比如元素的实际宽度是100,margin为10,那么元素的实际宽度此时是120,因为margin没有计算在内,如果要将margin计算在内,需要设置:
box-sizing: border-box;
7.要设置flex布局下的子元素对齐方式,使用justify-content属性,比如最常用的,在做登录页面时我们希望div里面的登录框在flex布局下水平且垂直居中,那么应该这么设置:
.App {
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
8.react使用脚手架创建的项目覆盖webpack配置,网上很多方法都是将配置暴露出来,即使用npm run eject命令,然后进行修改。该命令是不可逆的,同时会有大量的我们不太会用到的配置暴露出来,这样做不太好。因此可以尝试下使用craco覆盖配置的方案。
craco源码地址:https://github.com/gsoft-inc/craco。
首先安装craco:
npm install @craco/craco --dev-save
然后在项目根目录下创建craco.config.ts文件(文件名为craco.config.js也没问题),这里添加ts文件可能会报错:All files must be modules when the '--isolatedModules' flag is provided,把tsconfig.json配置文件里的isolatedModules改为false,这个报错就消失了,这个原因我暂时还不清楚。新增的ts文件内容如下,可以参考官方的文档:craco/README.md at master · gsoft-inc/craco · GitHub
9.react脚手架创建的项目使用less,同时支持模块化。这里简单说一下为何要进行模块化,进行模块化的目的是为了避免不同模块使用相同的类名,导致相互影响,比如A模块使用了一个class为page,B模块也使用了一个class为page,这两个page就会相互影响,而模块化之后,则只对引用了该less的模块生效。
这里使用一个叫craco-less的插件:https://github.com/DocSpring/craco-less。
安装好craco-less后,在craco.config.js里面配置如下的内容:
const CracoLessPlugin = require('craco-less');
module.exports = {
plugins: [
{
plugin: CracoLessPlugin,
options: {
lessLoaderOptions: {
lessOptions: {
modifyVars: {},
javascriptEnabled: true,
},
},
},
},
],
};
如果你的项目是ts的,还需要同时修改src目录下的react-app-env.d.ts文件,因为ts可能无法正确识别导致编译报错,增加内容如下:
declare module "*.module.less" {
const classes: { readonly [key: string]: string };
export default classes;
}
那么代码里面就可以这么引用了:
import styles from './index.module.less';
const Index:React.FC=()=>{
return (
<div>
<a className={styles.title}
href="https://www.jd.com"
target="_blank" rel='noreferrer'
>京东商城</a>
</div>
);
}
export default Index;
注意,这里less文件的后缀是.module.less,这个后缀是可以修改的,如何修改轻参照官方仓库里面的文档。这里建议不要修改了,less模块化,使用.module.less个人认为更合理,同时如果修改了,可能会跟一些第三方组件库冲突,比如如果把后缀名修改为.less,则可能导致ant design的主题失效。
10.react脚手架创建的typescript项目配置alias别名。这里用到一个第三方的配置插件,叫做craco-alias:GitHub - risenforces/craco-alias: A craco plugin for automatic aliases generation for Webpack and Jest安装该插件:
npm i -D craco-alias
在根目录下创建文件tsconfig.extend.json,文件内容如下:
{
"compilerOptions": {
"baseUrl": "./src",
"paths": {
"@": ["./"],
"@/*": ["./*"]
}
}
}
修改tsconfig.json,在最上面添加内容:
根目录创建craco.config.js文件,内容如下:
const CracoAlias = require("craco-alias");
module.exports = {
plugins: [
{
plugin: CracoAlias,
options: {
source: 'tsconfig',
tsConfigPath: './tsconfig.extend.json',
baseUrl: './src',
}
}
]
};
使用的时候就可以像下面这样用了:
import Space from "@/component/Space";
有问题可以参考这个demo:https://github.com/risenforces/craco-alias-ts-demo。
11.如果不用craco如何给我们创建的项目配置别名呢,答案是不可以,这在官方项目的issue里面作者有提到:https://github.com/facebook/create-react-app/issues/7795#issuecomment-541582032。
同时官方提供了一种解决方,就是在tsconfig.json里面添加:
"baseUrl": "."
然后在引用的地方,可以直接使用src进行引用,比如下面的com组件:
import React from 'react';
import Com from 'src/component/com';
const Test: React.FC=()=>{
return (
<div>
<Com/>
</div>
);
}
export default Test;
文件目录如下:
诚如官方所言,baseUrl已经足够使用了,没必要再配别名,所以我本人也推荐这种方法,减少第三方插件的使用,因为很多插件,其实都有莫名其妙的bug,经常会导致你的代码编译出问题,然后查找很久,都找不到原因。
12.关于react组件的命名方式我一般是这样的,一个组件一个目录,组件的目录要大写,然后里面不用组件名称来命名js文件或者ts文件,而是用index来命名,如下:
组件名称也可以用Index,就像下面这么写:
import React from 'react';
const Index: React.FC=()=>{
return (
<div>
com
</div>
);
}
export default Index;
这样写虽然没有问题,但是我本人不推荐这么做,因为这样做,在使用react脚手架创建的原始项目中就没代码提示了,也就是当你输入TestCom的时候,编译器是找不到这个组件从而进行代码提示的,因为你的组件命名其实是在这个包里面的Index组件,它和其他包的组件是重名的,因此我建议这么写:
import React from 'react';
const TestCom: React.FC=()=>{
return (
<div>
com
</div>
);
}
export default TestCom;
这样写之后,你会发现代码提示很好用,而组件按照它本来该有的名字命名,其实也是应该的。偶尔有一些网上的教程,可能会用上面的写法,这里我个人不推荐。
12.React使用路由,react的定位其实就是一个ui library,是没有提供路由的,我们在涉及到路由相关的问题时,一般都是使用一个叫react-router的第三方库,实际上react-router是react-router系类的核心库,通常来讲,在新版本中,我们在使用的时候都不直接使用这个库,而是使用react-router-dom或者react-router-native,它俩各自有自己的应用场景。这些信息也在官方的npm文档中有介绍:react-router - npm。这里是官方的使用教程:react-router/installation.md at main · remix-run/react-router · GitHub