|
前言
学无止境,无止境学。坚持每天学点编程知识,坚持每天写点小文章,坚持每天进步一点点。大家好,我是张大鹏,喜欢学习和分享,希望能够通过此公众号,将自己学到的东西分享给大家,和大家一起交流,一起成长,一起进步。
乾坤未定,你我皆是黑马。大鹏一日同风起,扶摇直上九万里。宝剑锋从磨砺出,梅花香自苦寒来。不积跬步,无以至千里,不积小流无以成江海。
如果有多余的时间,就坚持学习吧,小时候学习改变命运,长大了学习丰富内涵,老了学习带来宁静。活到老,学到老,我能行!
课程介绍
收费说明
《JavaScript全栈班》收费说明:
- 时长:50节课
- 价格:9999元
- 内容:
- NodeJS开发后端API
- React开发H5端
- Electron开发桌面端软件
- ReactNative开发Android和iOS跨端APP
- 上课方式:腾讯会议小班教学
- 联系电话(同微信):18010070052
课程大纲
本篇文章是《JavaScript全栈班》的第25篇文章,前面还有:
- 《搭建JavaScript全栈开发环境》
- 《NodeJS和GraphQL构建社交笔记API》
- 《使用Express开发Web应用》
- 《第一个GraphQL API》
- 《基于GraphQL的笔记增删改查API》
- 《NodeJS整合MongoDB》
- 《GraphQL整合MongoDB》
- 《GraphQL模块化开发》
- 《GraphQL实现增删改查API》
- 《GraphQL自定义日期时间类型》
- 《NodeJS密码加密和校验》
- 《NodeJS实现JWT Token》
- 《GraphQL整合JWT实现用户注册登录》
- 《GraphQL请求上下文的用法》
- 《GraphQL控制用户新增和删除笔记权限》
- 《GraphQL权限模块设计》
- 《GraphQL模块化开发Resolver》
- 《MongoDB分表操作》
- 《GraphQL实现收藏笔记功能》
- 《GraphQL接口安全和分页》
- 《使用Docker部署GraphQL项目》
- 《GraphQL项目升级》
- 《使用React创建笔记应用》
使用布局
目标
- 进一步简化代码,让代码更便于维护
- 降低重复代码
- 优化以后功能不变,页面结构不变
目录结构

从目录结构我们可以知道,我们需要实现的是:
- 新增layout.jsx,主要是抽取每个页面中的重复代码
- 修改pages下面的所有页面,主要是减少每个页面中的重复代码
src/components/layout.jsx
将每个页面中都会用到的头部组件和导航组件抽离出来,同时,提供一个Outlet占位空间,让React组件的内容可以被放置在指定的位置。
import React from &#39;react&#39;;import { Outlet } from &#34;react-router-dom&#34;;import Header from &#39;./header&#39;;import Navigation from &#39;./navigation&#39;;const Layout = () =>{ return ( <React.Fragment> <Header /> <div className=&#39;container&#39;> <Navigation /> <Outlet/> </div> </React.Fragment> )}export default Layout;
src/pages/index.jsx
主要是引入layout组件,同时将每个页面设置成layout组件中的子路由。每个组件的内容会被放置到layout组件中的Outlet位置。
import Home from &#34;./home&#34;import MyNotes from &#34;./mynotes&#34;import Favorites from &#34;./favorites&#34;import Layout from &#34;../components/layout&#34;const Pages = [ { path: &#34;/&#34;, element: <Layout />, children: [ { path: &#34;/&#34;, element: <Home/>, }, { path: &#34;/mynotes&#34;, element: <MyNotes/>, }, { path: &#34;/favorites&#34;, element: <Favorites/>, }, ] }, ]export default Pages;
src/pages/home.jsx
删除头部组件和导航组件以及多余的代码。
import React from &#39;react&#39;;const Home = () =>{ return ( <div> <p>首页</p> </div> )}export default Home;
src/pages/mynotes.jsx
删除头部组件和导航组件以及多余的代码。
import React, { useEffect } from &#34;react&#34;;const MyNotes = () =>{ useEffect( () => { document.title = &#34;我的笔记&#34; } ) return ( <div> <p>我的笔记</p> </div> )}export default MyNotes;
src/pages/favorites.jsx
删除头部组件和导航组件以及多余的代码。
import React, { useEffect } from &#34;react&#34;;const Favorites = () =>{ useEffect( () => { document.title = &#34;我的收藏&#34; } ) return ( <div> <p>我的收藏</p> </div> )}export default Favorites;
测试
启动服务:
npm run dev
访问以下页面:
- 首页:http://localhost:5173/
- 我的收藏:http://localhost:5173/favorites
- 我的笔记:http://localhost:5173/mynotes
StyleeComponents快速入门
参考文档
https://styled-components.com/docs/basics#installation
安装
npm install --save styled-components
自定义按钮组件
src/components/button.jsx
import styled from &#34;styled-components&#34;const Button = styled.button` display: block; padding: 10px; border: none; border-radius: 5px; font-size: 18px; color: #fff; background-color: #0077cc; cursor: pointer; :hover { opacity: 0.8; } :active { background-color: #005fa3; }`export default Button;
src/pages/home.jsx
import React from &#39;react&#39;;import Button from &#39;../components/button&#39;;const Home = () =>{ return ( <div> <p>首页</p> <Button>按钮</Button> </div> )}export default Home;
测试
启动服务:npm run dev
访问:http://localhost:5173/

