大家好,我是考100分的小小码 ,祝大家学习进步,加薪顺利呀。今天说一说前端实现拖拽布局完成界面_vue拖拽布局,希望您对编程的造诣更进一步.
前言
页面布局也是在实际开发中经常用到的技术。
- 在大的方面,可以实现整个页面的布局,比如左侧导航、header、footer…
- 在小的方面,可以是内容布局,比如文章。
- 考虑布局时,需要兼顾桌面浏览器和移动端的情况,也就是常说的 responsive。
在 react 中实现,和经典实现其实没什么大的区别。
实现布局有这几种方式:
- 从 0 开始使用 CSS 实现,这是必须掌握的技能
- 使用 CSS Grid 系统(网状页面),可以使用不同尺寸的屏幕
- 使用组件库,例如
antd
Grid
:24 栅格系统Layout
:页面级整体布局
CSS 实现基础布局
上中下布局
.app-layout1 {
width: 500px;
height: 400px;
position: relative;
text-align: center;
}
.app-layout1 .header {
line-height: 60px;
}
.app-layout1 .content {
position: absolute;
bottom: 60px;
top: 60px;
left: 0;
right: 0;
}
.app-layout1 .footer {
line-height: 60px;
bottom: 0;
left: 0;
right: 0;
position: absolute;
}
Sider + 上中下布局
使用 left: 150px,留出 Sider 的位置
.app-layout2 {
width: 500px;
height: 400px;
position: relative;
text-align: center;
}
.app-layout2 .header {
position: absolute;
left: 150px;
top: 0;
right: 0;
}
.app-layout2 .content {
position: absolute;
bottom: 60px;
top: 60px;
left: 150px;
right: 0;
}
.app-layout2 .footer {
bottom: 0;
left: 150px;
right: 0;
position: absolute;
}
.app-layout2 .sider {
width: 150px;
position: absolute;
top: 0;
left: 0;
bottom: 0;
}
进阶:侧边栏宽度可拖拽
样式布局
style.css
.layout {
position: relative;
width: 100%;
height: 400px;
}
.sider {
position: absolute;
top: 0;
left: 0;
bottom: 0;
background-color: #ddd;
}
.header {
background-color: #aaa;
height: 60px;
}
index.js
通过状态 siderWidth
控制 layout
的 paddingLeft
import { useState } from 'react';
import './style.css';
export default function ResizeLayout() {
const [siderWidth, setSiderWidth] = useState(150);
const pxWidth = `${siderWidth}px`;
return (
<div className="layout" style={{ paddingLeft: pxWidth }}> <div className="sider" style={{ width: pxWidth }}> sider </div> <div className="header">header</div> <div className="content">content</div> </div>
);
}
拖放逻辑
视觉上,我们拖拽的是侧边栏 Sider 的右边框,其实并不是。我们会在右边框位置放置一个“隐身”的 bar — sider-resizer
:
.sider-resizer {
position: absolute;
width: 6px;
top: 0;
bottom: 0;
cursor: col-resize;
}
当鼠标在 sider-resizer
上,触发 onMouseDown
时,记录下鼠标的初始位置,同时标记 dragging
状态为 true
:
const handleMouseDown = (event) => {
setStartPageX(event.pageX);
setDragging(true);
};
伴随着 dragging
状态的改变,我们会为页面铺上一层遮罩 — resize-mask
,以便后续 事件的监听:
{
dragging && (
<div className="resize-mask" onMouseMove={handleMouseMove} onMouseUp={handleMouseUp} />
);
}
.resize-mask {
background: rgba(0, 0, 0, 0);
position: fixed;
left: 0;
top: 0;
right: 0;
bottom: 0;
cursor: col-resize;
}
onMouseMove
的过程中,实时更新 siderWidth
以及对 startPageX
的更新,就会产生拖拽的效果。
最终在 onMouseUp
时,结束拖拽状态。
const handleMouseMove = (event) => {
const currentSiderWidth = siderWidth + event.pageX - startPageX;
setSiderWidth(currentSiderWidth);
setStartPageX(event.pageX);
};
const handleMouseUp = () => {
setDragging(false);
};
localStorage 存储宽度位置
在拖拽结束时,保存 siderWidth
到 localStorage
;初始化 siderWidth
时,检查 localStorage
是否有值。
const [siderWidth, setSiderWidth] = useState(
parseInt(localStorage.getItem('siderWidth')) || 150,
);
const handleMouseUp = () => {
setDragging(false);
localStorage.setItem('siderWidth', siderWidth);
};
完整代码
style.css
.layout {
position: relative;
width: 100%;
height: 400px;
}
.sider {
position: absolute;
top: 0;
left: 0;
bottom: 0;
background-color: #ddd;
}
.header {
background-color: #aaa;
height: 60px;
}
.sider-resizer {
position: absolute;
width: 6px;
top: 0;
bottom: 0;
cursor: col-resize;
}
.resize-mask {
background: rgba(0, 0, 0, 0);
position: fixed;
left: 0;
top: 0;
right: 0;
bottom: 0;
cursor: col-resize;
}
index.js
import { useState } from 'react';
import './style.css';
export default function ResizeLayout() {
const [siderWidth, setSiderWidth] = useState(
parseInt(localStorage.getItem('siderWidth')) || 150,
);
const [dragging, setDragging] = useState(false);
const [startPageX, setStartPageX] = useState(0);
const pxWidth = `${siderWidth}px`;
const handleMouseDown = (event) => {
setStartPageX(event.pageX);
setDragging(true);
};
const handleMouseMove = (event) => {
const currentSiderWidth = siderWidth + event.pageX - startPageX;
setSiderWidth(currentSiderWidth);
setStartPageX(event.pageX);
};
const handleMouseUp = () => {
setDragging(false);
localStorage.setItem('siderWidth', siderWidth);
};
return (
<div className="layout" style={{ paddingLeft: pxWidth }}> <div className="sider" style={{ width: pxWidth }}> sider </div> <div className="header">header</div> <div className="content">content</div> <div className="sider-resizer" style={{ left: pxWidth }} onMouseDown={handleMouseDown} > {dragging && ( <div className="resize-mask" onMouseMove={handleMouseMove} onMouseUp={handleMouseUp} /> )} </div> </div>
);
}
React 最佳实践
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/12942.html