深圳整站,wordpress安装时候500错误,网站如何提高权重,台州建设网站制作文章目录 一、项目起航#xff1a;项目初始化与配置二、React 与 Hook 应用#xff1a;实现项目列表三、TS 应用#xff1a;JS神助攻 - 强类型四、JWT、用户认证与异步请求五、CSS 其实很简单 - 用 CSS-in-JS 添加样式六、用户体验优化 - 加载中和错误状态处理七、Hook… 文章目录 一、项目起航项目初始化与配置二、React 与 Hook 应用实现项目列表三、TS 应用JS神助攻 - 强类型四、JWT、用户认证与异步请求五、CSS 其实很简单 - 用 CSS-in-JS 添加样式六、用户体验优化 - 加载中和错误状态处理七、Hook路由与 URL 状态管理八、用户选择器与项目编辑功能九、深入React 状态管理与Redux机制十、用 react-query 获取数据管理缓存十一、看板页面及任务组页面开发1~34.添加任务搜索功能5.优化看板样式6.创建看板与任务 学习内容来源React React Hook TS 最佳实践-慕课网 相对原教程我在学习开始时2023.03采用的是当前最新版本
项版本react react-dom^18.2.0react-router react-router-dom^6.11.2antd^4.24.8commitlint/cli commitlint/config-conventional^17.4.4eslint-config-prettier^8.6.0husky^8.0.3lint-staged^13.1.2prettier2.8.4json-server0.17.2craco-less^2.0.0craco/craco^7.1.0qs^6.11.0dayjs^1.11.7react-helmet^6.1.0types/react-helmet^6.1.6react-query^6.1.0welldone-software/why-did-you-render^7.0.1emotion/react emotion/styled^11.10.6
具体配置、操作和内容会有差异“坑”也会有所不同。。。 一、项目起航项目初始化与配置 一、项目起航项目初始化与配置 二、React 与 Hook 应用实现项目列表 二、React 与 Hook 应用实现项目列表 三、TS 应用JS神助攻 - 强类型 三、 TS 应用JS神助攻 - 强类型 四、JWT、用户认证与异步请求 四、 JWT、用户认证与异步请求(上) 四、 JWT、用户认证与异步请求(下) 五、CSS 其实很简单 - 用 CSS-in-JS 添加样式 五、CSS 其实很简单 - 用 CSS-in-JS 添加样式(上) 五、CSS 其实很简单 - 用 CSS-in-JS 添加样式(下) 六、用户体验优化 - 加载中和错误状态处理 六、用户体验优化 - 加载中和错误状态处理(上) 六、用户体验优化 - 加载中和错误状态处理(中) 六、用户体验优化 - 加载中和错误状态处理(下) 七、Hook路由与 URL 状态管理 七、Hook路由与 URL 状态管理(上) 七、Hook路由与 URL 状态管理(中) 七、Hook路由与 URL 状态管理(下) 八、用户选择器与项目编辑功能 八、用户选择器与项目编辑功能(上) 八、用户选择器与项目编辑功能(下) 九、深入React 状态管理与Redux机制 九、深入React 状态管理与Redux机制(一) 九、深入React 状态管理与Redux机制(二) 九、深入React 状态管理与Redux机制(三) 九、深入React 状态管理与Redux机制(四) 九、深入React 状态管理与Redux机制(五) 十、用 react-query 获取数据管理缓存 十、用 react-query 获取数据管理缓存上 十、用 react-query 获取数据管理缓存下 十一、看板页面及任务组页面开发
1~3 十一、看板页面及任务组页面开发一 4.添加任务搜索功能
接下来为任务看板添加搜索功能
编辑 src\screens\ViewBoard\utils.ts新增 useTasksSearchParams 为后续 SearchPanel 中数据联动做准备
import { useMemo } from react;
import { useLocation } from react-router;
import { useProject } from utils/project;
import { useUrlQueryParam } from utils/url;...
export const useTasksSearchParams () {const [param, setParam] useUrlQueryParam([name,typeId,processorId,tagId,]);const projectId useProjectIdInUrl();return useMemo(() ({projectId,typeId: Number(param.typeId) || undefined,processorId: Number(param.processorId) || undefined,tagId: Number(param.tagId) || undefined,name: param.name,}),[projectId, param]);
};
...新建 src\components\task-type-select.tsx仿照 UserSelect 改造出一个 TaskTypeSelect
import { useTaskTypes } from utils/task-type;
import { IdSelect } from ./id-select;export const TaskTypeSelect (props: React.ComponentPropstypeof IdSelect) {const { data: taskTypes } useTaskTypes();return IdSelect options{taskTypes || []} {...props} /;
};新建 src\screens\ViewBoard\components\SearchPanel.tsx
import { useSetUrlSearchParam } from utils/url
import { useTasksSearchParams } from ../utils
import { Row } from components/lib
import { Button, Input } from antd
import { UserSelect } from components/user-select
import { TaskTypeSelect } from components/task-type-selectexport const SearchPanel () {const searchParams useTasksSearchParams()const setSearchParams useSetUrlSearchParam()const reset () {setSearchParams({typeId: undefined,processorId: undefined,tagId: undefined,name: undefined})}return Row marginBottom{4} gap{true}Input style{{width: 20rem}} placeholder任务名 value{searchParams.name}onChange{e setSearchParams({name: e.target.value})}/UserSelect defaultOptionName经办人 value{searchParams.processorId}onChange{val setSearchParams({processorId: val})}/TaskTypeSelect defaultOptionName类型 value{searchParams.typeId}onChange{val setSearchParams({typeId: val})}/Button onClick{reset}清除筛选器/Button/Row
}编辑 src\screens\ViewBoard\index.tsx引入 SearchPanel
...
import { SearchPanel } from ./components/SearchPanel;export const ViewBoard () {...return (divh1{currentProject?.name}看板/h1SearchPanel/ColumnsContainer.../ColumnsContainer/div);
};
...查看功能和效果
5.优化看板样式
功能实现一部分了接下来优化样式
编辑 src\components\lib.tsx(新增 ViewContainer 处理内边距)
export const ViewContainer styled.divpadding: 3.2rem;width: 100%;display: flex;flex-direction: column;编辑 src\authenticated-app.tsx(调整 Main 样式垂直占满)
...
const Main styled.maindisplay: flex;/* overflow: hidden; */
;编辑 src\screens\ViewBoard\index.tsx(应用 ViewContainer 增加 Loading 调整 ColumnsContainer 样式并暴露出来使其触底)
...
import { useProjectInUrl, useTasksSearchParams, useViewBoardSearchParams } from ./utils;
...
import { ViewContainer } from components/lib;
import { useTasks } from utils/task;
import { Spin } from antd;export const ViewBoard () {...const { data: viewboards, isLoading: viewBoardIsLoading } useViewboards(useViewBoardSearchParams());const { isLoading: taskIsLoading } useTasks(useTasksSearchParams())const isLoading taskIsLoading || viewBoardIsLoadingreturn (ViewContainerh1{currentProject?.name}看板/h1SearchPanel /{isLoading ? Spin/ : ColumnsContainer.../ColumnsContainer}/ViewContainer);
};const ColumnsContainer styled.divdisplay: flex;overflow-x: scroll;flex: 1;
;编辑 src\screens\ProjectDetail\index.tsx(引入 Menu 并调整整个组件样式Menu 高亮状态从路由中获取)
import { Link, Navigate } from react-router-dom;
import { Route, Routes, useLocation } from react-router;
import { TaskGroup } from screens/TaskGroup;
import { ViewBoard } from screens/ViewBoard;
import styled from emotion/styled;
import { Menu } from antd;const useRouteType () {const pathEnd useLocation().pathname.split(/)return pathEnd[pathEnd.length - 1]
}export const ProjectDetail () {const routeType useRouteType()return (ContainerAsideMenu modeinline selectedKeys{[routeType]}Menu.Item keyviewboardLink toviewboard看板/Link/Menu.ItemMenu.Item keytaskgroupLink totaskgroup任务组/Link/Menu.Item/Menu/AsideMainRoutesRoute path/viewboard element{ViewBoard /} /Route path/taskgroup element{TaskGroup /} /Route index element{Navigate toviewboard replace /} //Routes/Main/Container);
};const Aside styled.asidebackground-color: rgb(244, 245, 247);display: flex;
const Main styled.divdisplay: flex;box-shadow: -5px 0 5px -5px rgbs(0, 0, 0, 0.1);overflow: hidden;
const Container styled.divdisplay: grid;grid-template-columns: 16rem 1fr;width: 100%;查看功能和效果
6.创建看板与任务
接下来新建创建看板的组件
先准备好调用新增看板接口的 Hook编辑 src\utils\viewboard.ts
...
export const useAddViewboard (queryKey: QueryKey) {const client useHttp();return useMutation((params: PartialViewboard) client(kanbans, {method: POST,data: params,}),useAddConfig(queryKey));
};新建组件src\screens\ViewBoard\components\CreateViewboard.tsx
import { useState } from react
import { useProjectIdInUrl, useViewBoardQueryKey } from ../utils
import { useAddViewboard } from utils/viewboard
import { Input } from antd
import { Container } from ./ViewboardCloumnexport const CreateViewBoard () {const [name, setName] useState()const projectId useProjectIdInUrl()const { mutateAsync: addViewBoard } useAddViewboard(useViewBoardQueryKey())const submit async () {await addViewBoard({name, projectId})setName()}return ContainerInputsizelargeplaceholder新建看板名称onPressEnter{submit}value{name}onChange{evt setName(evt.target.value)}//Container
}编辑src\screens\ViewBoard\index.tsx引入 CreateViewBoard
...
import { CreateViewBoard } from ./components/CreateViewboard;export const ViewBoard () {...return (ViewContainer...{isLoading ? Spin/ : ColumnsContainer{viewboards?.map((vbd) (ViewboardColumn viewboard{vbd} key{vbd.id} /))}CreateViewBoard//ColumnsContainer}/ViewContainer);
};
...查看功能和效果输入新增看板名后回车即可看到新看板
接下来新建创建任务的组件
先准备好调用新增任务接口的 Hook编辑 src\utils\task.ts
...
import { QueryKey, useMutation, useQuery } from react-query;
import { useAddConfig } from ./use-optimistic-options;...
export const useAddTask (queryKey: QueryKey) {const client useHttp();return useMutation((params: PartialTask) client(tasks, {method: POST,data: params,}),useAddConfig(queryKey));
};新建组件src\screens\ViewBoard\components\CreateTask.tsx
import { useEffect, useState } from react;
import { useProjectIdInUrl, useTasksQueryKey } from ../utils;
import { Card, Input } from antd;
import { useAddTask } from utils/task;export const CreateTask ({kanbanId}: {kanbanId: number}) {const [name, setName] useState();const { mutateAsync: addTask } useAddTask(useTasksQueryKey());const projectId useProjectIdInUrl();const [inputMode, setInputMode] useState(false)const submit async () {await addTask({ name, projectId, kanbanId });setName();setInputMode(false)};const toggle () setInputMode(mode !mode)useEffect(() {if (!inputMode) {setName()}}, [inputMode])if (!inputMode) {return div onClick{toggle}创建任务/div}return (CardInputonBlur{toggle}placeholder需要做些什么autoFocus{true}onPressEnter{submit}value{name}onChange{(evt) setName(evt.target.value)}//Card);
};编辑src\screens\ViewBoard\components\ViewboardCloumn.tsx引入 CreateTask
...
import { CreateTask } from ./CreateTask;...
export const ViewboardColumn ({ viewboard }: { viewboard: Viewboard }) {...return (Containerh3{viewboard.name}/h3TasksContainer...CreateTask kanbanId{viewboard.id}//TasksContainer/Container);
};
...查看功能和效果点击 创建任务 输入框出现点击输入框以外的地方输入框隐藏输入新增任务名后回车即可看到新任务 部分引用笔记还在草稿阶段敬请期待。。。