前端实习周记3、4
这两周因为有两天请了假回学校,导致上周忘记记录周记了,不过好在我每天都有写日记,所以也还是能够回顾一些东西。
技术知识
AntD相关
Table表格固定分页设计:
其实在官网api就有,隔壁组实习生来跟我讨论= =,项目中也经常用到,多翻翻官网文档还是挺有用的。
- 原生的话可以使用position:sticky实现
<Table
columns={columns}
pagination={{
position: [top, bottom],
}}
dataSource={data}
/>
Grid栅格
基于row建立一组column,范围在1-24当中设置可适应的栅格,注意加和要等于24
useRef()
useRef()常在Echarts当中用到,我们也可以用它获取到想要获取到dom元素,从而实现操作dom的效果。
useRef()返回以一个具有current属性的ref对象,但改变ref并不会重新引发渲染,(与state区分),尽量不要在渲染期间写入ref,如:
function MyComponent() {
// ...
// 🚩 不要在渲染期间写入 ref
myRef.current = 123;
// ...
// 🚩 不要在渲染期间读取 ref
return <h1>{myOtherRef.current}</h1>;
}
但是可以在事件处理程序或者effect中使用:
function MyComponent() {
// ...
useEffect(() => {
// ✅ 你可以在 effects 中读取和写入 ref
myRef.current = 123;
});
// ...
function handleClick() {
// ✅ 你可以在事件处理程序中读取和写入 ref
doSomething(myOtherRef.current);
}
// ...
}
ref.current可以保存任何值,只需要记住ref是一个普通的对象即可。
useRef()操作dom元素
useRef()最常用的功能之一就是使用ref来操作Dom元素,这适用于在jsx中我们不建议直接操作dom元素,但是可以使用ref来进行,具体操作如下:
import {useRef} from 'react'
function Myinstance(){
const inputRef=useRef(null);
...
return <input ref={inputRef} />
}
注意:当react创建dom节点并将其渲染到屏幕的时候,react会将dom节点设置为ref对象的current属性,这样我们就可以调用到dom属性的例如focus、value等方法
inputRef.current.focus()
不能使用ref的场景
-
hooks只能在组件的顶层被调用
//可行 function App(){ const myRef=useRef(null) } //不可行 <ul> {items.map((item) => { const ref = useRef(null); return <li ref={ref} />; })} </ul>
-
ref只能在组件内部使用,不能访问其他组件的DOM节点
//MyInput组件 function MyInPut(props){ return <input {...props} /> } //不可行 import MyInput fron'&/component/myInput' function App(){ const inputRef=useRef(null); return( <> <MyInput ref={inputRef} /> </>) }
但如果想要暴露子组件的DOM节点,我们可以这么做:使用forwardRef将自身的ref转发给一个子组件。
//改写MyInput const MyInput= forwardRef((props,ref)=>{ return <input {...props} ref={ref} /> })
CSS样式相关
五种定位方式:relative\absolute\fixed\static\sticky
-
relative : 相对于自身原来的位置
//相对于自身向右偏移了10rem position:relative; right:10rem;
-
absolute : 相对于除了static定位以外的第一个父元素进行定位。
-
也就是说,absolute定位的时候要先向上一层一层的寻找自己的父元素,如果谁的position不是static,他就以谁的标准来进行偏移,也就是最常见的父级元素设置为relative,子元素设置为absolute的定位方式。
-
但如果父级没有定位的话,他就会一直找到body最后一层,以body的初始位置为基准。(所以块属性position默认为static)。
-
-
fixed : 固定定位,其偏移不会随着滚动条的滚动而滚动,相对的是浏览器窗口进行定位。(常用于固定展示的
-
static: 默认,没有定位。top\bottom\left\right设置无效。
-
sticky: 动态效果,类似于relative+fixed的结合,(例如:网页搜索框,初始加载为默认位置-relative,当页面滚动条向下滚动时候,变为固定位置-fixed,始终停留在页面头部)
- 必须搭配top\bottom\left\right属性一起使用,否则等同于relative定位
伪类与伪元素
伪类:当已有元素处于某个状态时,为其添加对应的样式,css3之后规定,伪类使用一个冒号来表示,一个选择器中可以同时跟随多个伪类并一起起作用,
div:first-child:hover { color: #ddd; }
如
//写法 标签名 :伪类
a:hover //鼠标移动到a标签上的样式
input:checked //每个被选中的input元素
li:first-child //每个子元素的第一个li元素
li: nth-child(2) //每个子元素的双倍数li元素
input: focus //获取焦点的input框
input:read-only//选择指定了readonly属性<input>元素
:read-write //不带readonly属性
:required //指定有required属性
:root //选择元素的根元素
:target //选择当前活动的元素
伪元素: 创建了一个文档树以外的元素,css3之后规定,伪元素使用两个冒号来表示,伪元素如果在选择器后跟随多个则不会起作用,如
::after //选中元素的第一个子元素
::before //选中元素的最后一个子元素
::first-letter //选中块元素第一行的第一个字母
::first-line //选择块元素的第一行
::selection //文档中被用户选中的部分
::marked //list-item元素上标记点的样式
-
before和after
一般常用于在元素内部创建一个子元素,默认为行内元素,且需要使用content属性为其添加内容
<div class='container'> <label>请选择你的房屋</label> </div>
//添加图标 .container::before{ content:url(./asserts/home.png) } //添加引号 label::before{ content:open-quote color:#fff } label::after{ content:close-quote color:#fff }
padding与margin
考虑设置边距的时候,不应该更改原本元素和父元素,可以使用padding而不是margin,也不用调整元素的高度和宽度。
- 修改子盒子的margin等于修改父盒子的padding
圆角边框
设置圆角边框:
border-radius:10px
响应式
rem\百分比
封装样式组件
注意children使用,children指子组件:
const CustomCard =
({ title, headColor, bodyColor, children }) => {
return
<Card title={title}
bordered={false}
headStyle={{ color: 'white', backgroundColor: headColor }}
bodyStyle={{ backgroundColor: bodyColor }}>
{children}
</Card>
}
接口联调
解构props
传递props的时候如果传递的是一个对象,可以直接在()内解构
<BaseForm record={record} />
}
const BaseForm=({record})=>{
...}
//如果props中对象较多,也可以这样解构
const BaseForm=(props)=>{
const{record,index,content}=props
}
主要参考接口文档,确定返回的数据类型选择调用的方法,map(如有封装的组件,根据indexdata对应即可)
后端传递反参数
前端公用组件 1实时 2概况
返回的参数 1概况 2实时
解决方法
//传入点击参数修改
const onclickhand=(a)=>{
let obj={ type:"2" }
if (a.typedata==='1'){
obj.type="2";
getHomeWarnWeekData(obj.type)
}
if(a.typedata==='2'){
obj.type="1";
getHomeWarnWeekData(obj.type)
}
}
//获取接口
const getHomeWarnWeekData = async (query) => {
const res=await getHomeWarnWeek(query);
setAlarmNums(res.alarm_num);
setlistData(res.ent_list)
}
//每次调用传入固定
useEffect(() => { getHomeWarnWeekData("2")}, [])
//渲染——
<ScrollList
columns={nowColumns}
data={listData}
step={1}
clickEvent={true}
onClick={handleClick}
/>
踩坑bug
git连接错误
使用vpn连接公司内网gitlab出现报错:
ssh: connect to host gitlab.xxxxx.com port 22: Connection timed out fatal: Could not read from remote repository.
解决方法:(将ssh换为http)
-
输入命令
git config --local -e
-
修改配置文件从url=git@github.com:username.git改为url=github.com:username.git
查询参数
-
拼接查询参数:正则表达式?拼接,公用查询请求方法中设立{},
-
?type=1 拼接查询参数、不拼接、返回的不是对象Uncaught (in promise) TypeError: target must be an object
需要给api添加参数、请求时也要修改
-
强制回流Foeced Reflow
Forced reflow while executing JavaScript took
引发问题的原因:每次渲染页面都会进行判断或计算-引发重新渲染-n次强制回流
解决:将多次更新dom的操作整合为一次更新dom操作,减少回流次数
尝试修改不可扩展的对象
React Router caught the following error during render TypeError: Cannot add property if_discharge_permit, object is not extensible。
这个错误通常是由于在渲染期间尝试修改一个不可扩展的对象而引起的。在React应用程序中,这通常是由于在渲染期间更新了一个不应该被更新的对象,例如一个props或state对象。如果这个对象被设置为不可扩展,则将无法向其添加新属性。
确认对象是否可扩展。可以在对象上调用Object.isExtensible()方法来检查它是否被设置为可扩展。 避免在渲染期间更新props或state对象。尽可能避免在渲染期间更新props或state对象。如果必须更新它们,请确保它们是可扩展的,并且不会影响其他组件或函数。 使用React的不可变数据结构。
为了避免在渲染期间更新props或state对象,可以使用React的不可变数据结构,例如Immutable.js,来管理应用程序状态。这些数据结构使用不变性的原则来确保数据的不可变性,从而减少了在渲染期间更新对象的风险。