【React】极客园--04.发布文章模块

news2024/11/26 10:49:29

实现基础文章发布

创建基础结构

在这里插入图片描述

import {
  Card,
  Breadcrumb,
  Form,
  Button,
  Radio,
  Input,
  Upload,
  Space,
  Select
} from 'antd'
import { PlusOutlined } from '@ant-design/icons'
import { Link } from 'react-router-dom'
import './index.scss'

const { Option } = Select

const Publish = () => {
  return (
    <div className="publish">
      <Card
        title={
          <Breadcrumb items={[
            { title: <Link to={'/'}>首页</Link> },
            { title: '发布文章' },
          ]}
          />
        }
      >
        <Form
          labelCol={{ span: 4 }}
          wrapperCol={{ span: 16 }}
          initialValues={{ type: 1 }}
        >
          <Form.Item
            label="标题"
            name="title"
            rules={[{ required: true, message: '请输入文章标题' }]}
          >
            <Input placeholder="请输入文章标题" style={{ width: 400 }} />
          </Form.Item>
          <Form.Item
            label="频道"
            name="channel_id"
            rules={[{ required: true, message: '请选择文章频道' }]}
          >
            <Select placeholder="请选择文章频道" style={{ width: 400 }}>
              <Option value={0}>推荐</Option>
            </Select>
          </Form.Item>
          <Form.Item
            label="内容"
            name="content"
            rules={[{ required: true, message: '请输入文章内容' }]}
          ></Form.Item>

          <Form.Item wrapperCol={{ offset: 4 }}>
            <Space>
              <Button size="large" type="primary" htmlType="submit">
                发布文章
              </Button>
            </Space>
          </Form.Item>
        </Form>
      </Card>
    </div>
  )
}

export default Publish

pages/Publish/index.scss

.publish {
  position: relative;
}

.ant-upload-list {
  .ant-upload-list-picture-card-container,
  .ant-upload-select {
    width: 146px;
    height: 146px;
  }
}

准备富文本编辑器

实现步骤

  1. 安装富文本编辑器
  2. 导入富文本编辑器组件以及样式文件
  3. 渲染富文本编辑器组件
  4. 调整富文本编辑器的样式

代码落地
1-安装 react-quill

npm i react-quill@2.0.0-beta.2

2-导入资源渲染组件

import ReactQuill from 'react-quill'
import 'react-quill/dist/quill.snow.css'

const Publish = () => {
  return (
    // ...
    <Form
      labelCol={{ span: 4 }}
      wrapperCol={{ span: 16 }}
    >
      <Form.Item
        label="内容"
        name="content"
        rules={[{ required: true, message: '请输入文章内容' }]}
      >
        <ReactQuill
          className="publish-quill"
          theme="snow"
          placeholder="请输入文章内容"
        />
      </Form.Item>
    </Form>
  )
}
.publish-quill {
  .ql-editor {
    min-height: 300px;
  }
}

频道数据获取

在这里插入图片描述

实现步骤

  1. 使用useState初始化数据和修改数据的方法
  2. 在useEffect中调用接口并保存数据
  3. 使用数据渲染对应模版

代码实现

import { http } from '@/utils'

// 频道列表
const [channels, setChannels] = useState([])

// 调用接口
useEffect(() => {
    async function fetchChannels() {
      const res = await http.get('/channels')
      setChannels(res.data.channels)
    }
    fetchChannels()
}, [])

// 模板渲染
return (
 <Form.Item
    label="频道"
    name="channel_id"
    rules={[{ required: true, message: '请选择文章频道' }]}
  >
    <Select placeholder="请选择文章频道" style={{ width: 200 }}>
      {channels.map(item => (
        <Option key={item.id} value={item.id}>
          {item.name}
        </Option>
      ))}
    </Select>
  </Form.Item>
)

发布文章

// 发布文章
const onFinish = async (formValue) => {
  const { channel_id, content, title } = formValue
  const params = {
    channel_id,
    content,
    title,
    type: 1,
    cover: {
      type: 1,
      images: []
    }
  }
  await http.post('/mp/articles?draft=false', params)
  message.success('发布文章成功')
}

在这里插入图片描述

上传封面实现

准备上传结构

在这里插入图片描述

<Form.Item label="封面">
  <Form.Item name="type">
    <Radio.Group>
      <Radio value={1}>单图</Radio>
      <Radio value={3}>三图</Radio>
      <Radio value={0}>无图</Radio>
    </Radio.Group>
  </Form.Item>
  <Upload
    listType="picture-card"
    showUploadList
  >
    <div style={{ marginTop: 8 }}>
      <PlusOutlined />
    </div>
  </Upload>
