2019年 前端总结二【转藏】

作者:前端小胖

前后端分离
解决前后端服务器共存
大后端:
nodejs + express + router + ejs 后端处理路由,渲染页面
html + css + js效果 http://localhost:3000 public
大前端:
Vue-cli + vue-router + axios/resource + vuex 前端处理路由
this.$http(url:接口,params:{keyvalue})
nodeJs + express
负责:写接口,处理后端到库,send(库数据) json() write+end()
前后端分离:
跨域:需要后台允许的, 设置头
a) 逐条设置
res.setHeader('Access-Control-Allow-Origin', req.headers.origin)
问题:每一个路由都要设置
b) 统一设置(中间件cors)
app.use(cors({
"origin": ['http://localhost:8080'],
methods: "GET,HEAD,PUT,PATCH,POST,DELETE",
allowedHeaders:['Content-Type', 'Authorization']
}));
跨源凭证
ajax跨源请求数据,默认不提供凭据(cookie,http认证,客户端SSL证明)
流程:假设
vue->用户中心->vue发送请求->nodejs响应判断无session,返回给vue->vue路由切换到登录页面->vue发送登录请求->nodejs响应,兜库,种cookie(需要凭证),返回用户数据->vue 路由跳转,传递接受到的数据给 "用户中心组件"

        切换到其他路由,再切回来(用户中心)->vue发送请求->nodejs响应判断有session,返回vue的是 已登录|兜库拿用户数据
    使用携带跨源凭据|反向跨域
        前端: 携带
            a)  逐条允许 axios({})
                withCredentials: true,//携带跨源凭证
            b) axios.defaults.withCredentials=true 统一携带
        后端:允许携带
            a) 逐条允许
                res.setHeader('Access-Control-Allow-Credentials', true);
            b) 中间件统一配置(cors)



前端原生:请求头里面带凭证,带cookie
var xhr = new XMLHttpRequest();
xhr.open("post", "xxx/xxx", true);
xhr.withCredentials = true;     放在 open 方法后面比较靠谱
xhr.onload = function(){}
xhr.send("a=1&b=2");

前端jqAjax:   请求头里面带凭证,带cookie
    $.ajax({
        type:'get',
        url:"http://localhost:3000/logouts",
        dataType:"json",
        xhrFields: {
            withCredentials: true
        },
        success:function(data){
            console.log(data);
        }
    })
    前端:vue-resource
            this.$http.get(url,{credentials:true}) 追条

        Vue.http.interceptors.push(function(request, next) {
          request.credentials = true  统一
          next();
        });

部署前:build
历史记录模式路由,部署nodejs服务器环境问题
技术环境: nodejs + express +public(build后的vue代码)
问题:客户端路由服务找/todos/42时,服务器会找build/todos/42(没有这个子服务接口)
解决:以index.html用于任何未知路径

    app.use(express.static(path.join(__dirname, 'build')));

    +app.get('/*', function (req, res) {
       res.sendFile(path.join(__dirname, 'build', 'index.html'));
     });
    app.listen(3000);

css 3 loading 动画

https://www.cnblogs.com/lhb25/p/loading-spinners-animated-with-css3.html

vue + echarts
npm i echarts --save
import echarts from 'echarts'
使用eechartsAPI

vue + 百度地图
http://lbsyun.baidu.com/
1 注册百度账号
2 申请成为百度开发者 注册 浏览器端
3 获取服务密钥(ak)
4 使用相关服务功能

vue的index.html cdn加入 库
  <script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=0933b0c4da0af91731e5dd9ffbc58511">
组件里面使用:
  注意:地图的id要有,元素要有高

  API:http://lbsyun.baidu.com/cms/jsapi/reference/jsapi_reference.html
  demo:http://lbsyun.baidu.com/jsdemo.htm#a1_2

----------------------react----------------------
介绍:
干嘛的:前端框架,把用户界面抽象成一个个的组件,按需组合成页面
官网:https://reactjs.org/
http://react.css88.com/
不同点:
angularJs vueJs reactJs angularTs(2+)
控制器 √ - - -
过滤器 √ √ - √
指令 √ √ - √
模板引擎 √ √ - √
服务 √ - - √

jsx     -           √       √                       -


