赞
踩
前面两章把基础简单介绍了,这一章开始就要正式搭建了,若有不正确的地方虚心接收大家的指正。
思考了一下还是把自己的目录习惯介绍一下吧,这样大家看起来应该更容易理解一点,因为我自己经常也是看到别人文章没看到目录介绍,跟着写就发现了对不上的情况!
在第一章就介绍了初始化的文件目录,这里就不介绍当时介绍过的目录了,要是忘记了可以去第一章节回顾;
components:与vue一样放置组件使用
layout:顾名思义,这是一个布局文件夹
router:因为这是属于单页面应用,局部刷新就少不了这个文件夹里面的东西
store:这是redux的全局状态管理仓库文件夹
store/actions:封装操作状态的方法的文件夹
store/reducers:放置模块化
store/connect.js:封装统一的装饰器使用
store/index.js:状态管理器的主入口文件
utils:放置一些工具函数
views:放置页面模块
关于这个我不做过多的赘述了,这个地方不知道的可以去参考我的另一个文章,传送门。
就说下持久化保存吧,因为这里毕竟要用到
首先安装持久化的依赖
yarn add redux-persist
在store/index.js中使用
代码
- import {createStore, combineReducers} from 'redux'
-
- // redux的持久化保存
- import {persistReducer, persistStore} from "redux-persist";
- import storage from "redux-persist/lib/storage";
-
- //创建reducer以及初始化状态
- const reducer = (state = {
- count: 1
- }, action) => {
- // action中type代表动作的标识,用于触发行为,payload代表传递的参数
- switch (action.type) {
- case 'ADD':
- return {...state, count: state.count + action.payload}
- case 'REDUCE':
- return {...state, count: state.count - action.payload}
- default:
- return state
- }
- }
-
- //定义配置的信息
- const persistConfig = {
- key: "root",
- storage: storage,
- // 如果不想将部分state持久化,可以将其放入黑名单(blacklist)中.黑名单是设置
- // blacklist: ['ll']
- }
- //创建持久化的配置persist的信息
- const persist_reducers = persistReducer(persistConfig, reducer);
-
- //创建状态管理器
- const store = createStore(persist_reducers)
- const persistor = persistStore(store);
-
- export {store, persistor}
-
-
这地方是还未做拆分的,后面会做reducer的拆分,方便管理;
在入口文件处需要设置
注:如果不知道这里的Provider是什么意思的可以去看我的《React-Redux使用connect,并封装装饰器》这个文章,里面是有写的
这里的路由就可以采用router6.x的特性,有一个useRouter的HOOK,这个写法就相当于vue里面的路由,单独拆成一个json文件,这样就更加易于维护管理了;
但是不局限于这个方式,喜欢router5.x的也可以采用循环方式注册路由,这里就看个人的习惯;
在layout文件夹下面创建Home.jsx文件、在views下创建404.jsx和login.jsx;
然后在router下创建index.jsx文件,创建路由;
router/index.jsx
- import React, {lazy ,Suspense} from "react";
-
- const routes = [
- {
- path:'/',
- component:lazy(()=>import('@/layout/Home'))
- },
- {
- path:'/login',
- title:'登录',
- component:lazy(()=>import('@/views/login'))
- },
- {
- path:'*',
- title:'404',
- component:lazy(()=>import('@/views/404'))
- }
- ]
-
- // 懒加载
- const syncRouter = (table)=>{
- let mRouteTable=[]
- table.forEach((route)=>{
- mRouteTable.push({
- path:route.path,
- element:(
- <Suspense fallback={<div>路由加载中...</div>}>
- <route.component />
- </Suspense>
- ),
- children:route.children&&syncRouter(route.children)
- })
- })
- return mRouteTable
- }
-
- export const newRoutes = syncRouter(routes)
然后在App.jsx文件中引入使用
最后在主入口文件main.jsx中引入注册
在网页上验证是否生效
输入错误的路由,进入了404的页面去了
到这里说明你的路由成功了
前面已经导入了antd5.x版本的组件了,所以这里可以直接按需引入使用antd的组件
这里采用的是这种布局方式
可以根据antd文档上的代码,写自己的业务需求
layout/Home.jsx
按照文档的代码复制进去,打开页面
现在已经把局布好了,但是这个点击左边右边并不会更新;那是因为路由并没有与这个页面关联起来,所以点击左边右边是不会切换刷新的;
根据布局我们能看出,内容模块处于的不是一级路由,所以我们要创建子路由文件了;
在views文件夹下面创建测试的模块以及对应的jsx文件
在这里我创建了一个中间页面layout/LayoutPage.jsx;若熟悉vue的 朋友就可以看出这个的用处,多层嵌套使用这个占位;
接下来我们就需要把这个路由文件在redux中引入,做全局使用,并且把这个在封装一个在antd的Menus组件使用的数据,方便在布局页面直接使用,而且不会出现还未初始化成功的同步问题;
上图这个是我处理的菜单栏的数据,也可以直接根据需求把这个写成菜单json数据,我这里根据路由文件处理的是为了方便做动态路由,简单说说我这里怎么来处理的吧;
第一步:路由文件里面去调取redux的actions
第二步:处理菜单栏
第三步:在布局组件里使用
这样就已经把菜单栏目配置好了,但是你会发现无论怎么切换嵌套路由地址依然不会变化,那是因为缺少占位的组件Outlet;
今天看到一段话是这样描述outlet的。说的是嵌套路由,可以保证子路由共享父路由的界面而不会覆盖。为此React提供了Outlet组件,将其用于父组件中可以为子路由的元素占位,并最终渲染子路由的元素。
这句话的意思大概就是说outlet是应用于嵌套路由的占位的。PS:如果是一级路由的话,我个人的理解还是要用Routes跟Route搭配的;
忘记说了,前面创建了一个占位组件LayoutPage.jsx 内部写法如下
到这一步的话就恭喜你已经可以通过地址栏更改路由了
到这里还没满足我们的需求,就是点击左边切换内容数据,那么该怎么做呢?
这里的话就要用到我们的路由跳转功能了,这里因为我们用的路由文件方式,那么就采用useNavigate这个方式跳转;
按照教程引入并使用:
点击菜单栏出现了下方的错
这是因为用的类组件方式,并不支持这种方式,那就要采用其他方式了,这里就需要包裹一层才能使用这个方式了;
layout/Home.jsx的修改成包裹方式导出
代码
- const widthUseNavigate = (WrapCompontent)=>{
- // 设置别名
- WrapCompontent.displayName = `widthUseNavigate${getDisplayName(WrapCompontent)}`
- return function NavigateCompont() {
- const navigate = useNavigate()
- const location = useLocation()
- // 给传入的组件新增一个to方法,传给原始组件的props,在原始组件中通过this.props.to(参数)使用
- return <WrapCompontent to={navigate} location={location}></WrapCompontent>
- }
- }
-
- const getDisplayName = (WrapCompontent)=>{
- return WrapCompontent.displayname || WrapCompontent.name || 'Component'
- }
-
-
- // 使用高阶组件包裹当前类组件
- const NavigateCompont = widthUseNavigate(Home);
然后再打印一下Home组件的props你就会发现,这里面又多出来很多东西
这样你就可以直接使用to方式跳转组件了;
这里点击菜单栏获取到的参数里面有两个参数key、keyPath,根据这两个就可以组装跳转路由地址了
这里只是做演示,具体的嵌套需要自己去处理
做到这步就可以点击左边然后右边跟随变化了,但是这里有一个需要自己去处理,就是通过this.props里面的location这个参数去获取当前的路由去做初次进来渲染左边默认选中的路由;
到这里就差不多结束了联动的操作了,这个章节的内容到这里就结束了,到这个章节的代码链接放在下面,需要的可以自行去看看,
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。