</Form.Item>

实现基础上传

实现步骤

  1. 为 Upload 组件添加 action 属性,配置封面图片上传接口地址
  2. 为 Upload组件添加 name属性, 接口要求的字段名
  3. 为 Upload 添加 onChange 属性,在事件中拿到当前图片数据,并存储到React状态中

代码实现

import { useState } from 'react'

const Publish = () => {
  // 上传图片
  const [imageList, setImageList] = useState([])
  const onUploadChange = (info) => {
      setImageList(info.fileList)
  }
  return (
   	<Form.Item label="封面">
      <Form.Item name="type">
        <Radio.Group>
          <Radio value={1}>单图</Radio>
          <Radio value={3}>三图</Radio>
          <Radio value={0}>无图</Radio>
        </Radio.Group>
      </Form.Item>
      <Upload
        name="image"
        listType="picture-card"
        showUploadList
        action={'http://geek.itheima.net/v1_0/upload'}
        onChange={onUploadChange}
      >
        <div style={{ marginTop: 8 }}>
          <PlusOutlined />
        </div>
      </Upload>
    </Form.Item>
  )
}

切换图片Type

实现步骤

  1. 点击单选框时拿到当前的类型value
  2. 根据value控制上传组件的显示(大于零时才显示)
const Publish = ()=>{
  // 控制图片Type
  const [imageType, setImageType] = useState(0)

  const onTypeChange = (e) => {
    console.log(e)
    setImageType(e.target.value)
  }
  
  return (
    <FormItem>
      <Radio.Group onChange={onTypeChange}>
        <Radio value={1}>单图</Radio>
        <Radio value={3}>三图</Radio>
        <Radio value={0}>无图</Radio>
      </Radio.Group>
      {imageType > 0 &&
      <Upload
        name="image"
        listType="picture-card"
        showUploadList
        action={'http://geek.itheima.net/v1_0/upload'}
        onChange={onUploadChange}
        >
        <div style={{ marginTop: 8 }}>
          <PlusOutlined />
        </div>
      </Upload>}
    </FormItem>
  )
}

在这里插入图片描述

控制最大上传图片数量

实现步骤

  1. 通过 maxCount 属性限制图片的上传图片数量
{imageType > 0 &&
<Upload
  name="image"
  listType="picture-card"
  className="avatar-uploader"
  showUploadList
  action={'http://geek.itheima.net/v1_0/upload'}
  onChange={onUploadChange}
  maxCount={imageType}
  multiple={imageType > 1}
>
  <div style={{ marginTop: 8 }}>
    <PlusOutlined />
  </div>
</Upload>}

暂存图片列表实现

业务描述
如果当前为三图模式,已经完成了上传,选择单图只显示一张,再切换到三图继续显示三张,该如何实现?

实现思路
在上传完毕之后通过ref存储所有图片,需要几张就显示几张,其实也就是把ref当仓库,用多少拿多少

实现步骤

  1. 通过useRef创建一个暂存仓库,在上传完毕图片的时候把图片列表存入
  2. 如果是单图模式,就从仓库里取第一张图,以数组的形式存入fileList
  3. 如果是三图模式,就把仓库里所有的图片,以数组的形式存入fileList

代码实现

const Publish = () => {
  // 上传图片
  const cacheImageList = useRef([])
  const [imageList, setImageList] = useState([])
  const onUploadChange = (info) => {
      setImageList(info.fileList)
      cacheImageList.current = info.fileList
  }

  // 控制图片Type
  const [imageType, setImageType] = useState(0)

  const onRadioChange = (e) => {
    const type = e.target.value
    setImageType(type)
    if (type === 1) {
      // 单图,截取第一张展示
      const imgList = cacheImageList.current[0] ? [cacheImageList.current[0]] : []
      setImageList(imgList)
    } else if (type === 3) {
      // 三图,取所有图片展示
      setImageList(cacheImageList.current)
    }
  }

  return (
    {imageType > 0 &&
    <Upload
      name="image"
      listType="picture-card"
      className="avatar-uploader"
      showUploadList
      action={'http://geek.itheima.net/v1_0/upload'}
      onChange={onUploadChange}
      maxCount={imageType}
      multiple={imageType > 1}
      fileList={imageList}
      >
      <div style={{ marginTop: 8 }}>
        <PlusOutlined />
      </div>
    </Upload>}
)
}