共同点:
    虚拟DOM(angularJs除外  angular有),数据驱动

JSX: react的模板语言
文件: oo.js/ oo.jsx
理解1:比喻(js + 类html) 类XML语法(json前身)
理解2:jsx是js一个数据类型 var a='<strong></strong>' 字符 var b= <strong></strong> jsx类型

语法要求:
    标签要闭合
    元素必须要有一个顶层元素
    变量首字母大写代表组件,小写对应是js数据类型
    属性,小驼峰命名 tabindex -> tabIndex

精髓:多组件组合,jsx+函数式编程(运算写成一系列的函数嵌套)

思想:
组件拆分目标:为了复用
组件如何拆:单一原则
状态应该给谁:
尽量给顶层组件(状态提升),->props->子组件
可以从 props(属性) 或者 state(状态) 得到,那么它可能不应该在 state(状态) 中
方法-》操作数据(数据|状态在哪,方法就应该在哪)
props取名:从组件本身的角度来命名, 而不是它被使用的上下文环境

纯函数:不会试图改变它们的输入,并且对于同样的输入,始终可以得到相同的结果,React
组件都必须是纯函数,并禁止修改其自身 props
    function(a,b){不会随机,不会修改a和b的值,输出可控}

setState: 是异步的,会将多个 setState() 调用合并为一次更新,所以不能同步依赖上一个setState的值,作为下一个setState的参数
    解决:
        1) this.setState(function(prevState,props){})
          prevState 抓取之前this.setState的所有状态
          props 所有属性
          更新会被合并,浅合并
        2) 函数节流(异步操作)
        3) ev.target......
refs绑定的是dom元素,挂载完毕时才可访问

环境搭建:
a) webpack + webpack-dev-server
/ 指向 index所在位置,图片,数据 都指向 /
js / css / jsx 相对定位

b) npm install create-react-app -g   官方脚手架

    参考: https://facebook.github.io/create-react-app/docs/getting-started

    目录解析:
        manifest.json 生成一个网页的桌面快捷方式时,会以这个文件中的内容作为图标和文字的显示内容
        registerServiceWorker.js  ==  pwa
            支持离线访问,所以用起来和原生app的体验很接近,只有打包生成线上版本的react项目时,registerServiceWorker.js才会有效。服务器必须采用https协议
        对Internet Explorer 9,10和11的支持需要polyfill。

    0. yarn add create-react-app global
        create-react-app -v 测试
            如有问题: 配置环境变量 yarn global bin -> 把得到的地址添加到环境变量
        create-react-app 目录名| .
            目标目录一定要空
        yarn start 开发模式
        yarn build 打包

    更改默认的端口号:
    1.  node_modules\react-scripts\scripts
    const DEFAULT_PORT = parseInt(process.env.PORT, 10) || 3001;

    2.  npm run eject / yarn eject
     修改script/start.js

     报git错误时: git add . -> git commit -m 'init' -> yarn eject
     报缺少babel 包: 安装一下


    本地资源导入(import) 不可以导入src之外的包

    问题:jsx前景图片, ./ 和 / 都指向了 public目录
    解决:1.模块化导入 src目录里 要在jsx里src的图片
          2.相对或者绝对导入public目录下的图片


    去除eslint 警告:
        yarn  eject
        找到项目下config/webpack.config.dev|prod
        注释关于eslint的导入和rules规则

    打包 + 预览:
        npm run build / yarn build
        serve -s build --port 端口 --open
        serve 服务器命令行工具(npm i serve -g)

        public目录里面的资源会直接copy到build目录,src里面的资源会打包模块化

    help: https://github.com/facebook/create-react-app

    解决方案:
        项目资源,尽量从src目录下引入,打包时会模块化
        图片资源模块化引入,如何来自库只能放到public目录下

c) 第三方脚手架 (yeomen/dva/mumi)
npm install
npm run dev

ES6 创建组件:es6/7类

import React from 'react';

class 组件名 extends React.Component{
    constrctor(props){ //组件有状态 constrctor就出现
        super(props) //类如果有继承 super就要出现
            需要在组件构造器内处理传递过来的props时,props参数就出现

        this.state={ // 本地状态

        }
    }
    render(){
        return jsx
    }
    方法1(){} 自定义的方法
    方法2(){}
}

