该项目的主要功能是增删改查笔记,笔记可以使用 markdown 语法编写,笔记内容展示 markdown 语法编译后内容。
前端:
后台:
搜索结果
新增笔记
笔记详情
编辑页面
前端:
后台:
主要解决各大浏览器默认样式不同的问题。同时相比 reset.css ,normalize.css 可以模块化引入、修复了浏览器的一些 bug、还没有复杂的继承链。
可以 通过状态 state 实现对类名的控制
import cs from 'classnames'
const [state, setState] = useState()
<Layout className={cs(
globalStyles.layout,
styles.layout, {
'layout': state,
})} >
还挺好用的,但是如果是深层传递数据,可能不能一下知道哪里提供数据、都提供了什么数据,会导致代码复杂一点。
// createContext
const TopicListContext = React.createContext({} as IContextProps)
// 提供数据
<TopicListContext.Provider value={{ searchResult, setSearchResult }}>
...
</TopicListContext.Provider >
// 使用数据
const { setSearchResult } = useContext(TopicListContext)
通过 props 的 isSearch 参数来判断是否显示搜索框。
通过获取 url 里的 id 来判断是否显示二级目录。
umi 具有约定式路由,它不需要手写配置,文件系统即路由,通过目录和文件及其命名分析出路由配置。
我用的是配置式路由,主要是自己实习外没使用过 umi 的路由,所以想试一试。
解析后的内容可以通过 dangerouslySetInnerHTML 对 div 进行 InnerHTML 的替换。
import { marked } from 'marked'
marked.setOptions({
renderer: new marked.Renderer(),
highlight: function (code) {
return hljs.highlightAuto(code).value;
},
gfm: true, // 允许 Git Hub标准的markdown.
pedantic: false, // 不纠正原始模型任何的不良行为和错误(默认为false)
sanitize: false, // 对输出进行过滤(清理),将忽略任何已经输入的html代码(标签)
// tables: true, // 允许支持表格语法(该选项要求 gfm 为true)
breaks: true, // 允许回车换行(该选项要求 gfm 为true)
smartLists: true, // 使用比原生markdown更时髦的列表
smartypants: false, // 使用更为时髦的标点
})
<div dangerouslySetInnerHTML={{ __html: marked.parse(res.topic.article)}}>
</div>
import moment from 'moment'
import 'moment/locale/zh-cn'
// 使用中文时间
moment.locale('zh-cn')
{moment(topic?.created_time).format('LL')}
与博客系统的后台大致相同,使用技术可见该 博客
对 props 参数进行类型限制。
type myProps = {
isSearch: boolean;
}
export default function Header(props: myProps) {}
设置 innerHTML 对 textarea 没有意义,因为 textarea 的内容都保存在它的 value 属性中,并且
textarea 不能呈现 HTML。 如果想在一个容器里放 HTML,可以使用 div、p 等。
initalvallues 只在第一次拿到初始值有效,不能初值是空之后再赋值,此时不会生效。不会根据其内容发生变化而进行对应更新。
此时我们可以通过 setFieldsValue 进行设置,setFieldsValue 可以动态的设置初始值。
const [form] = Form.useForm()
form.setFieldsValue({
title: res.topic.title,
model: res.topic.model
})
<Form form={form}>
...
</Form>
组件被div或者其他容器包裹,可以通过 getFiledDecorator 解决。
参考博客
<Form.Item name='article' >
<div className={styles.markdownDiv}>
<Input.TextArea />
</div>
</Form.Item>