样式美化
全局样式
安装依赖
安装依赖:https://necolas.github.io/normalize.css/
npm install normalize.css
src/components/global.jsx
import { createGlobalStyle } from &#34;styled-components&#34;;const GlobalStyle = createGlobalStyle` *, *:before, *:after { box-sizing: border-box; } body, html { height: 100%; margin: 0; } body { font-family: &#39;Roboto&#39;, sans-serif; font-size: 16px; line-height: 1.4; color: #333; background-color: #fff; } a:link, a:visited { color: #0077cc; } a:hover, a:focus { color: #004499; } code, pre { max-width: 100%; }`export default GlobalStyle;
src/main.jsx
import React from &#39;react&#39;import ReactDOM from &#39;react-dom/client&#39;import { createBrowserRouter, RouterProvider,} from &#34;react-router-dom&#34;;import &#39;normalize.css&#39;;import Pages from &#34;./pages&#34;;const router = createBrowserRouter( Pages);ReactDOM.createRoot(document.getElementById(&#39;root&#39;)).render( <React.StrictMode> <RouterProvider router={router} /> </React.StrictMode>)
通用样式
src/components/common.css.jsx
import styled from &#34;styled-components&#34;;// 容器样式export const Container = styled.div` @media(min-width: 768px){ display:flex; top: 64px; position: relative; height: calc(100% - 64px); width: 100%; flex: auto; flex-direction: column; }`// 内容样式export const Content = styled.div` position: fixed; height: calc(100% - 185px); width: 100%; padding: 1em; overflow-y: scroll; @media(min-width: 768px){ flex: 1; margin-left: 220px; height: calc(100% - 64px); width: calc(100% - 220px); }`
src/components/layout.jsx
import React from &#39;react&#39;;import { Outlet } from &#34;react-router-dom&#34;;import Header from &#39;./header&#39;;import Navigation from &#39;./navigation&#39;;import GlobalStyle from &#39;./global&#39;;import {Container, Content} from &#34;./common.css&#34;const Layout = () =>{ return ( <React.Fragment> <GlobalStyle /> <Header /> <Container> <Navigation /> <Content> <Outlet/> </Content> </Container> </React.Fragment> )}export default Layout;
测试
访问:http://localhost:5173/
头部样式
src/components/common.css.jsx
import styled from &#34;styled-components&#34;;// 头部样式export const HeaderBar = styled.header` width: 100%; padding: 0.5em 1em; display: flex; position: fixed; align-items: center; background-color: #fff; box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.25); z-index: 1;`// Logo文本export const LogoText = styled.h1` margin: 0; padding: 0; display: inline;`...
src/commonts/header.jsx
import React from &#34;react&#34;;import { HeaderBar, LogoText } from &#34;./common.css&#34;;import logo from &#34;../img/logo.svg&#34;;const Header = () =>{ return ( <HeaderBar> <img src={ logo } alt=&#34;笔记&#34; height=&#34;40&#34; /> <LogoText>笔记</LogoText> </HeaderBar> )}export default Header;
测试
访问:http://localhost:5173/
导航样式
src/components/common.css.jsx
import styled from &#34;styled-components&#34;;...// 导航样式export const Nav = styled.nav` padding: 1em; background-color: #f5f4f0; @media(max-width: 768px){ padding-top: 64px; } @media(min-width: 768px){ position: fixed; width: 220px; height: calc(100% - 64px); overflow-y: scroll; }`// 导航列表样式export const NavList = styled.ul` list-style: none; padding: 0; margin: 0; line-height: 2; a { text-decoration: none; font-weight: bold; font-size: 1.1em; color: #333; } a:visited { color: #333; } a:hover, a:focus { color: #0077cc; }`
src/commponents/navigation.jsx
import React from &#34;react&#34;;import { Link } from &#34;react-router-dom&#34;;import { Nav, NavList } from &#34;./common.css&#34;;const Navigation = () =>{ return ( <Nav> <NavList> <li> <Link to={`/`}>首页</Link> </li> <li> <Link to={`/favorites`}>我的收藏</Link> </li> <li> <Link to={`/mynotes`}>我的笔记</Link> </li> </NavList> </Nav> )}export default Navigation;
测试
访问:http://localhost:5173/