ES5 创建组件:
var React = require('react');
let 组件名 = React.createClass({
getInitialState:function(){ //组件状态
return {
数据:值
}
}
render:function(){
return html|jsx
}
});
使用组件:
<HelloWorld/>
<HelloWorld></HelloWorld>

渲染(描画)页面
import ReactDom from 'react-dom';
var RactDom = require('react-dom');

ReactDom.render(组件/jsx,插入点)

组件属性(props):

调用组件:<组件名 属性名=值 属性名2=值2 .. />   传递属性
组件内部: {this.props.属性名}   jsx表达式  使用属性
          this 代表的是组件本身

值类型:字符||{表达式}
this.props.属性名==array 需要循环
arr值:this.props.属性名.map(function(){
    return html
})
json {json} 报错, 对象无法直接通过{obj}展示->{obj.key}

props类型检查

需要安装  import propsTypes from 'prop-types'

默认值:        组件.defaultProps={propName:值}
类型约定:   组件.propTypes={propsName:使用propsTypes库.类型名}

    propsTypes库.类型名
    propName: propsTypes.array/bool/func/number/object/string
必传参数: propName: propsTypes库.类型名.isRequired

事件:驼峰命名 es6 事件函数内部this会丢失
<元素 onClick={this.实例方法|函数体}

修正this的指向
onClick={this.方法.bind(this,值)}
onClick={()=>{this.方法()}}
this.方法=this.方法.bind(this)  √
this.方法=()=>{箭头函数定义方法}  √√

方法(ev)  ev 代理事件对象 ev.target 返回虚拟Vdom √

组件之间数据传递(props传递) props 禁止修改

父到子 props 传递 <Child 属性=数据/>
子到父  props 传递 <Child 属性=父方法/>
        {this.props.属性(子数据)}

所有 React 组件都必须是纯函数,并禁止修改其自身 props

ref: 抓取子元素

context组件上下文  越级传递
    Context 旨在共享一个组件树内可被视为 “全局” 的数据
    https://www.jianshu.com/p/b4983246a3dc

    顶层组件:
      //类属性 定义子上下文类型
      static childContextTypes={
        msg: propTypes.string,
        setMsg : propTypes.func
      };

      getChildContext(){//返回上下文对象
        return {
          msg:this.state.msg,
          setMsg:this.setMsg
        }
      }

    下层组件:
      //类属性 接受上下文
      static contextTypes = {
        msg: propTypes.string,
        setMsg: propTypes.func
      };

    使用:  this.context.msg | this.context.setMsg(数据)

订阅发布

路由

状态管理

组件的状态 (state|数据|私有状态|本地状态)
定义:es7实例属性:state | es6 构造器 this.state
getInitialState:fn(){return {状态名:值,xx:oo}} ES5
使用: this.state.xxx
修改: this.setState(对象|函数)


获取jsx元素 获取的是真实dom
给jsx元素 设置ref属性=名字
this.refs.名字

何时用:
    处理focus、文本选择或者媒体播放
    触发强制动画
    集成第三方DOM库

受控元素:

react 默认是单项绑定  defaultValue(非受控)

value={this.state.数据名}  model->view
onChange={this.监听方法}   view->model(  setState )
监听方法: this.setState(...)

处理多个输入元素
可以为每个元素添加一个 name 属性(通常和数据名一致)
处理函数根据 event.target.name 的值来选择要做什么

name="inputUserName" name="inputContent"
this.setState({[ev.target.name]:ev.target.value})

react 处理 样式:
1) 在index.html : 引入 link/style 场景:应用的公共样式
2)index.js: import './css/xx.css' 是全局 注入口(程序) 公共样式
2.5) 组件.js import './css/xx.css' 是全局 注入口(程序) 公共样式

    问题: 选择器冲突,
    解决:
        a) 命名空间  BEM
        b) 模块化:
            引入 import 变量  from './css/xx.module.css' 模块
            使用 <xx className={变量.类名|id}

            配置1 webpack配置 "style-loader!css-loader?modules" | module:true
                 问题:所有css都需要模块化使用
            配置2 改名xx.css -> xx.module.css 需要模块化的才修改,不影响其他非模块化css写法

