diff --git a/README.MD b/README.MD index 823eef1..cfd3bf8 100644 --- a/README.MD +++ b/README.MD @@ -1,17 +1,15 @@ -# 秦时明月 - ### 技术栈 +### 技术栈 * vite * react * react-router * redux + * redux-saga * windicss ### 目的 -制作一个展示秦时明月的网站 - > 资源链接: > [React Router](https://reactrouter.com/web/guides/quick-start) > [vite](https://cn.vitejs.dev/config/#resolve-alias) @@ -19,3 +17,4 @@ > [react-admin](https://gitee.com/sxfad/react-admin?_from=gitee_search) > [实现SLOT](https://www.jb51.net/article/165648.htm) > [context](https://www.jianshu.com/p/65b348bf86ad) +> [redux-saga](https://redux-saga-in-chinese.js.org/) diff --git a/package-lock.json b/package-lock.json index 2db5319..940b9ab 100644 --- a/package-lock.json +++ b/package-lock.json @@ -310,6 +310,53 @@ "fastq": "^1.6.0" } }, + "@redux-saga/core": { + "version": "1.1.3", + "resolved": "https://registry.npm.taobao.org/@redux-saga/core/download/@redux-saga/core-1.1.3.tgz", + "integrity": "sha1-MIUJe1ek6o21Uo1YZz8gzglQ9qQ=", + "requires": { + "@babel/runtime": "^7.6.3", + "@redux-saga/deferred": "^1.1.2", + "@redux-saga/delay-p": "^1.1.2", + "@redux-saga/is": "^1.1.2", + "@redux-saga/symbols": "^1.1.2", + "@redux-saga/types": "^1.1.0", + "redux": "^4.0.4", + "typescript-tuple": "^2.2.1" + } + }, + "@redux-saga/deferred": { + "version": "1.1.2", + "resolved": "https://registry.npm.taobao.org/@redux-saga/deferred/download/@redux-saga/deferred-1.1.2.tgz", + "integrity": "sha1-WZN6Drpx//KJ8TECM7xRgRenGIg=" + }, + "@redux-saga/delay-p": { + "version": "1.1.2", + "resolved": "https://registry.nlark.com/@redux-saga/delay-p/download/@redux-saga/delay-p-1.1.2.tgz", + "integrity": "sha1-j1FfSwCbBbAqN6fD0Mqd3BV7s1U=", + "requires": { + "@redux-saga/symbols": "^1.1.2" + } + }, + "@redux-saga/is": { + "version": "1.1.2", + "resolved": "https://registry.npm.taobao.org/@redux-saga/is/download/@redux-saga/is-1.1.2.tgz", + "integrity": "sha1-rmyEIfWPy6gPr3ytt9ZbMDuX5Y4=", + "requires": { + "@redux-saga/symbols": "^1.1.2", + "@redux-saga/types": "^1.1.0" + } + }, + "@redux-saga/symbols": { + "version": "1.1.2", + "resolved": "https://registry.nlark.com/@redux-saga/symbols/download/@redux-saga/symbols-1.1.2.tgz", + "integrity": "sha1-IWpnKkh/wlaHK4A0g1r8IqLQWV0=" + }, + "@redux-saga/types": { + "version": "1.1.0", + "resolved": "https://registry.npm.taobao.org/@redux-saga/types/download/@redux-saga/types-1.1.0.tgz", + "integrity": "sha1-DoHOVrSIO0sqMAHr4aspi4QjcgQ=" + }, "@rollup/pluginutils": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.1.0.tgz", @@ -455,6 +502,14 @@ "picomatch": "^2.0.4" } }, + "axios": { + "version": "0.21.1", + "resolved": "https://registry.nlark.com/axios/download/axios-0.21.1.tgz", + "integrity": "sha1-IlY0gZYvTWvemnbVFu8OXTwJsrg=", + "requires": { + "follow-redirects": "^1.10.0" + } + }, "babel-plugin-syntax-jsx": { "version": "6.18.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz", @@ -646,6 +701,11 @@ "to-regex-range": "^5.0.1" } }, + "follow-redirects": { + "version": "1.14.1", + "resolved": "https://registry.nlark.com/follow-redirects/download/follow-redirects-1.14.1.tgz?cache=0&sync_timestamp=1620555300559&other_urls=https%3A%2F%2Fregistry.nlark.com%2Ffollow-redirects%2Fdownload%2Ffollow-redirects-1.14.1.tgz", + "integrity": "sha1-2RFN7Qoc/dM04WTmZirQK/2R/0M=" + }, "fsevents": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", @@ -1047,6 +1107,14 @@ "symbol-observable": "^1.2.0" } }, + "redux-saga": { + "version": "1.1.3", + "resolved": "https://registry.npm.taobao.org/redux-saga/download/redux-saga-1.1.3.tgz", + "integrity": "sha1-nz5q69PJlLvA9pAaYl+aQrUdERI=", + "requires": { + "@redux-saga/core": "^1.1.3" + } + }, "regenerator-runtime": { "version": "0.13.7", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", @@ -1258,6 +1326,27 @@ "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==", "dev": true }, + "typescript-compare": { + "version": "0.0.2", + "resolved": "https://registry.npm.taobao.org/typescript-compare/download/typescript-compare-0.0.2.tgz", + "integrity": "sha1-fuQKQApAbC6gp+VR79MwkCHV9CU=", + "requires": { + "typescript-logic": "^0.0.0" + } + }, + "typescript-logic": { + "version": "0.0.0", + "resolved": "https://registry.npm.taobao.org/typescript-logic/download/typescript-logic-0.0.0.tgz", + "integrity": "sha1-ZuvYKiVI8rREpDZnvsEgtJaJAZY=" + }, + "typescript-tuple": { + "version": "2.2.1", + "resolved": "https://registry.npm.taobao.org/typescript-tuple/download/typescript-tuple-2.2.1.tgz", + "integrity": "sha1-fZgT+0s1X2msVQMuA2Pouw8E2tI=", + "requires": { + "typescript-compare": "^0.0.2" + } + }, "value-equal": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", diff --git a/package.json b/package.json index b05da11..e90fce3 100644 --- a/package.json +++ b/package.json @@ -6,12 +6,14 @@ "serve": "vite preview" }, "dependencies": { + "axios": "^0.21.1", "classnames": "^2.3.1", "react": "^17.0.0", "react-dom": "^17.0.0", "react-redux": "^7.2.4", "react-router-dom": "^5.2.0", "redux": "^4.1.0", + "redux-saga": "^1.1.3", "styled-jsx": "^3.4.4" }, "devDependencies": { diff --git a/src/AppRouter.tsx b/src/AppRouter.tsx index 8ab753b..7520282 100644 --- a/src/AppRouter.tsx +++ b/src/AppRouter.tsx @@ -6,17 +6,23 @@ import { pageList } from "@/plugins/pageHoc" import Layout from "@/views/Layout" import Auth from "@/ui/Auth" -import routes from "./route" +import routes, { Loading } from "./route" -function Wrapper(props: any) { - if (props.loading) { - return }>{props.children} +function NormalLoading() { + return +} + +function LoadWrapper(props: any) { + if (props.isLazy) { + const LoadingComp=props.loading?props.loading: ()=> //NormalLoading; + return }>{props.children} } return {props.children} } function RouteMap(props: any) { const routes: any[] = props.routes + return ( {routes.map((route, index) => { @@ -31,11 +37,9 @@ function RouteMap(props: any) { if (route.component) { return ( - - - {route.children && } - - + + {route.children && } + ) } diff --git a/src/route.tsx b/src/route.tsx index 9caf37c..84f92f7 100644 --- a/src/route.tsx +++ b/src/route.tsx @@ -5,7 +5,7 @@ function Test() { return
TExtas
} -const Loading = (props: any) =>
Lodeing.22..
+export const Loading = (props: any) =>
Lodeing.22..
let delay = (Comp: any, duration = 1000) => diff --git a/src/store/action/todo.ts b/src/store/action/todo.ts index bd00bf5..9ab5e98 100644 --- a/src/store/action/todo.ts +++ b/src/store/action/todo.ts @@ -1,11 +1,11 @@ -import {ADD, REMOVE} from "@/store/constant/todo" +import {ADD, REMOVE, ADD_ASYNC} from "@/store/constant/todo" let nextTodoId = 0 type Action = (param: any) => IAction export const addTodo: Action = text => ({ - type: ADD, + type: ADD_ASYNC, id: nextTodoId++, text }) diff --git a/src/store/constant/todo.ts b/src/store/constant/todo.ts index 7ec6bd2..dc364ae 100644 --- a/src/store/constant/todo.ts +++ b/src/store/constant/todo.ts @@ -1,2 +1,4 @@ export const ADD = "ADD_TODO" +export const ADD_ASYNC = "ADD_ASYNC" + export const REMOVE = "REMOVE_TODO" diff --git a/src/store/index.ts b/src/store/index.ts index f5ca2dc..7dc002a 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -1,8 +1,13 @@ -import {combineReducers, createStore} from 'redux' +import {applyMiddleware, combineReducers, createStore} from 'redux' import reducer from "./reducer" +import createSagaMiddleware from 'redux-saga' +import mySaga from './saga' + +const sagaMiddleware = createSagaMiddleware() const reduces = combineReducers(reducer) -const store = createStore(reduces) +const store = createStore(reduces, applyMiddleware(sagaMiddleware)) +sagaMiddleware.run(mySaga) export default store diff --git a/src/store/saga/index.ts b/src/store/saga/index.ts new file mode 100644 index 0000000..d3c93ce --- /dev/null +++ b/src/store/saga/index.ts @@ -0,0 +1,52 @@ +import { call, put, takeEvery, takeLatest } from "redux-saga/effects" +import { ADD, REMOVE, ADD_ASYNC } from "@/store/constant/todo" +import axios, { Method } from "axios" + +const instance = axios.create({ + timeout: 3000, +}) +const http = (method: Method = "GET", url: string) => { + return instance({ + method, + url, + }) +} + +let Api: any = { + fetchUser: async (id: any) => { + return await http("GET", "https://gank.io/api/v2/banners") + }, +} + +// worker Saga : 将在 USER_FETCH_REQUESTED action 被 dispatch 时调用 +function* fetchUser(action: any) { + try { + // @ts-ignore + const user = yield call(Api.fetchUser, action?.id) + console.log(user) + yield put({ type: ADD, id: action.id, text: user.data.data[0].image }) + } catch (e) { + yield put({ type: "USER_FETCH_FAILED", message: e.message }) + } +} + +/* + 在每个 `USER_FETCH_REQUESTED` action 被 dispatch 时调用 fetchUser + 允许并发(译注:即同时处理多个相同的 action) +*/ +function* mySaga() { + yield takeEvery(ADD_ASYNC, fetchUser) +} + +/* + 也可以使用 takeLatest + + 不允许并发,dispatch 一个 `USER_FETCH_REQUESTED` action 时, + 如果在这之前已经有一个 `USER_FETCH_REQUESTED` action 在处理中, + 那么处理中的 action 会被取消,只会执行当前的 +*/ +// function* mySaga() { +// yield takeLatest("USER_FETCH_REQUESTED", fetchUser) +// } + +export default mySaga diff --git a/src/views/Home/Header.tsx b/src/views/Home/Header.tsx index 0c31790..2c187ed 100644 --- a/src/views/Home/Header.tsx +++ b/src/views/Home/Header.tsx @@ -1,7 +1,7 @@ import React, { useState } from "react" export default () => { - const title = "美女管理后台" + const title = "TEST" const [leftMenuList, setLeftMenuList] = useState([ { title: "首页", path: "/" }, { title: "角色", children: [{ title: "月儿", path: "/about" }] }, diff --git a/src/views/Login/index.module.scss b/src/views/Login/index.module.scss new file mode 100644 index 0000000..b4908d6 --- /dev/null +++ b/src/views/Login/index.module.scss @@ -0,0 +1,3 @@ +.login.page{ + background-color: red; +} \ No newline at end of file diff --git a/src/views/Login/index.tsx b/src/views/Login/index.tsx index 0def55d..3f3eb93 100644 --- a/src/views/Login/index.tsx +++ b/src/views/Login/index.tsx @@ -1,4 +1,6 @@ import React from "react" +import cn from "classnames" +import style from "./index.module.scss" import { useLocation, Route, Switch } from "react-router-dom" function Test() { @@ -6,11 +8,8 @@ function Test() { } export default function (props: any) { - let location = useLocation() - console.log(location) - console.log(props) return ( -
+
Login
22