reactjs - React JS 中的两个固定导航栏
问题描述
NavBars 应该固定在顶部,第一个的高度应该比第二个略小。我现在使用的代码是:
<Navbar variant="light" fixed="top" expand="lg" className="pt-4 pb-4">
<Container>
<Navbar.Brand href="/"><Image src={logo}></Image></Navbar.Brand>
<Navbar.Toggle aria-controls="basic-navbar-nav" />
<Navbar.Collapse id="basic-navbar-nav">
<Nav className="mr-auto">
<Nav.Link as={Link} to="/" className="ml-xl-4">Home</Nav.Link>
<Nav.Link className="ml-xl-4">Shop</Nav.Link>
<Nav.Link className="ml-xl-4">Sale</Nav.Link>
</Nav>
<Form inline>
<FormControl type="text" placeholder="Search" className="mr-sm-5" />
</Form>
<Nav.Link as={Link} to="/"><Image src={accountIcon}></Image></Nav.Link>
<Nav.Link as={Link} to="/cart" className="pr-0"><Image src={cartIcon}></Image></Nav.Link>
</Navbar.Collapse>
</Container>
</Navbar>
我正在使用 FontAwesome、StyledIcons、StyledComponents 和 ReactBootstrap。现在我无法在现有导航栏的顶部添加另一个导航栏。我试图在容器内创建另一个导航,但它失败了。请指导我对齐两个导航栏。
解决方案
我离开 UI 库的原因之一是它们在外观定制方面可能会限制您可以做的事情。我经常发现外观定制的越多,我编写的 CSS/样式覆盖就越多。有些组件对于同一个组件会有完全不同的布局和不同的类,这意味着更多的 CSS 覆盖!因此,这种来回的斗争是我强烈建议利用 CSS-in-JS 的强大功能的主要原因之一(例如@emotion或styled-components等等)。
不过,这是一个工作演示:
或者
我使用 Typescript 而不是普通的 Javascript,因为 VSCode 允许您将鼠标悬停在组件上以查看JSDoc描述(您可能需要向下滚动才能在对话框中查看描述)。按住ctrl
鼠标左键单击组件时,将在同一选项卡中打开预览!
另一种方法是手动将className
s 添加到 ReactBootstrap 组件并应用 CSS 覆盖。在这种情况下,底部栏将是:
position: fixed; // locks it to screen
top: 30px; // at this position (factoring in the height of the top bar)
但是同样,这不会像编写自己的可重用组件那样灵活。您可能会发现自己创建了许多类来为不同的页面/屏幕布局/主题设置相同的组件样式(例如 this DOM与 this DOM;或者,甚至与仅使用 UI 库的这个DOM相比)。
固定/index.ts
import styled from "@emotion/styled";
/**
* The Fixed component is a custom styled component to mainly adjust related 'fixed: position" CSS properties.
*
* @param background - sets 'background' CSS property (default: "transparent").
* @param bottom - sets 'bottom' CSS property (default: undefined).
* @param height - sets 'height' CSS property (default: "auto").
* @param left - sets 'left' CSS property (default: undefined).
* @param padding - sets 'padding' CSS property (default: "0px").
* @param right - sets 'right' CSS property (default: undefined).
* @param top - sets 'top' CSS property (default: undefined).
* @param width - sets 'width' CSS property (default: "100%").
*/
const Fixed = styled.div<{
background?: string;
bottom?: string;
height?: string;
left?: string;
padding?: string;
right?: string;
top?: string;
width?: string;
}>`
position: fixed;
display: flex;
align-items: center;
width: 100%;
background: ${({ background }) => background || "transparent"};
border-bottom: 2px solid #ccc;
height: ${({ height }) => height || "auto"};
padding: ${({ padding }) => padding || "0px"};
top: ${({ top }) => top};
right: ${({ right }) => right};
bottom: ${({ bottom }) => bottom};
left: ${({ left }) => left};
width: ${({ width }) => width || "100%"};
`;
export default Fixed;
弹性/索引.ts
import styled from "@emotion/styled";
/**
* The Flex component is a custom styled component to mainly set 'flex' CSS properties.
*
* @param align - sets 'align-items' CSS property (default: "stretch").
* @param justify - sets 'justify-content' CSS property (default: "flex-start").
* @param padding - sets 'padding' CSS property (default: "0px").
* @param width - sets 'width' CSS property (default: "100%").
*/
const Flex = styled.div<{
align?:
| "stretch"
| "center"
| "flex-start"
| "flex-end"
| "baseline"
| "initial"
| "inherit";
justify?:
| "flex-start"
| "flex-end"
| "center"
| "space-between"
| "space-around"
| "space-evenly";
padding?: string;
width?: string;
}>`
display: flex;
justify-content: ${({ justify }) => justify || "flex-start"};
align-items: ${({ align }) => align || "stretch"};
padding: ${({ padding }) => padding || "0px"};
width: ${({ width }) => width || "100%"};
`;
export default Flex;
导航栏/index.tsx
import * as React from "react";
import Nav from "react-bootstrap/Nav";
import NavDropdown from "react-bootstrap/NavDropdown";
import Navbar from "react-bootstrap/Navbar";
import Form from "react-bootstrap/Form";
import FormControl from "react-bootstrap/FormControl";
import { IoPersonOutline } from "react-icons/io5";
import { GiShoppingCart } from "react-icons/gi";
import Fixed from "../Fixed";
import Flex from "../Flex";
export type eventKey = string | null;
const TopNavBar = () => {
const [language, setLanguage] = React.useState<eventKey>("DE");
const [currency, SetCurrency] = React.useState<eventKey>("€ EUR");
const handleLanguageChange = React.useCallback((eventKey: eventKey) => {
setLanguage(eventKey);
}, []);
const handleCurrencyChange = React.useCallback((eventKey: eventKey) => {
SetCurrency(eventKey);
}, []);
return (
<>
<Navbar className="navbar-top" fixed="top">
<Flex justify="flex-end" padding="0 20px 0 0">
<NavDropdown
onSelect={handleLanguageChange}
alignRight
title={language}
id="basic-nav-dropdown"
>
<NavDropdown.Item eventKey="EN">EN</NavDropdown.Item>
<NavDropdown.Item eventKey="ES">ES</NavDropdown.Item>
<NavDropdown.Item eventKey="DE">DE</NavDropdown.Item>
<NavDropdown.Item eventKey="JP">JP</NavDropdown.Item>
</NavDropdown>
<NavDropdown
onSelect={handleCurrencyChange}
alignRight
title={currency}
id="basic-nav-dropdown"
>
<NavDropdown.Item eventKey="€ EUR">€ EUR</NavDropdown.Item>
<NavDropdown.Item eventKey="£ GBP">£ GBP</NavDropdown.Item>
<NavDropdown.Item eventKey="¥ JPY">¥ JPY</NavDropdown.Item>
<NavDropdown.Item eventKey="$ USD">$ USD</NavDropdown.Item>
</NavDropdown>
</Flex>
</Navbar>
<Fixed background="#fff" padding="5px 60px 0 20px" top="30px">
<Flex justify="flex-start">
<Navbar.Brand href="/">Brand</Navbar.Brand>
</Flex>
<Flex justify="center">
<Form inline>
<FormControl
type="text"
placeholder="Search"
className="search-box"
/>
</Form>
</Flex>
<Flex justify="flex-end">
<Nav.Link>
<IoPersonOutline />
</Nav.Link>
<Nav.Link className="pr-0">
<GiShoppingCart />
</Nav.Link>
</Flex>
</Fixed>
</>
);
};
export default TopNavBar;
应用程序.tsx
import Navbar from "./Navbar";
import "bootstrap/dist/css/bootstrap.min.css";
import "./styles.css";
const App = () => (
<div className="app">
<Navbar />
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<p>
Curabitur aliquet quam id dui posuere blandit. Nulla porttitor accumsan
tincidunt. Nulla porttitor accumsan tincidunt. Curabitur arcu erat,
accumsan id imperdiet et, porttitor at sem. Vestibulum ante ipsum primis
in faucibus orci luctus et ultrices posuere cubilia Curae; Donec velit
neque, auctor sit amet aliquam vel, ullamcorper sit amet ligula.
Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere
cubilia Curae; Donec velit neque, auctor sit amet aliquam vel, ullamcorper
sit amet ligula. Vestibulum ac diam sit amet quam vehicula elementum sed
sit amet dui. Vestibulum ante ipsum primis in faucibus orci luctus et
ultrices posuere cubilia Curae; Donec velit neque, auctor sit amet aliquam
vel, ullamcorper sit amet ligula. Cras ultricies ligula sed magna dictum
porta. Pellentesque in ipsum id orci porta dapibus.
</p>
<p>
Proin eget tortor risus. Donec sollicitudin molestie malesuada. Lorem
ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum ante ipsum
primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec
velit neque, auctor sit amet aliquam vel, ullamcorper sit amet ligula.
Curabitur aliquet quam id dui posuere blandit. Curabitur aliquet quam id
dui posuere blandit. Curabitur aliquet quam id dui posuere blandit.
Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere
cubilia Curae; Donec velit neque, auctor sit amet aliquam vel, ullamcorper
sit amet ligula. Praesent sapien massa, convallis a pellentesque nec,
egestas non nisi. Vestibulum ac diam sit amet quam vehicula elementum sed
sit amet dui.
</p>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin eget tortor
risus. Curabitur non nulla sit amet nisl tempus convallis quis ac lectus.
Vivamus suscipit tortor eget felis porttitor volutpat. Pellentesque in
ipsum id orci porta dapibus. Cras ultricies ligula sed magna dictum porta.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque in
ipsum id orci porta dapibus. Vestibulum ante ipsum primis in faucibus orci
luctus et ultrices posuere cubilia Curae; Donec velit neque, auctor sit
amet aliquam vel, ullamcorper sit amet ligula. Praesent sapien massa,
convallis a pellentesque nec, egestas non nisi.
</p>
</div>
);
export default App;
索引.tsx
import { render } from "react-dom";
import App from "./App";
render(<App />, document.getElementById("root"));
样式.css
.app {
margin-top: 120px;
font-family: sans-serif;
text-align: center;
min-height: 120vh;
}
.navbar-top {
padding: 0;
background: #dadada;
border-bottom: 2px solid #ccc;
}
.nav-link {
padding: 2px 20px;
}
.search-box {
height: 35px;
}
::-moz-focus-inner {
border: 0;
}
::-webkit-scrollbar {
display: none;
}
html,
body {
margin: 0;
padding: 0;
background: #f9f9f9;
}
*,
:after,
:before {
-ms-overflow-style: none;
scrollbar-width: none;
box-sizing: border-box;
}
推荐阅读
- macos - 我无法在 VM Ware 虚拟机上打开 Mac OS Mojave,并且上面有我需要恢复的数据文件
- laravel - 在 laravel 的登录控制器中添加太多尝试
- javascript - 使用 JS 和 Firebase 上传图像后显示模式
- ruby - 如何在 ruby 中抓取下一页
- php - 使用 PHP fwrite 从下拉表单中选择的文件中写回文本文件时遇到问题
- c# - C#:使用反射按名称获取字段/属性/方法值(字符串或 uint)
- c++ - ios::fmtflags 在 C++ 中是如何工作的? setf() 是如何工作的?
- amazon-s3 - aws s3 通知包括元数据信息
- javascript - 如何在 vuejs 中创建动态行跨度表?
- typescript - 来自类型数组的 Typescript 泛型类型约束