jsx引用:
    className="类名 类名2" className={返回字符}
    style={{key:value,key:value}}


3)SCSS 是 Sass 3 引入新的语法
        安装: node-sass
        sass:
            使用换行和缩进

            $bg-color: #939
            .box
                background: #bg-color

        scss:
            使用分号和花括号
            $bg-color: #399;
            .box{
              background: $bg-color;
            }
        定义主题: $theme-color: #300

        scss for create-react-app脚手架
            引入: xx.sass/xx.scss  使用: <xx className="box"
            引入: style form xx.module.sass/xx.module.scss  使用: <xx className={style.box}

            引入sass全局变量?
                1. 局部sass: @import './全局.scss'
                2. 安装插件 : sass-resources-loader
                配置:use: [
                              {loader:'style-loader'},
                              {loader:'css-loader'},
                              {loader:'sass-loader'},
                              {
                                loader: 'sass-resources-loader',
                                options:{
                                  resources:'./src/xx/全局主题.scss'
                                }
                              }
                            ]

动画
css tansition
ant.desinge动画

    https://motion.ant.design/api/queue-anim

    QueueAnim:进退场动画  组件

    QueueAnim组件内部的 一级元素&& 进退场,做动画
    一级元素要有key,根据编号依次做动画,无key不动画
    路由离场动画无效
    包裹路由组件无效(一级元素&& 进退场)

生命周期流程:

实例化 ->  更新期  -> 销毁时
实例化:
    es5:
        1.取得默认属性(getDefaultProps) 外部传入的props
        2.初始状态(getInitailState)  state状态
        3.即将挂载 componentWillMount
        4.描画VDOM  render
        5.挂载完毕 componentDidMount
    es6:
        1.取得默认属性(getDefaultProps) 外部传入的props
        2.初始状态(getInitailState)  state状态
            1 && 2 都在构造器里面完成
            constructor(props){
                super(props) == getDefaultProps
                直接访问props
                this.state={} == getInitailState
                直接使用或者修改state
                不能使用setState

            }
        3.即将挂载 componentWillMount
        4.描画VDOM  render
        5.挂载完毕 componentDidMount
            才可使用ref
更新期:
    0.props改变 componentWillReceiveProps(nextProps)
        初始化render时不执行 这里调用更新状态是安全的,并不会触发额外的render调用
        nextProps 更新后  this.props更新前
    1.是否更新 shouldComponentUpdate  指视图 return true/false
    2.即将更新 componentWillUpdate
    3.描画dom  render
        不要在这里修改数据
    4.描画结束 componentDidUpdate
销毁时:
    即将卸载 componentWillUnmount
    可以做一些组件相关的清理工作,例如取消计时器、网络请求等


实例化->存在(更新)->销毁时
    getDefaultProps->getInitialState->componentWillMount->render->componentDidMount
    ->shouldComponentUpdate->componentWillUpdate->render->componentDidUpdate->
    ->componentWillUnmount

数据交互:
cra官方脚手架 静态数据读取时,参考根指向public '/data' == public/data

fetch   原生就有

用法: fetch(url+get数据,{配置}).then(成功函数(res)).catch()
res.ok -> true/false 成功/失败
res.status - > 状态码
res.body 数据 数据流(stream)

res.text() 转换 文本(string)
    过程异步:   return res.text()
    同步: res.text().then((data)=>{}) data:转换后的数据
res.json() 转  对象
配置:
    method:'POST'  默认get
    headers:{"Content-type":"application/x-www-form-urlencoded"},
    body:'a=1&b=2'|URLSearchPrams

jsonp:  fetch不带jsonp请求  需要依赖第三库
    npm install fetch-jsonp -D
    import fetchJsonp from 'fetch-jsonp'
    用法:
        fetchJsonp(url+数据,{配置}).then(success(res)).catch(error)
        特点: 是个promise 返回promise 数据是个流
        解析:res.json()  -> 流转换数据 是异步
        配置:
            timeout: 延时  5000
            jsonpCallback: 回调函数key callback
            jsonpCallbackFunction: null

create-react-app 2.x 代理

新版本cra脚手架在package.json中使用proxy只能用字符串了。

方案1: 
    配置: package.json
        "proxy":"https://uncle9.top"

    组件: /api/xx ...

