富贵汪记账React版
项目介绍
基于 React
/ React Router
/ 自定义 Hooks
/ webpack
/ TypeScrip
t / LocalStorage
实现的极简主义记账应用。
功能
1、记账:金额、标签、备注、收入或支出等。
2、管理标签:添加、改名、删除
3、实现效果 富贵汪记账 (gitee.io)
4、源码链接zxjdzxb/wealth-dog (github.com)
重点思路
用命令创建React
Create-react-app . --template typescript
在当前目录创建\
Git reset HEAD
查看更改过文件名称
目录声名
常用到文件:
public:index.html
src:App.tst;index.tsx;setupTests.ts\
这标签可以帮助检查代码错误给出提示\
<React.StrictMode> <App /> </React.StrictMode>
这个文件是typescript的声名文件
默认的配置文件
老师用的版本不支持dart-sass,用的小技巧,安装node-sass但把内容替换成dart-sass
yarn add node-sass@npm:dart-sass
正题
Styled-components
将css写到js里面,插件会自动翻译。这个真的好用,不用再为想className烦恼了
yarn add styled-components yarn add --dev @types/styled-components
React Router
yarn add react-router-dom yarn add --dev @types/react-router-dom
我用的History
但是我查了一下官方文档建议不要用HashRouter
reactrouterdotcom.fly.dev/docs/en/v6/…
哈希的好处是不需要后台服务器支持,如果走错路径也会有保底
@import-normalize;
写在scss中的样式,可以设置默认样式与网页一致,但VsCode会报错不认识,不影响。
在设置布局中用到了flex-grow:1
让显示内容尽量的高。并且在主要内容里加了一个overflow:auto
若显示内容超出,自动给里面加一个滚动条
底边框添加阴影:box-shadow:0 0 3px rgba(0,0,0,0.25);
SVG sprite loader
我自己用的添加class设置的照片,也成功了,但为了练习试了一下,这插件会在页面帮我们把引入的svg放到一个大的svg里包住,把大的svg放到body里面
yarn eject
命令可以提取出webpack的config文件进行更改
yarn add --dev svg-sprite-loader
安装 svg-sprite-loader
yarn add --dev svgo-loader
给照片添加属性
上边的console.log打印出来的是引入的照片会自带一个id,用哪个svg就里面放个use里并且引入这个id, 但引入不能用import照片还没改,要用require()
require()
他与import类似但import引用但不插入到页面会被DOM树删除,
require()引用不会被删除,但必须将内容被括号包括起
因为svg代码重复了三遍,创建一个组件,组件里就是其中一个svg做的事情,但因为id是个变量所以传进来时候要用props,但props有个参数“props”隐式具有“any”类型,但老师不让设置成any,自己定义了一个type 如图!
引入一整个目录,不再需要require每一个照片的路径了,这代码老师没说,直接让复制了。但复制后会有报错,需要安装插件 yarn add --dev @types/webpack-env
安装之后,就不会报错了,并且可以删除引用
let importAll = (requireContext: __WebpackModuleApi.RequireContext) =>requireContext.keys().forEach(requireContext); try {importAll(require.context('icons', true, /.svg$/));} catch (error) {console.log(error);}再用记得改icons地址!
NavLink
这是一个当点击摁键会变颜色的style 总共分为3步
- 把Link标签改为NavLink
- 把代码复制粘贴
- 改喜欢的颜色
style={({ isActive }) => ({ color: isActive ? 'green' : 'blue' })}
网络异常,图片无法展示|
无聊的写css中 记录一些被遗忘的布局
White-space:nowrap
阻止文字换行
:focus{outline: none;}
阻止默认选中的边框
标签里添加类似注释的
line-height:72px
css中尽量写行高,别写高度,容易污染吧?
box-shadow:inset 0 -5px 5px -5px rgba(0,0,0,0.25);
给边框设置个样式,不突兀
flex-grow:1;
剩下的空间都给他
overflow:hidden
溢出部分隐藏
text-overflow:ellipsis
超出部分用省略号\
将 Styled Component 改造为 Function Component
改造中遇到标签问题卡了许久,变成React 标签会变成自结束标签const tagName =window.prompt('新标签的名称为')
window的属性当点击时弹出对话框询问添加标签名称
Filter() 函数
Filter() 函数用于过滤序列,过滤掉不符合条件的元素,返回由符合条件元素组成的新列表。
Python filter() 函数 | 菜鸟教程 (runoob.com)
onChange事件
在添加受控组件(备注栏默认有事件,但要添加受控)时用到了onChange事件
.onChange={(e)=>setNote(e.target.value)
非受控组件:
非受控组件,不会监听变化过程,只需要记录当鼠标移出后的onBlur
最终结果,例如修改文档,只需要知道最后哪里加粗哪里空行即可。但Input
并没有将值传给note
这时就用到了useRef
拿到值,这个useRef
默认是个html
的input
元素,默认值为空。将这个值用setNote
放在Note
上。这样可以在用户将鼠标移出时获取到这个Input
的值
type X = {"-": string;"+": string;} type Y = "-" | "+"
这样useState
可以从categoryMap
里拿到key
**As**可以强制指定类型
switch case
switch (表达式) { case 常量表达式1: 语句1 break; case 常量表达式2: 语句2 break; case 常量表达式n: 语句n break; default: 语句n+1 }
若是表达式1则执行语句1,后边一定有个break!若是表达式n则执行语句n
Type Script
因为seleceted类型有四种,所以第16行代码Ttypeof获取这四种的值得类型,赋给Selected,然后obj:Partial<Selected> 给Partial传一个类型,类型里面有四种类型,Partial可以获取其中任意类型
封装自定义Hook
在函数里用useState、useRef等然后把读和写接口tuturn出去
抽离组件时,因为参数多,所以不一一写出来,用...rest
这个大概用法是一个一个的复制过来 除了label
,和childern
React封装了SVG,(window的一些属性,例如返回上一层菜单)
组件挂载后执行
JSON.parse将localStorage缓存变成对象
保存后弹提示成功
TypeScript提供了一个函数,Omit专门作用与类型。 意思是newRecordItem除去createdAt这一项.要是有两个不要的用"|"
时间库
Yarn add dayjs
一定要大写括号内容