当前位置: 首页 > news >正文

学设计网站做守望同人的网站

学设计网站,做守望同人的网站,网架安装,昆明seo排名项目搭建 创建项目 # 使用npx创建项目 npx create-react-app my-react-app # 进入项目目录 cd my-react-app # 创建项目目录结构 mkdir -p src/{apis,assets,components,pages,store,utils} touch src/{App.js,index.css,index.js} 使用npx create-react-app创建项目#xff0…项目搭建 创建项目 # 使用npx创建项目 npx create-react-app my-react-app # 进入项目目录 cd my-react-app # 创建项目目录结构 mkdir -p src/{apis,assets,components,pages,store,utils} touch src/{App.js,index.css,index.js} 使用npx create-react-app创建项目进入项目目录后通过npm start启动。调整项目目录结构包括apis、assets、components、pages等多个文件夹。 使用技术 接入scss预处理器安装sass工具创建全局样式文件index.scss。 # 安装sass工具 npm i sass -D // 在src/index.scss中设置全局样式 body {font-family: Arial, sans-serif;background-color: #f4f4f4; } 引入组件库antd安装后在Login页面测试Button组件。 # 安装antd组件库 npm i antd // 在src/pages/Login/index.jsx中使用Button组件 import React from react; import { Button } from antd;const Login () {return (divButton typeprimary登录/Button/div); };export default Login; 使用react-router-dom配置基础路由创建Layout和Login组件并配置路由规则。 # 安装react-router-dom npm i react-router-dom // 在src/router/index.js中配置路由 import { createBrowserRouter } from react-router-dom; import Login from ../pages/Login; import Layout from ../pages/Layout;const router createBrowserRouter([{path: /,element: Layout /,},{path: /login,element: Login /,}, ]);export default router; 通过craco工具包配置别名路径在craco.config.js中设置webpack别名并在jsconfig.json中配置VsCode提示。 # 安装craco工具包 npm i craco/craco -D // 在craco.config.js中配置别名 const path require(path); module.exports {webpack: {alias: {: path.resolve(__dirname,src)}} }; // 在package.json中修改scripts命令 scripts: {start: craco start,build: craco build,test: craco test,eject: react-scripts eject } // 在src/router/index.js中使用别名 import { createBrowserRouter } from react-router-dom; import Login from /pages/Login; import Layout from /pages/Layout;const router createBrowserRouter([{path: /,element: Layout /,},{path: /login,element: Login /,}, ]);export default router; // 在jsconfig.json中配置VsCode提示 {compilerOptions: {baseUrl: ./,paths: {/*: [src/*]}} } 功能模块实现 登录模块 基本结构搭建         在Login/index.js创建登录页面结构引入antd组件使用/assets路径引入图片在Login/index.scss中设置样式。 import React from react; import { Card, Form, Input, Button } from antd; import logo from /assets/logo.png; import ./index.scss;const Login () {return (div classNameloginCard classNamelogin-containerimg classNamelogin-logo src{logo} alt /FormForm.ItemInput sizelarge placeholder请输入手机号 //Form.ItemForm.ItemInput sizelarge placeholder请输入验证码 //Form.ItemForm.ItemButton typeprimary htmlTypesubmit sizelarge block登录/Button/Form.Item/Form/Card/div); };export default Login; 表单校验实现 为Form组件设置validateTrigger为Form.Item组件设置name和rules属性进行表单校验。 import React from react; import { Form, Input, Button } from antd;const Login () {return (Form validateTrigger{[onBlur]}Form.Itemnamemobilerules{[{ required: true, message: 请输入手机号 },{pattern: /^1[3-9]\d{9}$/,message: 手机号码格式不对}]}Input sizelarge placeholder请输入手机号 //Form.ItemForm.Itemnamecoderules{[{ required: true, message: 请输入验证码 },]}Input sizelarge placeholder请输入验证码 maxLength{6} //Form.ItemForm.ItemButton typeprimary htmlTypesubmit sizelarge block登录/Button/Form.Item/Form); };export default Login; 获取登录表单数据 为Form组件设置onFinish属性在点击登录按钮时触发获取表单数据的函数。 import React from react; import { Form, Input, Button } from antd;const Login () {const onFinish formValue {console.log(formValue);};return (Form onFinish{onFinish}Form.ItemInput sizelarge placeholder请输入手机号 //Form.ItemForm.ItemInput sizelarge placeholder请输入验证码 //Form.ItemForm.ItemButton typeprimary htmlTypesubmit sizelarge block登录/Button/Form.Item/Form); };export default Login; 封装 request 工具模块 安装axios在utils/request.js中创建axios实例配置baseURL、请求拦截器和响应拦截器。 # 安装axios npm i axios import axios from axios;const http axios.create({baseURL: http://example.com/api,timeout: 5000 });// 请求拦截器 http.interceptors.request.use(config {return config; }, error {return Promise.reject(error); });// 响应拦截器 http.interceptors.response.use(response {return response.data; }, error {return Promise.reject(error); });export { http }; 使用 Redux 管理 token 安装react-redux和reduxjs/toolkit在store中创建userStore切片设置token初始状态和setUserInfo等reducers封装fetchLogin异步方法。 # 安装react-redux和reduxjs/toolkit npm i react-redux reduxjs/toolkit import { createSlice } from reduxjs/toolkit; import { http } from /utils;const userStore createSlice({name: user,initialState: {token: },reducers: {setUserInfo(state, action) {state.token action.payload;}} });const { setUserInfo } userStore.actions; const userReducer userStore.reducer;const fetchLogin loginForm {return async dispatch {const res await http.post(/authorizations, loginForm);dispatch(setUserInfo(res.data.token));}; };export { fetchLogin }; export default userReducer; 实现登录逻辑 在Login组件中调用fetchLogin方法登录成功后跳转到首页并提示。 import React from react; import { message } from antd; import { useDispatch } from react-redux; import { fetchLogin } from /store/modules/user;const Login () {const dispatch useDispatch();const onFinish async formValue {await dispatch(fetchLogin(formValue));message.success(登录成功);};return (divform onSubmit{onFinish}{/* 登录表单字段 */}/form/div); };export default Login; token 持久化 封装setToken、getToken和clearToken方法在userStore中setUserInfo时将token存入本地。 // 在/utils/token.js中封装存取方法 const TOKENKEY token_key;function setToken(token) {return localStorage.setItem(TOKENKEY, token); }function getToken() {return localStorage.getItem(TOKENKEY); }function clearToken() {return localStorage.removeItem(TOKENKEY); }export {setToken,getToken,clearToken }; // 在userStore中使用token持久化方法 import { createSlice } from reduxjs/toolkit; import { http } from /utils; import { getToken, setToken } from /utils/token;const userStore createSlice({name: user,initialState: {token: getToken() || },reducers: {setUserInfo(state, action) {state.token action.payload;setToken(state.token);}} });export default userStore; 请求拦截器注入 token 在request.js的请求拦截器中判断是否有token有则添加到请求头Authorization中。 // 在utils/request.js中注入token import axios from axios;const http axios.create({baseURL: http://example.com/api,timeout: 5000 });http.interceptors.request.use(config {const token getToken();if (token) {config.headers.Authorization Bearer ${token};}return config; }, error {return Promise.reject(error); });http.interceptors.response.use(response {return response.data; }, error {return Promise.reject(error); });export { http }; 路由鉴权实现 在components/AuthRoute/index.jsx中创建路由鉴权高阶组件判断本地是否有token决定是否重定向到登录页面。 import React from react; import { Navigate } from react-router-dom; import { getToken } from /utils;const AuthRoute ({ children }) {const isToken getToken();if (isToken) {return {children}/;} else {return Navigate to/login replace /;} };export default AuthRoute; // 在src/router/index.js中使用AuthRoute组件 import { createBrowserRouter } from react-router-dom; import Login from /pages/Login; import Layout from /pages/Layout; import AuthRoute from /components/AuthRoute;const router createBrowserRouter([{path: /,element: AuthRouteLayout //AuthRoute,},{path: /login,element: Login /,}, ]);export default router; Layout 模块 基本结构和样式 reset 在pages/Layout/index.js中使用antd/Layout组件创建页面结构引入antd的Menu和Popconfirm等组件设置样式并安装normalize.css进行样式 reset。 import React from react; import { Layout, Menu, Popconfirm } from antd; import { HomeOutlined, DiffOutlined, EditOutlined, LogoutOutlined } from ant-design/icons; import ./index.scss; import normalize.css;const { Header, Sider } Layout;const items [{label: 首页,key: 1,icon: HomeOutlined /,},{label: 文章管理,key: 2,icon: DiffOutlined /,},{label: 创建文章,key: 3,icon: EditOutlined /,}, ];const GeekLayout () {return (LayoutHeader classNameheaderdiv classNamelogo /div classNameuser-infospan classNameuser-name用户名/spanspan classNameuser-logoutPopconfirm title是否确认退出 okText退出 cancelText取消LogoutOutlined / 退出/Popconfirm/span/div/HeaderLayoutSider width{200} classNamesite-layout-backgroundMenumodeinlinethemedarkdefaultSelectedKeys{[1]}items{items}style{{ height: 100%, borderRight: 0 }}/Menu/SiderLayout classNamelayout-content style{{ padding: 20 }}内容/Layout/Layout/Layout); };export default GeekLayout; 二级路由配置 在pages目录创建Home、Article、Publish页面文件夹在router/index.js中配置嵌套子路由在Layout中配置二级路由出口使用Link修改左侧菜单内容实现路由切换。 // 在pages目录创建Home.jsx import React from react;const Home () {return div首页内容/div; };export default Home; // 在pages目录创建Article.jsx import React from react;const Article () {return div文章管理内容/div; };export default Article; // 在pages目录创建Publish.jsx import React from react;const Publish () {return div发布文章内容/div; };export default Publish; // 在src/router/index.js中配置二级路由 import { createBrowserRouter } from react-router-dom; import Login from /pages/Login; import Layout from /pages/Layout; import Publish from /pages/Publish; import Article from /pages/Article; import Home from /pages/Home; import { AuthRoute } from /components/AuthRoute;const router createBrowserRouter([{path: /,element: (AuthRouteLayout //AuthRoute),children: [{index: true,element: Home /,},{path: article,element: Article /,},{path: publish,element: Publish /,},],},{path: /login,element: Login /,}, ]);export default router; // 在Layout组件中配置二级路由出口 import React from react; import { Outlet } from react-router-dom;const GeekLayout () {return (Layout classNamelayout-content style{{ padding: 20 }}Outlet //Layout); };export default GeekLayout; 路由菜单点击交互实现 为Menu组件设置onClick属性实现点击菜单跳转路由通过useLocation获取当前路由路径实现菜单反向高亮。 import React from react; import { Outlet, useNavigate } from react-router-dom; import { HomeOutlined, DiffOutlined, EditOutlined, LogoutOutlined } from ant-design/icons;const items [{label: 首页,key: /,icon: HomeOutlined /,},{label: 文章管理,key: /article,icon: DiffOutlined /,},{label: 创建文章,key: /publish,icon: EditOutlined /,}, ];const GeekLayout () {const navigate useNavigate();const menuClick route {navigate(route.key);};return (LayoutHeader classNamemain-headerdiv classNamelogo /div classNameuser-infospan classNameuser-name用户名/spanspan classNameuser-logoutPopconfirm title是否确认退出 okText退出 cancelText取消LogoutOutlined / 退出/Popconfirm/span/div/HeaderLayoutSider width{200} classNamesite-layout-backgroundMenumodeinlinethemedarkselectedKeys{[1]}items{items}style{{ height: 100%, borderRight: 0 }}onClick{menuClick}/Menu/SiderLayout classNamelayout-content style{{ padding: 20 }}Outlet //Layout/Layout); };export default GeekLayout; // 菜单反向高亮实现 import React from react; import { Outlet, useLocation } from react-router-dom; import { HomeOutlined, DiffOutlined, EditOutlined, LogoutOutlined } from ant-design/icons;const items [{label: 首页,key: /,icon: HomeOutlined /,},{label: 文章管理,key: /article,icon: DiffOutlined /,},{label: 创建文章,key: /publish,icon: EditOutlined /,}, ];const GeekLayout () {const location useLocation();const selectedKey location.pathname;return (LayoutHeader classNamemain-headerdiv className 展示个人信息 在store/userStore.js中编写获取用户信息的逻辑在Layout组件中触发fetchUserInfo方法获取信息并渲染用户名。 // store/userStore.js import { createSlice } from reduxjs/toolkit; import { http } from /utils; import { getToken, setToken } from /utils;const userStore createSlice({name: user,initialState: {token: getToken() || ,userInfo: {}},reducers: {setUserToken(state, action) {state.token action.payload;setToken(state.token);},setUserInfo(state, action) {state.userInfo action.payload;},clearUserInfo(state) {state.token ;state.userInfo {};clearToken();}} });// 解构出actionCreater const { setUserToken, setUserInfo, clearUserInfo } userStore.actions; // 获取reducer函数 const userReducer userStore.reducer;const fetchLogin (loginForm) {return async (dispatch) {const res await http.post(/authorizations, loginForm);dispatch(setUserToken(res.data.token));}; };const fetchUserInfo () {return async (dispatch) {const res await http.get(/user/profile);dispatch(setUserInfo(res.data));}; };export { fetchLogin, fetchUserInfo, clearUserInfo }; export default userReducer; 退出登录实现 为Popconfirm添加确认回调事件在store/userStore.js中新增clearUserInfo方法删除token和用户信息在回调事件中调用该方法并返回登录页面。 // pages/Layout/index.js import React, { useEffect } from react; import { Layout, Menu, Popconfirm } from antd; import {HomeOutlined,DiffOutlined,EditOutlined,LogoutOutlined, } from ant-design/icons; import { useDispatch, useSelector } from react-redux; import { fetchUserInfo } from /store/modules/user;const { Header, Sider } Layout;const items [// 菜单配置项 ];const GeekLayout () {const dispatch useDispatch();const name useSelector(state state.user.userInfo.name);useEffect(() {dispatch(fetchUserInfo());}, [dispatch]);const loginOut () {dispatch(clearUserInfo());// 假设这里有合适的导航函数替换为实际的导航逻辑// navigate(/login); };return (LayoutHeader classNameheaderdiv classNamelogo /div classNameuser-infospan classNameuser-name{name}/spanspan classNameuser-logoutPopconfirmtitle是否确认退出okText退出cancelText取消onConfirm{loginOut}LogoutOutlined / 退出/Popconfirm/span/div/HeaderLayoutSider width{200} classNamesite-layout-backgroundMenumodeinlinethemedarkdefaultSelectedKeys{[1]}items{items}style{{ height: 100%, borderRight: 0 }}/Menu/SiderLayout classNamelayout-content style{{ padding: 20 }}{/* 页面内容 */}/Layout/Layout/Layout); };export default GeekLayout; 处理 Token 失效 在http.interceptors.response中判断响应状态码为401时清除token跳转到登录页面并刷新页面。 // 在http.js假设是配置axios请求相关的文件中处理Token失效 import axios from axios;const http axios.create({baseURL: http://example.com/api,timeout: 5000 });http.interceptors.response.use((response) {return response.data; }, (error) {if (error.response error.response.status 401) {// 假设这里有合适的获取和清除token的函数替换为实际的逻辑const token getToken();if (token) {clearToken();}// 假设这里有合适的导航函数替换为实际的导航逻辑// navigate(/login); window.location.reload();}return Promise.reject(error); });export { http };
http://www.hkea.cn/news/14539784/