问题: 只能代理一个服务器
官网给了新的使用方式,在src下新建文件setupProxy.js加下面代码,无需单独应用,webpack会自动引入文件。

解决:
    src/ 创建 setupProxy.js

    const proxy = require('http-proxy-middleware'); //需要安装中间件

    module.exports = function(app) {
      app.use(
        proxy("/api", {
          target: 'https://uncle9.top',
          changeOrigin: true
        })
      );
      app.use(
        proxy("/v2", {
          target: "https://api.douban.com",
          changeOrigin: true
        })
      );

    };

    组件: /api/xx ... | /v2/...

无状态(没有state)组件(简写)创建:
const 组件名=(props)=>(jsx)
const 组件名=props=>jsx
const 组件名=(props)=>{
let xx=props.xx
return html
}

无状态组件特点:
    不能访问this对象(this.ref,this.state  ... )
    只能访问props
    无需实例化,渲染性能高
    this.方法/钩子(生命周期)  也不需要

Qqlist(Article|Comment)
Article(ArticleList(ArticleListItem) | Page * (PageItem *) )
Comment( CommentUser | CommentList * (CommentListItem *) | Page * )


react路由3.X:
干嘛的:根据不同的URL,展示不同的内容
安装:npm install react-router@3.2.1 -D
引入:import {
Router, 路由对象
Route, 一个路由配置
hashHistory, 哈希模式
IndexRoute, 默认路由
Link, 路由调用
Redirect 重定向
browserHistory 历史记录
} from 'react-router';
配置路由: 路由对象Router,一定要包裹一个根路由
Router history={hashHistory}
Route path="/" ..
xx
xx
oo
oo
xx
oo
xx
调用:hash模式下不用加/ browser模式需要加/
Link to="path名" 转换成DOM a ,不可改
path名: string|| {{pathname:'news/003',query:{a:1,b:2}}}
展示区: 找组件自身要props
{this.props.children} 展示区
{this.props.params.aid} 参数
{this.props.location.query} 数据
{this.props.location.pathname} 路径
组件内部获取router对象 this.props.router
this.props.router.push('xxx')/replace('')/goBack/goForward/go(-1)
跳转:this.props.router/ hashHistory/window.history 都是操作历史记录
激活后路由样式:
activeClassName="外部css的类名"
activeStyle={json} json={bacgroundColor:xx}驼峰

browserHistory:需要配置webpack服务(package.json + --history-api-fallback)
    Link调用路由时,需要/xx
    <Link to="/home"
    <Link to="/user/reg"

