/src/App/Admin/Header

布局 import {Row, Col} from "antd"

<div className="header_box">

<Row className="header_top">

<span>欢迎</span>

<a>退出</a>

</Row>

<Row className="header_bottom">

<Col span={4}></Col>

<Col span={20}>

<span className="weather_time">时间</span>

<span className="weather_img">图片</span>

<span className="weather_detail">晴天</span>

</Col>

</Row>

</div>

sysTime = Date.now() / DidMount 中计时器 时间动态显示

5

import jsonp from jsonp;

MyTools.weather(city){

return new Promise((resolve, reject)=>{

0

})

}

  • 根据 path 获取到 breadcrumb_title 和 父菜单
  • 分类列表 - 增加分类 - 修改分类 ---- 熟练对 API 的运用能力

antd 界面 ---- Button、Icon、CardTable(包含分页)

  • 每个分类

parentId    一级分类的 parentId 为 0 

_id    自动生成

name    新分类的名字

__v    自动生成

  • 添加分类返回的响应    

  • 更新状态 state 是异步的,this.setState({...}, ()=>{...})

注意其第二参数是一个回调函数,在状态更新完成以后立即执行

  • 对话框不保存上一次的交互记录,可以给 Modal 设置一下属性

  • 关于 Table 的 render 传值

如果不指定 dataIndex,则第一个参数为整个对象

如果指定了 dataIndex,则第二个参数为整个对象,第一个参数为指定的数据

5

  • 后台分页,每次点击分页都发请求获取数据,即使已经获取过了

优化: 保存每次请求的页码即数据

关键: 数据结构;一般分页/搜索分页

  • this.props.history.push("新页面", 要传递的数据) ---- this.props.history.goBack()

可以在 "新页面" 获取到传递的数据

传递的数据 = this.props.location.state || {}    // 优化: 保证 数据 始终是一个存在的对象

git 上一个基于 react 的富文本编辑器

RichTextEditor.js

  • import React, { Component } from 'react';
    import { EditorState, convertToRaw } from 'draft-js';
    import { Editor } from 'react-draft-wysiwyg';
    import 'react-draft-wysiwyg/dist/react-draft-wysiwyg.css';
    import draftToHtml from 'draftjs-to-html';
    import htmlToDraft from 'html-to-draftjs'; // import {Card, Button, Icon, Table, message, Modal, Form, Input, Select} from "antd"; import "./css/RichTextEditor.css"; /* 富文本编辑器组件 */
    export default class RichTextEditor extends Component {
    constructor(props){
    super(props);
    this.state = {
    editorState: EditorState.createEmpty()
    }
    } onEditorStateChange = (editorState) => {
    this.setState({
    editorState,
    });
    }; render() {
    const { editorState } = this.state;
    return (
    <div>
    <Editor
    editorState={editorState}
    wrapperClassName="demo-wrapper" /* 包裹区类名 */
    editorClassName="demo-editor" /* 编辑区类名 */
    onEditorStateChange={this.onEditorStateChange}
    />
    {/*<textarea // draft2html */}
    {/*disabled*/}
    {/*value={draftToHtml(convertToRaw(editorState.getCurrentContent()))}*/}
    {/*/>*/}
    </div>
    );
    }
    }
  • css/RichTextEditor.css
  • .product_edit  .rdw-dropdown-selectedtext{
    min-width: 54px; font-size: 16px;
    font-weight:;
    letter-spacing:;
    } .rdw-editor-toolbar {
    margin-bottom:;
    } .demo-editor {
    height: 120px;
    padding: 4px; font-size: 14px;
    line-height: 1.2em;
    letter-spacing:;
    background-color: #74878f;
    }