注意:需要给Upload组件添加fileList属性,达成受控的目的

发布带封面的文章

校验图片类型和数量是否吻合

// 发布文章
  const onFinish = async (formValue) => {
    if (imageType !== imageList.length) return message.warning('图片类型和数量不一致')
    const { channel_id, content, title } = formValue
    const params = {
      channel_id,
      content,
      title,
      type: imageType,
      cover: {
        type: imageType,
        images: imageList.map(item => item.response.data.url)
      }
    }
    await http.post('/mp/articles?draft=false', params)
    message.success('发布文章成功')
  }

处理图片列表格式为接口格式

// 发布文章
const onFinish = async (formValue) => {
  const { channel_id, content, title } = formValue
  const params = {
    channel_id,
    content,
    title,
    type: imageType,
    cover: {
      type: imageType,
      images: imageList.map(item => item.response.data.url)
    }
  }
  await http.post('/mp/articles?draft=false', params)
  message.success('发布文章成功')
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1849115.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LeetCode 1-两数之和

LeetCode第1题 两数之和 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是&#xff0c;数组中同一个元素在答案里不能重复出现…

重磅!2024年最新影响因子(生态学/林学/土壤学/遥感/微生物/环境科学/植物科学) 收藏版!

2024年最新影响因子正式揭晓&#xff01;2024年6月20日&#xff0c;Clarivate Analytics&#xff08;科睿唯安&#xff09;发布了各大SCI期刊的2023年影响因子。从最新结果看&#xff0c;今年的影响因子继续“普跌”&#xff0c;其中顶刊Nature和Science均有下降&#xff0c;分…

萨科微slkor宋仕强论道华强北假货之六

萨科微slkor宋仕强论道华强北假货之六&#xff0c;华强北的假货这么多&#xff0c;搞得客户害怕、同行焦虑&#xff0c;话说“在华强北没有被坑过的&#xff0c;就不是华强北人”。我们金航标Kinghelm&#xff08;www.kinghelm.com.cn&#xff09;公司以前有一个贸易部&#xf…

R语言数据分析案例33-基于logistic回归下的信用卡违约情况分析

一、选题背景 随着互联网产业的蓬勃发展&#xff0c;传统金融行业开始向着金融互联网化和互联网金融快速转型。网络信贷、信用卡等凭借门槛低、快速便捷、高收益等特点&#xff0c;借助互联网平台存在的优势&#xff0c;迅速成长。然而高收益的背后也存在着高风险&#xff0c;…

Docker配置阿里云加速器(2续)

默认情况下镜像是从docker hub下载&#xff0c;由于docker hub服务器在国外&#xff0c;由于网络原因镜像下载速度较慢&#xff0c;一般会配置镜像加速进行下载 国内镜像加速器有阿里云、网易云、中科大等&#xff0c;本章配置阿里云镜像加速器&#xff0c;速度较快 镜像加速源…

JavaWeb——SQL简介

1. SQL的介绍 SQL是一门结构化查询语言&#xff0c;就是一门用来操作关系型数据库的数据库语言&#xff1b; 使用SQL语句&#xff0c;可以操作所有的关系数据库&#xff1b; 但是&#xff0c;不同的关系型数据库的SQL操作略有不同&#xff0c;称为“方言”&#xff1b; 2. S…

408数据结构-图的遍历 自学知识点整理

前置知识&#xff1a;图的存储与基本操作 图的遍历是指从图的某一顶点出发&#xff0c;按照某种搜索方法沿着图中的边对图中的所有顶点访问一次&#xff0c;且仅访问一次。因为树是一种特殊的图&#xff0c;所以树的遍历实际上也可以视为一种特殊的图的遍历。图的遍历算法是求解…

excel数据透视

Excel中&#xff0c;数据透视图&#xff08;PivotChart&#xff09;和数据透视表&#xff08;PivotTable&#xff09;是两个紧密相关的工具&#xff0c;用于分析数据。数据透视表是数据透视图的数据源&#xff0c;也就是说&#xff0c;数据透视图是基于数据透视表中的数据创建的…

matplotlib 创建多个子图

有些时候我们需要用for循环来创建多个子图&#xff0c;来对比特征。现在已画出8组随机数来作为示例。 from matplotlib import pyplot as plt import numpy as np #设置画布大小 figplt.figure(figsize(20,8)) #解决中文乱码问题 plt.rcParams[font.sans-serif] [SimHei] fo…

BlockingQueue详解(含动画演示)

目录 BlockingQueue详解0、BlockingQueue简介BlockingQueue接口中方法注释BlockingQueue的实现&#xff0c;总结计划 1、ArrayBlockingQueue简介2、ArrayBlockingQueue的继承体系3、ArrayBlockingQueue的构造方法①、 ArrayBlockingQueue(int capacity)②、ArrayBlockingQueue(…

HumanPlus——斯坦福ALOHA团队开源的人形机器人:融合影子学习技术、RL、模仿学习

前言 今天只是一个平常的日子&#xff0c;不过看到了两篇文章 一篇是《半年冒出近百家新公司&#xff0c;「具身智能」也有春天》 我看完之后转发到朋友圈&#xff0c;并评论道&#xff1a;让机器人翻一万个后空翻&#xff0c;不如让机器人打好一个螺钉&#xff0c;毕竟在目前…

Python酷库之旅-第三方库openpyxl(03)

目录 一、 openpyxl库的由来 1、背景 2、起源 3、发展 4、特点 4-1、支持.xlsx格式 4-2、读写Excel文件 4-3、操作单元格 4-4、创建和修改工作表 4-5、样式设置 4-6、图表和公式 4-7、支持数字和日期格式 二、openpyxl库的优缺点 1、优点 1-1、支持现代Excel格式…

html--404页面

<!DOCTYPE html> <html> <head> <meta http-equiv"Content-Type" content"text/html; charsetUTF-8"> <meta http-equiv"X-UA-Compatible" content"IEedge,chrome1"> <title>404 错误页面不存在&…

01--MySQL数据库概述

目录 第1章 MySQL数据库概述 1.1 基本概念 1.2 MySQL数据库管理系统 1.3 表的关系 第2章 MySQL卸载、安装、登录 第3章 客户端使用演示 3.1 命令行客户端 3.1.1 数据库 3.1.2 数据表 3.1.3 导入数据 3.1.4 导出数据 3.2 可视化客户端 第4章 SQL语句 4.1 SQL的分类…

C#实现高斯模糊(图像处理)

在C#中实现高斯模糊&#xff0c;可以使用System.Drawing库。高斯模糊是一种基于高斯函数的滤波器&#xff0c;它可以有效地平滑图像。以下是详细的步骤&#xff0c;包括生成高斯核并应用到图像上的代码示例。 1. 生成高斯核 首先&#xff0c;我们需要编写一个方法来生成高斯核…

碳+绿证如何能源匹配?考虑碳交易和绿证交易制度的电力批发市场能源优化程序代码!

前言 近年来&#xff0c;面对日益受到全社会关注的气候变化问题&#xff0c;国外尤其是欧美等发达国家和地区针对电力行业制定了一系列碳减排组合机制。其中&#xff0c;碳排放权交易&#xff08;以下简称“碳交易”&#xff09;和绿色电力证书交易&#xff08;以下简称“绿证…

JAVA医院绩效考核系统源码 功能特点:大型医院绩效考核系统源码

JAVA医院绩效考核系统源码 功能特点&#xff1a;大型医院绩效考核系统源码 医院绩效管理系统主要用于对科室和岗位的工作量、工作质量、服务质量进行全面考核&#xff0c;并对科室绩效工资和岗位绩效工资进行核算的系统。医院绩效管理系统开发主要用到的管理工具有RBRVS、DRGS…

【SCAU数据挖掘】数据挖掘期末总复习题库简答题及解析——下

1.从某超市顾客中随机抽取5名&#xff0c;他们的购物篮数据的二元0/1表示如下&#xff1a; 顾客号 面包 牛奶 尿布 啤酒 鸡蛋 可乐 1 1 1 0 0 0 0 2 1 0 1 1 1 0 3 0 1 1 1 0 1 4 1 1 1 1 0 0 5 1 1 1 0 0 1 某学生依据这些数据做…

【2024.6.22】今日科技时事:科技前沿大事件

人不走空 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌赋&#xff1a;斯是陋室&#xff0c;惟吾德馨 目录 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌…

《STM32 HAL库》CAN通信系列函数详尽解析——HAL_CAN_Init()

食用指南&#xff1a;本文主要内容为梳理CAN初始化函数主要运行逻辑及重点功能实现代码的详尽解析。函数源码在文末&#xff0c;建议在阅读源码之后观看。 CAN相关寄存器图&#xff1a; 主要逻辑分析&#xff1a; 下面分点梳理函数的主要逻辑&#xff08;注意逻辑序号&#xf…