守卫
    前置进入前,数据预载 ,路由配置内完成
        <Route path="login" component={Login} onEnter={enterRoute}/>
        const enterRoute=(to, redirect,next)=>{
          to //去向路由
          redirect 重定向函数 replaceState(url)
          next();//允许
          to.location.query.data=data;//模拟接收到的数据,并修改
    离开,后置   组件内部完成
        设置路由,离开钩子 , 组件DidMount设置
        this.props.router.setRouteLeaveHook(
          this.props.route,
          this.routerWillLeave
        )

        离开钩子
        routerWillLeave(nextLocation)
        return false/true 允许或者不允许
        nextLocation 要去向的路由

react路由 4.x
资料:
API:https://reacttraining.com/react-router/web/guides/quick-start
CN:http://blog.csdn.net/sinat_17775997/article/details/77411324
redux:https://github.com/reacttraining/react-router/tree/master/packages/react-router-redux
区别:
V4
嵌套式路由(路由配置在组件内部),动态路由,包容性(多路由渲染)
舍去了路由钩子
V3
分离式(统一位置配置),静态路由,排他性(只有一个路由被渲染)
理念:
遵循Just Component的 API 设计理念 万物皆组件,路由规则位于布局和 UI 本身之间

安装引入 react-router-dom

React Router被拆分成三个包:react-router,react-router-dom和react-router-native。react-router提供核心的路由组件与函数。其余两个则提供运行环境(即浏览器与react-native)所需的特定组件

BrowserRouter 使用 HTML5 提供的 history API 来保持 UI 和 URL 的同步
HashRouter 使用 URL 的 hash (例如:window.location.hash) 来保持 UI 和URL 的同步

依赖安装引入 react-router-dom

提供哪些组件:
    
    BrowserRouter  约定模式 为 history
    HashRouter   约定模式 为 hash
    NavLink     声明式跳转 还可以约定 路由激活状态 | 导航高亮    ~~ push 
    Link        声明式跳转    ~~ push
    Redirect    重定向    ~~ replace
    Route       匹配
    Switch      排他性匹配
    Prompt      后置守卫

结构:
    BrowserRouter|HashRouter 路由对象
        根组件(App)|其他组件
            NavLink|Link  导航
            Route    匹配+展示
            Redirect 跳转
            404 <Redirect to="/error"/>
            默认路由 <Route exact path={match.path} render={fuc}
Route 属性
    path(string): 路由匹配路径。(没有path属性的Route 总是会 匹配);
    exact(bool):
        为true时,要求全路径匹配(/home)。V4 的路由默认为“包含”的(/和/home都匹配),这意味着多个 <Route> 可以同时进行匹配和渲染

    component:在地址匹配的时候React的组件才会被渲染,route props也会随着一起被渲染
    render:这种方式对于内联渲染和包装组件却不引起意料之外的重新挂载特别方便
Link:
    to:string/object:要跳转的路径或地址;
NavLink:是<Link> 的一个特定版本
    activeClassName(string):设置选中样式,默认值为 active;
    activeStyle(object):当元素被选中时, 为此元素添加样式;
Switch:该组件用来渲染匹配地址的第一个<Route>或者<Redirect>,仅渲染一个路由,排他性路由,默认全匹配(场景:侧边栏和面包屑,引导选项卡等
Redirect:
    <Redirect from="/" to='/home'/> 总是会被重定向
404:    <Route component={Error}/> 总是会匹配

参数数据:{history,location,match}==props
    传递:
        to={match.url+'/001'}
        to={`${match.url}/002?a=1&b=2`}
        to={{pathname:match.url+'/003',search:'?a=11&b=12',hash:'#a1'}}
        <Route path={match.path+'/:aid'} component={Detail}
            注意:
                url - (浏览器 URL 中的实际路径) URL 匹配的部分。 用于构建嵌套的 <Link>
                path - (路由编写的路径) 用于匹配路径模式。用于构建嵌套的 <Route>
    接收:
        接参数:{match.params.aid}
        接数据:{location.search}
        接地址:{location.pathname}
    注意:
        无法从v4 中获取 URL 的查询字符串了。因为没有关于如何处理复杂查询字符串的标准。所以,作者让开发者去选择如何处理查询字符串。推荐query-string库
跳转:
    history.push('/user?a=1&b=2')
    history.push({pathname:'/user',search:'?a=11&b=22'})
    history.replace({pathname:'/user',search:'?a=111&b=222'})
    history.go(-1)
授权路由:自定义路由
    前置守卫
        <AuthRoute path="/user" component={User}/>
        AuthRoute==授权路由==react组件==自定义路由
        条件:返回一个Route 组件
              Route的render函数内部判断加载目标||Redirect组件
        实现:
            AuthRoute = ({ component: Component, ...rest }) => (
              <Route {...rest} render={props =>
                  Math.random()<0.5 ?
                    <Component {...props} />
                   : <Redirect to="/login" />
                }
              />
            )
        目标组件    Component == User
        延展剩余属性 rest
        路由信息 ...props User组件需要用到的路由信息
    数据预载:
        AuthRoute 组件构造器存状态和预载数据
        DidMount钩子里异步请求,获取状态和数据
            fetch(url).then(result=>this.setState({}))
        render钩子返回 Route
             <Route {...rest} render={props => Xxx?<Component data={预载数据}
             if(!this.state.hasAuthed) return null;初始渲染时,未发送认证请求,因此不渲染
Prompt:后置守卫,离开后守卫
    import { Prompt } from 'react-router-dom'
    <Prompt
      when={this.state.isBlocking}
      message={location=>{return `未保存,是否去向${location.pathname}`}}
    />
    message: 后面可以跟简单的提示语,也可以跟函数,函数是有默认参数的。
    when: when的属性值为true时防止跳转;

注意加入状态管理时:影响了location的跳转,要用到withRouter(connect(x,x)(app))

问题:子路由使用父路由的展示区(插槽)
    <Route path="/a" render={()=>
        <div>
            <Switch>
                <Route path="/a/b" component={b}
                <Route path="/a/c" component={c}
                <Route path="/a" component={a}
            </Switch>
        </div>
    >

withRouter:
    把不是通过路由切换过来的组件中,将 history、location、match 三个对象传入props对象上
    用法:
        import {withRouter} from 'react-router-dom'
        class App extends Component{}
        export default withRouter(App)

Immutable.js 持久化数据结构
https://www.jianshu.com/p/0fa8c7456c15


项目带练

  1. 项目分析,组件安排

    |-pubilc
    |- data
    |- 数据
    |-index.html
    |-node_modules
    |-mock
    |-db.js
    |-server.js
    |-src
    |-library
    |-jquery.js
    |-swiper.js
    |-date.js / fillzero.js/...
    |-layouts
    |- App/Header/Footer
    |-components
    |- swiper
    |- cell
    |- button
    |-pages
    |- Home / Follow / Column / User
    |- Detail / Login / Reg / Error
    |- assets
    |- img
    |- css
    |- store
    |- state/reducer/asyncAction
    Index.js


  1. 布局(切图,mint-ui,elementUI...ant.design),模板移植
    样式:全局引入
    src / import

  1. 路由搭建
    样式冲突(命名冲突(错开))
    import 模块名 from '../css/xx.css'

    模块名.类名


  1. 数据交互

    fetch(url,{配置}).then().catch()
    axios({配置}).then(数据)

    home-> cell -> detail 拿到id dataName
    follow->cell
    column->cell

    cell -> link pathname:'detail/'+id,
    query:{dataName:'home'}

    detail this.props.location.query.dataName / this.props.match.params.id

  2. 全局方法(过滤事件,补零)
    |-common
    date.js
    fillzero.js
    ...
    index.js
    import date/fillzero ..
    export {
    date,fillzero
    }
    <Provider store={store}>
    <BrowserRouter>
    <App/>
    </BrowserRouter>
    </Provider>


  1. 非状态管理,控制navbar / footbar / loading

    this.props.location.pathname -> navbar / footbar

6.5 全局loading
pubsub [App订阅, home/follow/.. 发布]
问题:用户速度切换,this.setState报错
分析:fetch中断--无法中断
解决:
1. 高光盒(lightBox)√ / 自个维护一个组件属性 this.自定义属性
2. 状态管理,数据回来不修改组件,修改状态


  1. 传值思路:
    a) 子A->父->子B
    父方法(){this.refs.子.方法}
    b) pub/sub模式 消息通知(观察者模式) npm install pubsub-js -D
    订阅: token=pubsub.subscribe('消息名',回调函数('消息名',数据))
    发布: pubsub.publish('消息名',数据)
    清除指定订阅:pubsub.unsubscribe(token|'消息名'|回调函数名);
    清除所有:pubsub.unsubscribeAll()

     注意:订阅方不存在了,相关的订阅注意清除
    
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 221,695评论 6 515
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,569评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 168,130评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,648评论 1 297
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,655评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,268评论 1 309
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,835评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,740评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,286评论 1 318
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,375评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,505评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,185评论 5 350
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,873评论 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,357评论 0 24
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,466评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,921评论 3 376
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,515评论 2 359

推荐阅读更多精彩内容

  • 今天的React题没有太多的故事…… 半个月前出了248个Vue的知识点,受到很多朋友的关注,都强烈要求再出多些R...
    浪子神剑阅读 10,090评论 6 106
  • vue是什么? vue是构建数据驱动的web界面的渐进式框架。Vue.js 的目标是通过尽可能简单的 API 实现...
    九四年的风阅读 8,713评论 2 131
  • 包含 react基础 react传值 react路由 和redux管理 和react-redux reactDom...
    栀璃鸢年_49a3阅读 1,124评论 0 1
  • [toc] REACT react :1.用来构建用户界面的 JAVASCRIPT 库2.react 专注于视图层...
    拨开云雾0521阅读 1,454评论 0 1
  • 函数是面向过程的,函数的调用不需要主体,而方法是属于对象的,调用方法需要一个主体-即对象。 npm install...
    Gukson666阅读 473评论 0 3