各个字段 的含义:
从前天开始觉醒了觉得自己花三百块报篮球杯这个钱不能白花,于是开始写题,结果写了两天就撑不住了,感觉自己不是吃这碗饭的,故放弃,写出生理性不适了脑阔疼+牙疼?。,。。
故回来写项目,穿插着来。。。在圈钱杯开始之前本人将尽量把算法模板多背几个。。。
页头
kerwin老师使用pageheader实现了页头,但是在antd5中这样的写法已经被废除了,所以需要尝试新写法,比如这样:
import React from 'react'
import { Breadcrumb, Typography, Button, Space } from 'antd';
const { Title } = Typography;
export default function NewsAdd() {
return (
<div style={{ marginBottom: 24 }}>
<Breadcrumb items={[
{ title: 'Home' },
{ title: 'List' },
{ title: 'App' },
]} />
<Space style={{ justifyContent: 'space-between', width: '100%' }}>
<Title level={2} style={{ margin: '16px 0' }}>Page Title</Title>
<Space>
<Button>Cancel</Button>
<Button type="primary">Submit</Button>
</Space>
</Space>
</div>
)
}
步骤条
组件库中有现成的,所以可以直接引入
import React, { useState } from 'react'
import { Breadcrumb, Typography, Button, Space,Steps, message,theme } from 'antd';
import style from './News.module.css'
const { Title } = Typography;
const description = 'This is a description';
const steps = [
{
title: '基本信息',
content: '新闻标题 新闻分类',
},
{
title: '新闻内容',
content: '新闻主体内容',
},
{
title: '新闻提交',
content: '保存草稿 审核提交',
},
];
export default function NewsAdd() {
const { token } = theme.useToken();
const [current, setCurrent] = useState(0);
const next = () => {
setCurrent(current + 1);
};
const prev = () => {
setCurrent(current - 1);
};
const items = steps.map((item) => ({
key: item.title,
title: item.title,
}));
const contentStyle = {
lineHeight: '260px',
textAlign: 'center',
color: token.colorTextTertiary,
backgroundColor: token.colorFillAlter,
borderRadius: token.borderRadiusLG,
border: `1px dashed ${token.colorBorder}`,
marginTop: 16,
};
return (
<div style={{ marginBottom: 24 }}>
<Breadcrumb items={[
{ title: 'Home' },
{ title: 'List' },
{ title: 'App' },
]} />
<Space style={{ justifyContent: 'space-between', width: '100%' }}>
<Title level={2} style={{ margin: '16px 0' }}>撰写新闻</Title>
<Space>
<Button>Cancel</Button>
<Button type="primary">Submit</Button>
</Space>
</Space>
<Steps current={current} items={items} />
<div className={current===0?'':style.active}>
11111
</div>
<div style={contentStyle}>{steps[current].content}</div>
<div
style={{
marginTop: 24,
}}
>
{current < steps.length - 1 && (
<Button type="primary" onClick={() => next()}>
Next
</Button>
)}
{current === steps.length - 1 && (
<>
<Button type="primary" style={{
margin: '0 8px',
}} onClick={() => message.success('Processing complete!')}>
保存草稿
</Button>
<Button type="primary">
提交审核
</Button>
</>
)}
{current > 0 && (
<Button
style={{
margin: '0 8px',
}}
onClick={() => prev()}
>
Previous
</Button>
)}
</div>
</div>
)
}
大部分代码都是antd里面的,想要实现动态的就不能只是创建,而是想办法让它显示和隐藏
表单
引入一下form表单
import React, { useState, useEffect,useRef } from 'react'
import {
Breadcrumb,
Typography,
Button,
Space,
Steps,
message,
theme,
Checkbox,
Form,
Input,
Select,
} from 'antd'
import style from './News.module.css'
import axios from 'axios'
import { set } from 'nprogress'
const { Title } = Typography
const description = 'This is a description'
const { Option } = Select
const onFinish = (values) => {
console.log('Success:', values)
}
const onFinishFailed = (errorInfo) => {
console.log('Failed:', errorInfo)
}
export default function NewsAdd() {
const { token } = theme.useToken()
const [current, setCurrent] = useState(0)
const [categoryList, setCategoryList] = useState([])
const NewsForm = useRef(null)
const steps = [
{
title: '基本信息',
content: (
<Form
name="basic"
ref = {NewsForm}
labelCol={{
span: 4,
}}
wrapperCol={{
span: 20,
}}
style={{
maxWidth: 600,
margin: '25px',
}}
initialValues={{
remember: true,
}}
onFinish={onFinish}
onFinishFailed={onFinishFailed}
autoComplete="off"
>
<Form.Item
label="新闻标题"
name="title"
rules={[
{
required: true,
message: 'Please input your username!',
},
]}
>
<Input></Input>
</Form.Item>
<Form.Item
label="新闻分类"
name="categoryId"
rules={[
{
required: true,
message: 'Please input your username!',
},
]}
>
<Select>
{categoryList.map((item) => (
<Select.Option value={item.id} key={item.id}>
{item.title}
</Select.Option>
))}
</Select>
</Form.Item>
</Form>
),
},
{
title: '新闻内容',
content: '新闻主体内容',
},
{
title: '新闻提交',
content: '保存草稿 审核提交',
},
]
const next = () => {
if(current === 0){
NewsForm.current.validateFields().then((res) => {
console.log(res)
setCurrent(current + 1)
}).catch((err) => {
console.log(err)
})
}
else{
setCurrent(current + 1)
}
}
const prev = () => {
setCurrent(current - 1)
}
const items = steps.map((item) => ({
key: item.title,
title: item.title,
}))
useEffect(() => {
axios.get('/categories').then((res) => {
setCategoryList(res.data)
})
}, [])
return (
<div style={{ marginBottom: 24 }}>
<Breadcrumb
items={[{ title: 'Home' }, { title: 'List' }, { title: 'App' }]}
/>
<Space style={{ justifyContent: 'space-between', width: '100%' }}>
<Title level={2} style={{ margin: '16px 0' }}>
撰写新闻
</Title>
<Space>
<Button>Cancel</Button>
<Button type="primary">Submit</Button>
</Space>
</Space>
<Steps current={current} items={items} />
<div>{steps[current].content}</div>
<div
style={{
marginTop: 24,
}}
>
{current < steps.length - 1 && (
<Button type="primary" onClick={() => next()}>
Next
</Button>
)}
{current === steps.length - 1 && (
<>
<Button
type="primary"
style={{
margin: '0 8px',
}}
onClick={() => message.success('Processing complete!')}
>
保存草稿
</Button>
<Button type="primary">提交审核</Button>
</>
)}
{current > 0 && (
<Button
style={{
margin: '0 8px',
}}
onClick={() => prev()}
>
Previous
</Button>
)}
</div>
</div>
)
}
富文本编辑器
富文本编辑器也是自己导入的,用前人写好的项目
$ npm install --save react-draft-wysiwyg draft-js
安装它之后,需要改一下配置:vite.config.js
加个global
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react-swc';
export default defineConfig({
plugins: [react()],
define: {
global: 'window' // 解决 global 和 setImmediate 问题
},
server: {
proxy: {
'/schedule': {
target: 'https://api.tvmaze.com', // 代理地址
changeOrigin: true, // 允许跨域
rewrite: (path) => path.replace(/^\/schedule/, ''), // 重写路径,去掉 /shows
},
},
},
});
NewsEditor.jsx:
import React, { useState } from 'react'
import { Editor } from 'react-draft-wysiwyg'
import 'react-draft-wysiwyg/dist/react-draft-wysiwyg.css'
import { EditorState } from 'draft-js'
export default function NewsEditor() {
// 定义 editorState 初始状态
const [editorState, setEditorState] = useState(EditorState.createEmpty())
// 处理 editorState 更新
const onEditorStateChange = (newState) => {
setEditorState(newState)
}
return (
<div>
<Editor
editorState={editorState}
toolbarClassName="toolbarClassName"
wrapperClassName="wrapperClassName"
editorClassName="editorClassName"
onEditorStateChange={onEditorStateChange}
/>
</div>
)
}
就这样水灵灵的成功
但是现在的这个不能保存数据,应该是转成html或者markdown的,最后子传父调用提交到父组件
看一下项目的文档:
React Draft Wysiwyghttps://jpuri.github.io/react-draft-wysiwyg/#/docs?_k=jjqinp
这里有演示不同的格式之间的转换
提交
现在写提交的部分
康康这个蚂蚁编程:
最好加一个提示框
现在综合一下写路由跳转和提示框:
import React, { useState, useEffect,useRef } from 'react'
import {
Breadcrumb,
Typography,
Button,
Space,
Steps,
message,
theme,
Checkbox,
Form,
Input,
Select,
notification,
} from 'antd'
import style from './News.module.css'
import axios from 'axios'
import { set } from 'nprogress'
import NewsEditor from '../../../../src/components/news-manage/NewsEditor.jsx'
import { useNavigate } from 'react-router-dom'
const { Title } = Typography
const description = 'This is a description'
const { Option } = Select
const onFinish = (values) => {
console.log('Success:', values)
}
const onFinishFailed = (errorInfo) => {
console.log('Failed:', errorInfo)
}
export default function NewsAdd(props) {
const { token } = theme.useToken()
const [current, setCurrent] = useState(0)
const [categoryList, setCategoryList] = useState([])
const [formInfo, setFormInfo] = useState({})
const [content, setContent] = useState("")
const User = JSON.parse(localStorage.getItem('token'))
const NewsForm = useRef(null)
const steps = [
{
title: '基本信息',
content: (
<Form
name="basic"
ref = {NewsForm}
labelCol={{
span: 4,
}}
wrapperCol={{
span: 20,
}}
style={{
maxWidth: 600,
margin: '25px',
}}
initialValues={{
remember: true,
}}
onFinish={onFinish}
onFinishFailed={onFinishFailed}
autoComplete="off"
>
<Form.Item
label="新闻标题"
name="title"
rules={[
{
required: true,
message: 'Please input your username!',
},
]}
>
<Input></Input>
</Form.Item>
<Form.Item
label="新闻分类"
name="categoryId"
rules={[
{
required: true,
message: 'Please input your username!',
},
]}
>
<Select>
{categoryList.map((item) => (
<Select.Option value={item.id} key={item.id}>
{item.title}
</Select.Option>
))}
</Select>
</Form.Item>
</Form>
),
},
{
title: '新闻内容',
// 留一个回调函数用于子传父
content: <NewsEditor getContent={(value)=>{
// console.log(value)
setContent(value)
}}>
</NewsEditor>,
},
{
title: '新闻提交',
content: '保存草稿 审核提交',
},
]
const next = () => {
if(current === 0){
NewsForm.current.validateFields().then((res) => {
setFormInfo(res)
setCurrent(current + 1)
}).catch((err) => {
console.log(err)
})
}
else{
if(content === "" || content.trim()==="<p></p>"){
//如果收集的是空的就不放行
message.error('新闻内容不能为空')
return
}
else{
setCurrent(current + 1)
}
}
}
const prev = () => {
setCurrent(current - 1)
}
const items = steps.map((item) => ({
key: item.title,
title: item.title,
}))
useEffect(() => {
axios.get('/categories').then((res) => {
setCategoryList(res.data)
})
}, [])
const navigate = useNavigate()
const handleSave = (auditState) => {
axios.post('/news', {
...formInfo,
"content":content,
"region": User.region?User.region:"全球",
"author": User.username,
"roleId": User.roleId,
"auditState": auditState,
"publishState": 0,
"createTime": Date.now(),
"star":0,
"view":0,
"publishState": 0,
}).then((res) => {
//这个写法已经舍弃了
// props.history.push(auditState===0?'/news-manage/draft':'/audit-manage/list')
navigate(auditState === 0 ? '/news-manage/draft' : '/audit-manage/list')
notification.info({
message:`通知`,
description:
`您可以到${auditState===0?'草稿箱':'审核列表'}查看您的新闻`,
placement: 'bottomRight',
})
})
}
return (
<div style={{ marginBottom: 24 }}>
<Breadcrumb
items={[{ title: 'Home' }, { title: 'List' }, { title: 'App' }]}
/>
<Space style={{ justifyContent: 'space-between', width: '100%' }}>
<Title level={2} style={{ margin: '16px 0' }}>
撰写新闻
</Title>
<Space>
<Button>Cancel</Button>
<Button type="primary">Submit</Button>
</Space>
</Space>
<Steps current={current} items={items} />
<div>{steps[current].content}</div>
<div
style={{
marginTop: 24,
}}
>
{current < steps.length - 1 && (
<Button type="primary" onClick={() => next()}>
Next
</Button>
)}
{current === steps.length - 1 && (
<>
<Button
type="primary"
style={{
margin: '0 8px',
}}
onClick={() => handleSave(0)}
>
保存草稿
</Button>
<Button type="primary" onClick={() => handleSave(1)}>提交审核</Button>
</>
)}
{current > 0 && (
<Button
style={{
margin: '0 8px',
}}
onClick={() => prev()}
>
Previous
</Button>
)}
</div>
</div>
)
}
前两天是算法day!项目没怎么推进。。。因为去打篮球杯和校赛了,校赛队名叫帮我,带,,饭,,和可 乐,靠强劲的小哥带飞成功金奖,可以去打后续的省赛了捏,省赛的队名商讨之后决定叫“搞点哦润吉吃吃”