锚定(点击tab 对应内容置顶 )
changeTab(id) {
this.currentIndex = id
console.log('currentId', this.currentIndex)
console.log('this.tabTop')
let domObj
let tabs = this.$refs.list_title
let scrollTop = document.documentElement.scrollTop || document.body.scrollTop
this.tabTop = true
console.log('this.$refs.report.$el', this.$refs.report.$el)
switch (id) {
case 1:
domObj = this.$refs.report.$el
break
case 2:
domObj = this.$refs.item_info
break
case 3:
domObj = this.$refs.fitable.$el
break
default:
break
}
scrollTop = domObj.getBoundingClientRect().top - tabs.getBoundingClientRect().height
console.log('scrollTop', scrollTop)
document.documentElement.scrollTop += scrollTop //滚动条滚动的距离
document.body.scrollTop += scrollTop
},
?.
做好条件判断 ?. 不是数组的话就会.map()白屏
const [cityList] = useState(() => {
if (props?.cityList?.length) {
return props?.cityList;
}
return []; //兜底策略 返回一个空值
});
封装组件注意的地方
- 简洁,注释写清楚
- 考虑多种情况
const [titleColor] = useState(() => {
return props.titleColor || "White"; //状态数据默认值初始化,如果props有数据优先
});
//定义方法要写清楚参数包含的数据以及数据类型
function show(
params = {
data: {},
}
) {
xxx;
}
//注意兜底情况
{conf ? (
<p></p>
) : null}
- 弹框的城市item出现不能一行平铺 设置 box-sizing: border-box 怪异盒 解决点击不同的item时导致的盒子抖动
.item_city {
width: 78px;
box-sizing: border-box;
padding:7px 0 6px 0;
border: 1px solid rgba(233,193,162,1);
border-radius: 18px;
margin:0 15px 15px 0;
&:nth-child(3n+3) {
margin-right: 0;
}
}
- 隐藏滚动条,且不影响滚动
使用 ::webkit-scrollbar 伪元素选择器,不过这个选择器只在 webkit 核心的浏览器中有效,例如 Chrome、新 Edge、Safari 等。::web-kit-scrollbar 可以直接选择滚动条元素,把它的 display 属性设置为 none 就可以隐藏滚动条了:
::-webkit-scrollbar { /* display: none; */ /* 或者 */ width: 0 !important; }
- 设置滚动条并且隐藏滚动条
.city_item {
box-sizing: border-box;
height: 30vh;
max-height: 448px;
overflow: auto; //重点
display: flex;
justify-content: space-between;
flex-wrap: wrap;
color: #E9C1A2;
text-align: center;
&::-webkit-scrollbar {
display: none; //隐藏滚动条样式
}
}
react插槽
子组件中在插入位置写 {props.children}
父组件给子组件传入事件 任意事件名=父组件的方法名
受控与非受控
useSomething = (inputCount) => {
const [ count, setCount ] = setState(inputCount);
setCount(inputCount);
};
因为 useState 参数代表的是初始值,仅在 useSomething 初始时赋值给了 count state。后续 count 的状态将与 inputCount 无关。这种外部无法直接控制 state 的方式,我们称为非受控。
只有通过 setCount(inputCount)才可以改变count的值,执行setCount(),React会立即退出当前的渲染函数并用更新后的 state 重新执行 render 函数。
样式
1.CRA 支持 CSS Module ,并为提供了一种将 CSS 封装到组件范围内的模块的方法。这样,它就不会意外泄露到其他 React 组件的样式中。
import style from './list.module.css'
<h1 className="${style.font_style} ${style.content}" style={{ color: 'blue' }}></h1>
styled components,作为React的CSS-in-JS方式之一
import styled from 'styled-components';
const Head = styled.h1`
color: blue;
`;
const Title = ({ title }) =>
<Head>
{title}
</Head>
函数式组件
// React.createElement(Card, {
// title: "XXX"
// });
const contentElement = <Card title="XXX" />;
ReactDOM.render(
contentElement,
document.getElementById('app')
);
React.js的hooks
以 “use” 作为开头的方法,可以避开使用 class式写法,在函数式组件中完成生命周期、状态管理、逻辑复用等几乎全部组件开发工作的能力。因此,hooks只能在函数组件中使用Eslint 通过判断一个方法是不是大坨峰命名来判断它是否是 React 函数。
为什么使用hooks?
- 状态复用
// 单个name的写法
const { name, setName } = useName();
// 多次使用的写法
const { name : firstName, setName : setFirstName } = useName();
const { name : secondName, setName : setSecondName } = useName();
- 告别this
vue中hooks的写法
<template>
<div>
{{ message }}
</div>
</template>
<script setup>
import { computed, ref } from 'vue'
// 定义了一个 ref 对象
const name = ref('')
// 定义了一个依赖 name.value 的计算属性
const message = computed(() => {
return `hello, my name is ${name.value}`
})
</script>
React中hooks的写法
import { useState, useEffect } from 'React'
export default () => {
// 通过 useState 可以创建一个 状态属性 和一个改变状态数据的方法
const [ name, setName ] = useState('')
// 通过 useEffect 可以对状态数据改变之后需要的操作进行处理
useEffect(() => {
console.log(name)
}, [ name ])
// 通过 useMemo 能生成一个依赖 name 的变量 message
const message = useMemo(() => {
return `my name is ${name}`
}, [name])
return <div>{ message }</div>
}
useEffect
Effects 函数一旦执行,函数内的副作用已经发生,React 无法猜测到函数相比于上一次做了哪些变化。但我们可以给 useEffect 传入第二个参数,作为依赖数组 (deps),避免 Effects 不必要的重复调用。
useMemo
useMemo 通过一些变量计算得到新的值。通过把这些变量加入依赖 deps,当 deps的值都没有变化,就不会计算。useMemo 中传入的函数,将在 render 函数调用过程被同步调用。
useMemo的意义就是尽可能的使用缓存的值。
const data = useMemo(() => ({ a, b,d: 'xxx' }), [a, b]);
const memoComponentsA = useMemo(() => ( <ComponentsA {...props} /> ), [props]);
如果子组件使用了对象和数组作为 props,使用useMemo减少它们重新生成,避免子组件不必要的重复渲染,提升性能。
const data = { id }; //未优化
const data = useMemo(() => ({ id }), [id]); //使用useMemo优化
return <Child data={data}>;
父组件渲染时,只要id不变,data的值也不会发生变化,子组件也不会 render。
一般组件内部对一个类似下面的content变量时,如果count改变使得整个组件重复的render,导致return的组件也要重新渲染,因此使用useMemo进行缓存,可减少元素渲染次数。
function Example(props) {
const [count, setCount] = useState(0);
const [foo] = useState("foo");
const content = useMemo(() => (
<div>
<Item key={1} x={1} foo={foo} />
<Item key={2} x={2} foo={foo} />
<Item key={3} x={3} foo={foo} />
</div>
), [foo]);
return (
<div>
<p>{count}</p>
<button onClick={() => setCount(count + 1)}>count</button>
{content}
</div>
);
}