颜色调整(可选)
稍微调整以下各个部分的背景颜色:src/components/common.css.jsx
import styled from &#34;styled-components&#34;;// 头部样式export const HeaderBar = styled.header` width: 100%; padding: 0.5em 1em; display: flex; position: fixed; align-items: center; background-color: #FFFACD; box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.25); z-index: 1;`// Logo文本export const LogoText = styled.h1` margin: 0 0 0 0.25em; padding: 0; display: inline;`// 容器样式export const Container = styled.div` @media(min-width: 768px){ display:flex; top: 64px; position: relative; height: calc(100% - 64px); width: 100%; flex: auto; flex-direction: column; }`// 内容样式export const Content = styled.div` position: fixed; height: calc(100% - 185px); width: 100%; padding: 1em; overflow-y: scroll; background-color: #E6E6FA; @media(min-width: 768px){ flex: 1; margin-left: 220px; height: calc(100% - 64px); width: calc(100% - 220px); }`// 导航样式export const Nav = styled.nav` padding: 1em; background-color: #FFF8DC; @media(max-width: 768px){ padding-top: 64px; } @media(min-width: 768px){ position: fixed; width: 220px; height: calc(100% - 64px); overflow-y: scroll; }`// 导航列表样式export const NavList = styled.ul` list-style: none; padding: 0; margin: 0; line-height: 2; a { text-decoration: none; font-weight: bold; font-size: 1.1em; color: #333; } a:visited { color: #333; } a:hover, a:focus { color: #0077cc; }`
效果预览:

广告
广告位出租
本公众号接广告,20元1个广告位,有意向的欢迎联系我微信:18010070052
总结
以上就是本文要分享的全部内容了,如果您对跨端开发小程序和APP感兴趣,想要查看更多的文章,欢迎关注我的公众号“Python私教”。若其他平台代码显示混乱,大家也可以通过公众号查看排版正确的源码哈。
打赏20元然后评论“已打赏”,可以获取本文的所有源码哦。
我是大鹏,专注于IT领域的编程知识分享,提供付费的个人IT技能提升服务,若有相关需求,欢迎留言或私信我。
咱们下篇文章再见~ |
|