header的搭建
1.一共有三个页面,可以每个页面都做一个header
,也可以只做一个header
,根据每个页面需要展示的条件进行控制显示。选择第二种方式进行搭建
2.分别对header
的left
、center
和right
进行封装
3.中间居中的问题
3.1.如果给左边固定宽度,右边固定宽度,中间部分flex: 1
。但是左右两边的固定宽度不一样,中间部分是不会居中的。
3.2.可以给中间部分一个固定的宽度,左右两部分分别flex: 1
,永远保证左右两边宽度是一致的,这样就能居中了
svg
在react
中的使用
1.如果是.svg
文件,在img
和background-image
中都可以使用
2.如果是直接嵌入svg标签,svg可以随着html文件的下载一起下载下来。
将svg
抽成组件,用一个工具函数将样式的字符串转化为string
<div>
<svg><path></path></svg>
</div>
style-components
管理资源
1.混入
2.传入服务器返回数据的样式
2.1.在wrapper中传入变量
2.2.将props使用
react
中引入图片
应该直接用import
引入
如果直接引入,因为是从js中引入图片,是解析不出来的。
<img src="../../assest/...">
home-itme
的每张图片的比例不一样,造成高度不一致
1.给padding-top
的值设为66.6%
,一个足够的高度
2.padding
的百分比是相对于width
而言的
3.给img
设置绝对定位,img
完全覆盖上去
.cover {
position: relative;
box-sizing: border-box;
padding: 66.66% 8px 0;
border-radius: 3px;
overflow: hidden;
img {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
}
}
这么写就能让每个内容有对齐的宽高
scrollView
的一些注意点
1.需要设置在父盒子的内部,这样才能获取到相关的width
数据
longfor-list
是父盒子,只有放在里面才能拿到相对于longfor-list的scorollWidth、clientWidth、offsetLeft等数据
2.如果每个item
没有达到对应的宽度,flex-shrink
应该设置为0
给item
设置inner
1.如果要给item
设置内边距,如果不用inner
,需要计算一个整个盒子的宽度与padding
的关系
2.使用inner
就可以不需要考虑这些问题
给home
的每个组件都加一个margin-top
不需要给每个组件都设置一次,可以在home
中直接设置
这样是给直接子元素div
设置margin-top: 30px
export const HomeWrapper = styled.div`
> div {
margin-top: 30px;
}
`
分页器切换页面效果
1.回到顶部
window.scrollTo(0, 0)
2.利用定位加一个蒙版
2.1 定义一个变量isLoading
,保存在store
中
2.2 在rooms
中增加蒙版
{ isLoading && <div className="bg-cover"></div> }
2.3 一旦发送网络请求,派发action修改状态
export const fetchEntireDataAction = createAsyncThunk("fetchData", async (page = 0, {dispatch, getState}) => {
// 请求数据前,增加蒙版
dispatch(changeIsLoadingAction(true))
// 请求数据
const res = await getEntireRoomListData(page * 20)
dispatch(changeCurrentPageAction(page))
dispatch(changeRoomListAction(res.list))
dispatch(changeTotalCountAction(res.totalCount))
// 请求完数据,移除蒙版
dispatch(changeIsLoadingAction(false))
})
图片被强行压缩
现象:
解决:可以给image加一个属性,保持原来宽高比的情况下,把超出的部分隐藏
效果:
sliper
的样式学习
.slider {
position: relative;
cursor: pointer;
&:hover {
.control {
display: flex;
}
}
.control {
position: absolute;
z-index: 9;
left: 0;
top: 0;
bottom: 0;
right: 0;
display: none;
justify-content: space-between;
color: #fff;
.icon {
display: flex;
justify-content: center;
align-items: center;
width: 83px;
height: 100%;
background: linear-gradient(to left, transparent 0%, rgba(0, 0, 0, 0.25) 100%);
&.right {
background: linear-gradient(to right, transparent 0%, rgba(0, 0, 0, 0.25) 100%);
}
}
}
}
entire页面轮播图indicator
1.封装成base-ui
组件
2.包裹需要使用的内容
3.监听点击,特判两个边界(最后一个点击跳到第一个,第一个点击同理)
4.每个选中的item
滚动到中间的位置
4.1.其实就是滚动蓝色箭头的长度,按照下面公式
4.2.flex
布局要放在i-content
里面,clientWidth
的值才正确
5.其他逻辑和scroll-view
组件思路一致
6.左右特殊情况。0
和1
都不需要居中。
6.1.左边的判断方法:0
和1
如果要居中都是向右边移动(1在居中位置的左边),2
需要向左移动。0
和1
移动到中间按照计算公式计算出来的结果是负值,而2
计算出来的是正值。通过这个条件特判。如果小于0
,就让distance = 0
,不能直接return
,否则点击上一张/下一张会原地不动
6.2.右边的判断方法:最多的移动距离是蓝色箭头的距离,如果比这个距离要大,让它等于这个距离
entire
页面item
点击跳转到详情页
如果直接在组件内部监听事件,全部使用到这件组件的地方都会进行跳转。可以不在item
组件内部来做,可以在entire
页面定义这个事件,传递给item
组件内部,判断itemClick
有没有值,只有有值的情况下再去调用,同时把itemData
回调出去。将数据派发保存到store
中
<RoomItem itemclick={itemClickHandle}>
const { itemClick } = props
function itemClickHandle() {
if (itemClick) itemClick(itemData)
}
detail
详情页
1.通过entire
页面进入详情页传递过来的数据,如果在detail
页面再刷新,数据就会清空,影响开发效率。
1.1.解决:store
里的detail
初始化值,不要用空对象,而是用一个itemInfo
做初始化值。这样测试的时候就很方便,不需要每次都重新进入。做完以后再复原。
2.需求:手指放上图片,所有图片加上cover
,只有鼠标对应的图片没有cover
,放上去的图片有缩放,需要有动画
&:hover {
.bg-cover {
opacity: 1 !important;
}
.item:hover {
.bg-cover {
opacity: 0 !important;
}
img {
transform: scale(1.1);
}
}
}
图片浏览器
1.用固定定位设置全屏背景
2.取消右侧滚动条,取消滚动功能
使用useEffect
设置对应的样式,组件卸载的时候还原
useEffect(() => {
document.body.style.overflow = "hidden"
return (() => {
document.body.style.overflow = "auto"
})
}, [])
3.关闭图片浏览器,从detail-pictures
传递事件进去
<PictureBrowser
picturesData={DetailPictures}
closeClick={e => setIsShowBrowser(false)}
/>
const closeBtnHandle = () => {
if (closeClick) closeClick()
}
4.点下一张图片时太快,图片会被选中,被蓝色背景遮罩覆盖
添加样式user-select: none;
5.切换图片过程中的动画,利用react-transition-group
库
npm install react-transition-group
6.底部显示和隐藏照片列表
6.1.控制栏和图片列表整体是一个做一个绝对定位,监听点击,height
由70px
变为0
,控制栏就能跟着往下走
7.bug
:点击轮播图切换会进入到详情页,因为由冒泡事件,所以会页面跳转。解决:阻止冒泡。需要拿到event
对象
<div className="left icon" onClick={e => IconClickHandle(false, e)}>
<IconArrowLeft height='30' width='30' />
</div>
const IconClickHandle = (isNext = true, event) => {
// 轮播图逻辑
isNext ? sliderRef.current.next(): sliderRef.current.prev()
// 指示器逻辑
const length = roomData.picture_urls.length
let newIndex = isNext ? selectIndex + 1: selectIndex - 1
if (newIndex === length) newIndex = 0
if (newIndex < 0) newIndex = length - 1
setSelectIndex(newIndex)
// 阻止事件冒泡
event.stopPropagation()
}