相关文章:

  • 中英西班牙网站建设公司网站建设概述
  • 建设工程评标专家在哪个网站登录北京住建网站
  • 建设一个大型网站大概费用甘肃省住房和城乡建设厅网站
  • 做网站 插件大叔 wordpress
  • 个人网站和企业网站的区别百度新闻源网站
  • 黄岐做网站企业品牌宣传
  • wordpress淘宝客自动采集wordpress++优化
  • 关于服饰搭配做的比较好的网站宁波网站建设费用报价
  • 做电影网站会被捉吗上海消费品网络营销推广公司
  • 域名网络的解析网站如何购买企业黄页网站
  • 网站搭建素材江苏建筑职业技术学院
  • 双城网站建设公司wordpress右侧
  • 个人网站做什么内容好网站建设高职考题目
  • 镇江网站建设价位镇江网站建设
  • 让网站快速收录国外营销网站
  • 电商会学着做网站呢广州出名的网站
  • 网站怎么做第三方支付接口扬州网站建设
  • 有哪些网站手游做的好的做排行榜的网站知乎
  • 建筑网站的功能模块自己做的网站网页错位
  • 推广做网站电话建设网站建设方案
  • 深圳专门网站制作换公司网站域名要改吗
  • 如何查询网站注册信息汽车网站开发背景
  • 产品互联网做推广做什么网站好用c语言做网站
  • 贵阳建站模板奉贤庄行网站建设
  • 做问卷的网站wordpress禁用自动保存
  • 电信 网站备案网站搭建需要什么技术
  • 网站首页布局设计教程西安网站搭建建设定制
  • 传统生意转型做那个网站好织梦图片网站
  • 网站如何被百度收录wordpress微信分享网页带图
  • 网站建设深圳赶集网短网址生成器下载