使用:(组件对象,就是标签对象,意味着可以使用 ref 去关联获取组件中的属性和方法。

  • 获取富文本编辑器最终生成的,html 标签内容
  • getRichTextEditor = ()=>{
    const {editorState} = this.state;
    return draftToHtml(convertToRaw(editorState.getCurrentContent());
    };
  • 父组件给子组件设置 ref ,从而可以从子组件调用这个方法
  • 编辑商品时,传递已有的 detail 给富文本编辑器显示
  • <div className="rich_text_editor">
    <div className="product_detail_edit">商品详情:</div>
    <div><RichTextEditor ref="RichTextEditor" detail={product.detail}/></div>
    </div>
  • 默认创建的空文本内容
  • constructor(props){
    super(props);
    this.state = {
    editorState: EditorState.createEmpty() // 默认创建一个空的文本内容
    }
    }
  • 使用第三方库,进行 html 到 draft 的转换
  • componentWillMount(){
    const detail = this.props.detail;
    if(detail){
    const blocksFromHtml = htmlToDraft(detail); // 将传过来的 detail 转换
    const { contentBlocks, entityMap } = blocksFromHtml;
    const contentState = ContentState.createFromBlockArray(contentBlocks, entityMap);
    const editorState = EditorState.createWithContent(contentState);
    this.setState({
    editorState // 更新界面相关内容
    })
    }
    }
  • 最终的 RichTextEditor.js 组件代码为
  • import React, { Component } from 'react';
    import { EditorState, convertToRaw, ContentState} from 'draft-js';
    import { Editor } from 'react-draft-wysiwyg';
    import 'react-draft-wysiwyg/dist/react-draft-wysiwyg.css';
    import draftToHtml from 'draftjs-to-html'; import htmlToDraft from 'html-to-draftjs'; // 将已有的 html 标签内容,生成一个 draft 内容 import "./css/RichTextEditor.css"; /* 富文本编辑器组件 */
    export default class RichTextEditor extends Component {
    constructor(props){
    super(props);
    this.state = {
    editorState: EditorState.createEmpty() // 默认创建一个空的文本内容
    }
    } onEditorStateChange = (editorState) => {
    this.setState({
    editorState,
    });
    }; getRichTextEditor = ()=>{ // 让父组件调
    const {editorState} = this.state;
    return draftToHtml(convertToRaw(editorState.getCurrentContent()))
    }; componentWillMount(){
    const detail = this.props.detail;
    if(detail){
    const blocksFromHtml = htmlToDraft(detail); // 将传过来的 detail 转换
    const { contentBlocks, entityMap } = blocksFromHtml;
    const contentState = ContentState.createFromBlockArray(contentBlocks, entityMap);
    const editorState = EditorState.createWithContent(contentState);
    this.setState({
    editorState // 更新界面相关内容
    })
    }
    } render() {
    const { editorState } = this.state;
    return (
    <div>
    <Editor
    editorState={editorState} /* 初始显示文本的内容 */
    wrapperClassName="demo-wrapper" /* 包裹区类名 */
    editorClassName="demo-editor" /* 编辑区类名 */
    onEditorStateChange={this.onEditorStateChange} /* 监听,实时获取最新的输入内容 */
    />
    {/*<textarea // draft2html */}
    {/*disabled*/}
    {/*value={draftToHtml(convertToRaw(editorState.getCurrentContent()))}*/}
    {/*/>*/}
    </div>
    );
    }
    }
  • 通过 ref 可以得到标签对象

因为标签对象就是组件对象,所以 ref 就可以得到组件对象

意味着,父组件调用子组件的方法,可以 this.refs.ref关联的名字.方法

  • 在 componentWillMount 可以直接 this.state.xxx = xxxNew

5

  • 图片上传 - 删除上传图片 name
  • 图片上传  ---- form-data ----  image - 选择文件

返回一个 data 包含了 name 和 服务器资源路径url

  • 删除上传的图片 ---- x-www-form-urlencoded ---- name - 图片文件名

antd 组件

管理图片的组件(上传/删除)

  • 父组件给子组件传 imgs 图片数组,生成对引用的 fileList,并更新其在 state 中的状态
  • componentWillMount(){
    const imgs = this.props.imgs;
    if(imgs && imgs.length>0){
    const fileList = imgs.map((img, index)=>({
    uid: -index,
    name: img,
    url: "http://localhost:5000/upload/"+img,
    status: "done",
    }));
    this.setState({
    fileList
    })
    }
    } // 此时,可以看到已有的图片了

  • 需要在 handleChange 上传图片完成 file.status: done 时,进行 response 取值,赋值

5

难点: 当用户 上传图片/删除图片 后,不进行保存,而是返回时,上传使得后台多了冗余数据,删除使得数据的丢失

解决:

1. 点击删除时,不是真的删除,而是保存删除的图片的名字 到数组 deleteNames 中

---- 当点击 提交保存 时,再将之前保存的 deleteNames 发送请求,发送 ajax 请求真正地删除

2. 点击上传时,真的上传了,同时保存下上传的图片的名字 到数组 fackNames 中

---- 当点击 返回 ←  时, 发送 ajax 请求 删除 之前保存的 fackNames

难点: 添加一条角色到后台,然后如何不发送获取列表的请求,来刷新页面

解决: 通过 name 添加到角色到, 后台返回一个角色的相关信息,可以将这个 role 角色对象,存入 roles 状态中

如此的问题在于,优化: 是 Component 始终在 setState 后 render

还是用 PureComponent + [...this.state.状态]去 浅拷贝 生成新状态来 激活 render

5

5

5

5

5

5

5

react_app 项目开发 (7)_难点集合的更多相关文章

  1. react_app 项目开发 (5)_前后端分离_后台管理系统_开始

    项目描述 技术选型 react API 接口 接口文档,url,请求方式,参数类型, 根据文档描述的方法,进行 postman 测试,看是否能够得到理想的结果 collections - 创建文件取项 ...

  2. react_app 项目开发 (3)_单页面设计_react-router4

    (web) 利用 react-router4 实现 单页面 开发 SPA 应用 ---- (Single Page Web Application) 整个应用只有 一个完整的页面 单击链接不会刷新页面 ...

  3. react_app 项目开发 (4)_ React UI 组件库 ant-design 的基本使用

    最流行的开源 React UI 组件库 material-ui 国外流行(安卓手机的界面效果)文档 ant-design 国内流行 (蚂蚁金服 设计,一套 PC.一套移动端的____下拉菜单.分页.. ...

  4. react_app 项目开发 (6)_后台服务器端-node

    后台服务器端 负责处理前台应用提交的请求,并向前台返回 json 数据 前台应用 负责 展现数据与用户交互 发 ajax 请求与后台应用交互 yarn add axios /src/api/ajax. ...

  5. react_app 项目开发 (8)_角色管理_用户管理----权限管理 ---- shouldComponentUpdate

    角色管理 性能优化(前端面试) 需求:只要执行 setState(), 就会调用 render  重新渲染.由于有时调用了 setState,但是并没有发生状态的改变,以致于不必要的刷新 解决: 重写 ...

  6. react_app 项目开发 (9)_数据可视化 ECharts

    数据可视化 ECharts yarn add echarts echarts-for-react

  7. react_app 项目开发

    react_app 项目开发 npm install -g create-react-app npm root -g        // 查看安装包位置 创建项目 create-react-app m ...

  8. react_app 项目开发_遇到的坑

    1. favicon.ico <link rel="shortcut icon" type="image/x-icon" href="./fav ...

  9. com.panie 项目开发随笔_数据字典(2017.2.24)

    (一) 做一个网站,第一步需要考虑的是从哪个地方开始下手.首先,每一个功能肯定有最基本的增删改查功能,而此功能一般都分为两个页面. 1) 列表显示页面.用列表来展示数据库中的数据,多用于分页显示.该页 ...

随机推荐

  1. velocity 新手用小常识--开源,简单易上手

    项目中经常用到的 .vm 后缀文件是什么? 基于 java 的 velocity 模版引擎的一种页面控制文件,是一些类似 html 语句和一种叫 VLT 的语句构成   velocity --美 [v ...

  2. Regularity criteria for NSE 6: $u_3,\p_3u_1,\p_3u_2$

    In [Zujin Zhang, Jinlu Li, Zheng-an Yao, A remark on the global regularity criterion for the 3D Navi ...

  3. JS 正则中的命名捕获分组

    假设你在一段陌生的代码中看到这样一个函数: function toLocalDate(date) { return date.replace(/(\d{2})-(\d{2})-(\d{4})/, &q ...

  4. APPLE-SA-2019-3-25-4 Safari 12.1

    APPLE-SA-2019-3-25-4 Safari 12.1 Safari 12.1 is now available and addresses the following: Safari Re ...

  5. Xvector in Kaldi nnet3

    Xvector nnet Training of Xvector nnet Xvector nnet in Kaldi     Statistics Extraction Layer in Kaldi ...

  6. mongoose 连接数据库操作

    连接数据库 var mongoose = require('mongoose'); var schema = mongoose.Schema; // 连接MongoDB mongoose.connec ...

  7. [转] 常用Loss函数

    好文mark 转自机器之心 :https://www.jiqizhixin.com/articles/2018-06-21-3 “损失函数”是机器学习优化中至关重要的一部分.L1.L2损失函数相信大多 ...

  8. 第三周 数据分析之概要 Pandas库数据特征分析

    数据的排序: 数据的基本统计分析 : 数据的累计统计分析: 数据的相关分析: 单元小结

  9. iOS app内打开safari完成google的OAuth2认证

    最近使用google的oauth认证,发现不再允许使用UIWebview进行认证了,必须使用系统游览器,使用游览器也不一定要在app之间跳转,ios使用SFSafariViewController就可 ...

  10. vue路由懒加载

    大项目中,为了提高初始化页面的效率,路由一般使用懒加载模式,一共三种实现方式.(1)第一种写法: component: (resolve) => require(['@/components/O ...