《react 思维导图笔记》

react

在react学习中,需要安装两个包[email protected] [email protected]

react这个包是专门用来创建react组件、组件生命周期等等
react-dom里面主要封装了和DOM操作相关的包

cnpm i [email protected] [email protected] -S

reactjs

在react中,不能直接像vue中手写HTML元素
https://reactjs.org
概述:一个javascript库、构建用户界面的
核心库只关注视图层

简介

react起源于Facebook的内部项目(Instagram)

React的核心思想:组件化(封装组件,复用组件)

声明式语法-----只需要知道怎么使用即可,不需要知道内部如何实现的

learn once write anywhere
学完ReactJs之后,可以使用基于ReactJs语法的ReactNative去做Android/ios开发

  • React简介

    1. React简介
      ●React起源于Facebook的内部项目,因为该公司对市场上所有JavaScript MVC框架。都不满意,就决定自
      己写一套,用来架设Instagram (照片交友)的网站。做出来以后,发现这东西很好用,就在2013年5月开
      源了,
      I
      ●Angular1 2009年谷歌MVC不支持组件化开发
      ●由于React的设计思想极其独特,属于革命性创新,性能出众,代码逻辑却非常简单,所以,越来越多的人开
      始关注和使用,认为它可能是将来Web开发的主流工具,
      ●清楚两个概念:
      。library (库) :小而巧的库,只提供了特定的API;优点就是船小好掉头,可以很方便的从-个库切换到
      另外的库:但是代码几乎不会改变;
      。Framework (框架) :大而全的是框架;框架提供了一整套的解决方案:所以,如果在项目中间,想切换
      到另外的框架,是比较困难的:

如何搭建ReactJs的开发环境

方案1:借助于命令行的方式
//安装工具create-react-app
npm install -g create-react-app
//创建一个my-app的基于ReactJs的项目
create-react-app my-app
//进入my-app目录
cd my-app/
//启动开发服务器
npm start
方案2:直接在普通的项目中,引入对应的文件:
引入了3个文件:
react.js-----核心文件
react-dom.js-----处理与DOM操作
browser.min.js----支持jsx语法

  • 创建一个组件

    是一个用来渲染视图的类,视图是可被反复使用的,带有特定功能
    var MyComponent = React.createClass({
    render: function () {
    return


    }
    });

    组件命名首字母大写

  • 复合组件

    在React中,并不是新的概念,其实是一个组件,只不过组件中包含其他的组件

  • awesome react

    参考:https://github.com/brillout/awesome-react-components

前端三大主流框架(Framework)

1.Angular.js:最早前端框架、
2.React.js:最流行的一门框架、设计优秀
3.Vue.js:最火的一门前端框架

react和vue.js都是基于组件化开发

  • Vue.js组件化方式

    通过.vue组件模板文件(浏览器不识别,需要编译成真正的组件)
    1.templateUI结构
    2.script业务逻辑和数据
    3.styleUI样式

  • 在vue中,有v-model指令来实现双向数据绑定

  • vue路由

    var router = new VueRouter({
    routes: [
    {path: ‘’, component: ‘’}
    ]
    });

    • router-link
    • router-view

模块化

从代码的角度分析问题,把业务逻辑分割到不同的模块中进行开发,方便代码的重用

组件化components

从UI的角度分析问题,把页面拆分多个小组件,随着我们的项目开发,组件会越来越多,能够方便我们快速得到一个完整的页面、方便UI元素组件的重用(组件是元素的集合体)

全部通过js实现组件化

好处:1.提高了代码的复用率
2.提高了代码的可读性、可维护性
3.提高了编码速度

  • 最基本的方式

    在react中,构造函数,就是一个最基本的组件
    function Hello() {
    return null;
    }

    function Hello() {
    return


    123

    ; } 调用:
  • react在解析所有标签的时候,是以标签的首字母来区分的,如果标签的首字母是小写,按照普通HTML标签来解析,如果首字母是大写,按照组件的方式去解析渲染

  • …对象----es6中的属性扩散,表示把对象的所有属性展开

  • function Hello(props) {}

    在组件中,如果想要使用外部传递过来的数据(只读),必须显示在构造函数参数列表中,定义props属性来接收;

    props.属性

  • 暴露组件export default Hello

    暴露组件的另一种方式:
    export default class Hello extends React.Component {
    constructor(props) {
    super(props);

        this.state = {
            msg: "请输入您的身份信息",
            info: "湖北省"
        }
    }
    render() {
        return this.state.info;
    }
    

    }

    export default function Hello(props) {
    return props;
    }

  • 另一种创建组件的方式通过es6的关键字class

    • class实现面向对象的新形式

      class Person {
      constructor(name, age) {
      this.name = name;
      this.age = age;
      }
      say() {
      console.log(“test”);
      }
      static info = ‘hello’;
      }

      class Chinese extends Person {
      constructor(color, language) {
      super(“老师”, 30);
      this.color = color;
      this.language = language;
      }
      }

      var p = new Person(“ls”, 28);
      var c = new Chinese(“red”, “韩语”);
      console.log©;
      c.say();
      console.log(Chinese.info);

    • 通过继承React.Component,使Hello成为一个组件

      class Hello extends React.Component {
      render() {
      return null;
      }
      }
      通过class实现组件,需要定义一个render函数(表示渲染哪些虚拟DOM元素并展示出来)

      class Hello extends React.Component {
      render() {
      return 123;
      }
      }

    • 在function定义组件中,如果需要使用props必须先定义,否则无法直接使用,但是,在class定义的组件中,可以直接使用this.props来直接访问

      class Hello extends React.Component {
      constructor(props) {
      super(props);
      }
      render() {
      return this.props.age;
      }
      }

    • this.state表示当前组件实例的私有数据对象

      class Hello extends React.Component {
      constructor(props) {
      super(props);

          this.state = {
              msg: "请输入您的身份信息",
              info: "湖北省"
          }
      }
      render() {
          return this.props.age;
      }
      

      }

    • render() {
      /var arr = [];
      this.state.cmts.forEach(item => {
      arr.push(

      {item.user}

      );
      });/

      return

      {arr}
      ;
      }

      render() {
      /var arr = [];
      this.state.cmts.forEach(item => {
      arr.push(

      {item.user}

      );
      });/

          return 
      {this.state.cmts.map((item, i) => { return

      (唯一的key,必须定义,vue中通过:key="i"定义)

      评论人:{item.user}


      评论内容:{item.content}


      ;
      })}
      ;
      }
    • 无状态组件和有状态组件的组合使用

      import React from ‘react’;

      function CommentItem(props) {
      return


      评论人:{props.user}


      评论内容:{props.content}


      ;
      }

      export default class CommentList extends React.Component {
      constructor(props) {
      super(props);

          this.state = {
              cmts: [
                  {user: '张三', content: '哈哈哈,沙发'},
                  {user: '李四', content: '哈哈哈,板凳'},
                  {user: '王五', content: '哈哈哈,凉席'},
                  {user: '赵柳', content: '哈哈哈,砖头'},
                  {user: '老王', content: '哈哈,楼下山炮'},
              ]
          }
      }
      render() {
          /*var arr = [];
          this.state.cmts.forEach(item => {
              arr.push(

      {item.user}

      ); });*/ return
      {this.state.cmts.map((item, i) => { return ;或者 return ; })}
      ; }

      }

  • 组件

    无状态组件—没有生命周期函数
    有状态组件----存在生命周期函数

    • 无状态组件

      没有this.state私有数据属性
      function Hello(props) {
      return props;
      }

      • 案例

        import React from ‘react’;

        export default function CommentItem(props) {
        return


        评论人:{props.user}

        评论内容:{props.content}


        ;
        }

    • 有状态组件

      存在this.state私有数据属性,可读可写
      class Hello extends React.Component {
      constructor(props) {
      super(props);
      this.state = {

      }
      }
      render() {
      return this.state;
      }
      }

refs

通过ref找到真实的DOM节点

            console.log(this.refs.input.value);

组件的本质就是视图

核心思想:封装组件、复用组件

props----属性

property

this.props.myname

props is immutable(不变的)

  • 属性传值

    var MyHeader = React.createClass({
    render() {
    return

    { this.props.myTitle }

    ;
    }
    });

        ReactDOM.render(
         
    , document.querySelector('#app'));
    • 单向数据流
  • children属性

    this.props.children

    var myList = React.createClass({
    render() {
    return


    • { React.Children.map(this.props.Children, (child) => {
      return child;
      }) }
    ;
    }
    });

        ReactDOM.render(
        
  • 1
  • 2
  • , document.querySelector('#app'));

父子组件传递属性和方法

调用方法:
return ;

  • 子组件传参给父组件

    myClick() {
    this.props.myClick(‘张三’);
    },

借助于单向数据流

减少了业务的复杂度,降低了代码的维护成本

babel

是一个js的编译器,可以支持将typescript\es6\jsx, 转换为当前浏览器所支持的普通的js

虚拟DOM(Virtual Document Object Model)

VDOM
通过js实现模拟DOM
var p = {
tagName: ‘p’,
children: [
var p = {
‘p标签’
]
}

react内部已经为我们实现了虚拟DOM
虚拟DOM就是一种数据结构,由组件构成

  • 减少操作DOM的次数

    目的:为了实现页面中,DOM元素的高效更新

  • 什么是React中的虚拟DOM

    框架中的概念,是程序员用js对象来模拟页面上的DOM和DOM嵌套;

  • DOM的本质

    浏览器中的概念,用js对象来表示页面上的元素,并提供了操作DOM对象的API;

state

状态:在React中,任何会变化的数据,都要保存在状态中。

React支持将状态中的值动态绑定到视图:
React是可以将状态中的值绑定到视图,当状态中的值发生变化的时候,react框架会检测到这一变化,然后在合适的时间经过DOM diff算法,采用最优的效率来更新真实的DOM

  • 基本操作

    1.初始化
    getInitialState() {
    return {
    count: 0
    };
    }
    2.写状态(异步操作)
    this.setState({ count: 1 }, func);
    3.读状态
    this.state.count

lifecycle

生命周期
在React中,组件的分为3个阶段:mount、update、unmount

表单

  • 受控表单元素

    值不可改变

  • 非受控表单元素

    • defaultValue的使用

      存在默认值,可修改、添加值

todoslist

参考:http://todomvc.com/

Diff算法

tree diff
component diff
element diff
DOM diff都是交给React框架处理

JSX语法

能够让我们在js文件中书写类似于html那样的代码、快速定义虚拟DOM结构(符合XML规范的JS语法)

cnpm i [email protected] -D(开发环境中需要用到)

导包:
import React from ‘react’;
import ReactDOM from ‘react-dom’;

【“env”, “stage-0”, “react”】
{ 变量名 }

  • javascriptXML

    JavaScriptXML并不是一种新的语法,只不过是支持在js中编写HTML标记而已,reactJS在渲染元素时,是不允许直接返回多个要渲染的元素,要统一放在一个容器中,支持js运算的通过花括号{}的语法执行js运算

    • ReactDOM.render()

      //向指定的容器渲染元素

  • jsx语法要求只能有一个根元素

  • React.createElement(‘div’, {title: ‘this is a div’, id: ‘mydiv’}, ‘div元素’)至少接收三个参数

    var mydiv = React.createElement(‘div’, {title: ‘div的title属性----div’, id: ‘mydiv’}, ‘这是一个div’);

    var myH1 = React.createElement(‘h1’, null, ‘这是一个h1’);
    等价于:
    var myH1 = React.createElement(‘h1’, {}, ‘这是一个h1’);

  • ReactDOM.render(‘需要渲染的DOM元素’, ‘要渲染到页面上的哪个位置中’)

    ReactDOM.render(mydiv, document.getElementsByClassName(‘info’)[0]);

  • 在{}内部、可以书写符合js规范的代码、在jsx中,添加class属性必须写成className、为label标签添加for属性写成htmlFor

    key = {i}

  • 在jsx语法中,如果需要使用style属性,为jsx语法创建DOM元素,设置样式,不能像网页中那么写样式,而是使用js语法来写样式

    style样式规则:如果属性值单位是px,可以省略
    import React from ‘react’;

    export default function CommentItem(props) {
    return

    (外层{}表示要写js代码了,内层{}表示用一个js对象表示样式)

    评论人:{props.user}


    评论内容:{props.content}


    ;
    }
  • 样式优化

    • 方式一

      import React from ‘react’;

      const divStyle = {border: ‘1px solid #ccc’, margin: ‘10px 0’, paddingLeft: 15};

      export default function CommentItem(props) {
      return


      评论人:{props.user}

      评论内容:{props.content}


      ;
      }
    • 方式二

      import React from ‘react’;

      const inlineStyle = {
      divStyle: {margin: ‘10px 0’, paddingLeft: 15, border: ‘1px solid #ccc’},
      h3Style: {color: ‘purple’, fontSize: 16},
      pStyle: {color: ‘red’, fontSize: 14}
      };

      export default function CommentItem(props) {
      return


      评论人:{props.user}


      评论内容:{props.content}


      ;
      }

  • 像input这样的单标签必须要闭合—“ / ”

  • 组件名称大写–切记

react项目的创建

1.运行cnpm i react react-dom -S安装包
2.导入相关包
3.创建虚拟DOM节点
4.渲染到页面

CSS模块化

1)import commentItem from ‘…/…/css/commentItem.css’;
2) {test: /.css$/, use: [‘style-loader’, ‘css-loader?modules’]},
(通过给css-loader添加参数modules,为css开启模块化)

css开启模块化之前,commentItem是个空对象,启用css模块化之后,所有类名都是私有的,如果想要把类名设置成全局的类,通过:global()包裹
:global(.box) {
color: red;
font-weight: 200;
text-align: center;
}

  • 让命名更符合规范

    1) {test: /.css$/, use: [‘style-loader’, ‘css-loader?modules&localIdentName=[name]_[local]-[hash:5]’]},
    (参数localIdentName–随机生成的class名称,name—css文件名称,local—文件内选择器的名称,hash–32位哈希码)

  • react组件内部的样式没有私有作用域

    通过webpack—css-loader可以让react组件内部样式具有私有作用域

组件的生命周期

“dependencies”: {
“jquery”: “^3.2.1”,
“prop-types”: “^15.6.0”,
“react”: “^16.1.1”,
“react-dom”: “^16.1.1”
},

https://github.com/brillout/awesome-react-components

  • 概念

    在组件创建、到加载到页面上运行、以及组件被销毁的过程中,总是伴随着各种各样的事件,这些在组件特定时期,触发的事件,统称为组件的生命周期

  • 组件生命周期分为三部分

    1)组件创建阶段(执行一次)
    componentWillMount、render、componentDidMount
    2)组件运行阶段
    componentWillReceiveProps、shouldComponentUpdate、componentWillUpdate、render、componentDidUpdate
    3)组件销毁阶段
    componentWillUnmount、

  • 使用defaultProps设置组件的默认值

    在react中,使用静态的defaultProps属性,来设置组件的默认属性值

    import React from ‘react’;

    export default class Counter extends React.Component {
    constructor(props) {
    super(props);

        this.state = {
            
        }
    }
    
    static defaultProps = {
        initCount: 0
    }
    
    render() {
        return 

    这是count计数器


    当前的数量是:{this.props.initCount}

    ; }

    }

  • 使用propTypes做类型校验

    1.需要安装prop-types第三方包
    cnpm i [email protected] -S
    在v.15.*之前这个包还没有从react分离

    import PropTypes from ‘prop-types’;

    static propTypes = {
    initCount: PropTypes.number
    }

  • 介绍componentWillMount(UNSAFE_componentWillMount, 这是新的名称)函数

    componentWillMount() {
    this.myselfFunction();
    }

    render() {
    return


    这是count计数器





    当前的数量是:{this.props.initCount}


    ;
    }

    myselfFunction() {
        console.log("这是我自定义的函数");
    }
    
    • 这个函数等同于vue中的created生命周期函数
  • 组件创建阶段的render函数

    将虚拟DOM渲染到内存中

  • 介绍componentDidMount函数

    虚拟DOM从内存渲染到页面
    componentDidMount() {
    console.log(document.querySelector(’#h3’));
    }

    • 这个函数等同于vue中的mounted生命周期函数
  • 改变this.state内的值

    btn.addEventListener(‘click’, () => {
    this.setState({
    count: this.state.count + 1
    });
    });

    箭头函数可以避免使用.bind(this);方法

    increment = () => {
    this.setState({
    count: this.state.count + 1
    });
    }

  • 使用react提供的事件绑定机制

  • 组件shouldComponentUpdate(nextProps, nextState) {}是否需要更新

    1.必须返回一个布尔值
    return false;
    2.false—不会继续执行生命周期函数,退回到运行状态,页面不会更新,但组件state会更新

    shouldComponentUpdate(nextProps, nextState) {(nextState是state最新的值,nextProps是初始值)
    return nextState.count % 2 === 0 ? true : false;
    }

  • 组件componentWillUpdate(UNSAFE_componentWillUpdate, 这是新名称)

    此时虚拟DOM和页面都是旧的

    react-----ref用法:

    当前的数量是:{this.state.count}

    componentWillUpdate() {
    console.log(this.refs.h3.innerHTML);
    }

    componentWillUpdate() {
    console.log(this.refs.h3.innerText);
    }

    • componentDidUpdate

      componentDidUpdate(prevProps, prevState);

  • 介绍componentWillReceiveProps(UNSAFE_componentWillReceiveProps, 这是新名称)

    componentWillReceiveProps(nextProps) {
    console.log(this.props.pmsg, nextProps.pmsg);//这是父组件中的msg消息 点击测试
    (nextProps.pmsg是最新的消息)
    }

扩展

context特性
getChildContextTypes
前三个,后三个,后两个
一个方法、两个静态属性
----组件参数传递

父组件共享context对象:
getChildContext() {
return {
color: this.state.color
};
}

static childContextTypes = {
    color: PropsTypes.string
}

子孙组件只需:
render() {
return


这是孙组件
;
}

static contextTypes = {
    color: PropsTypes.string
}

react-router-dom路由的基本使用

https://reacttraining.com/react-router/
参考网站:其中网站选择web、手机APP选择native

cnpm i [email protected] -S

import React from ‘react’;
import {
BrowserRouter as Router,
Switch,
Route,
Link
} from “react-router-dom”;
import Home from ‘./component/Home.jsx’;
import Movie from ‘./component/Movie.jsx’;
import About from ‘./component/About.jsx’;

export default class App extends React.Component {
constructor(props) {
super(props);

    this.state = {

    }
}

render() {
    return 
        

这是网站的APP根组件


首页   电影   关于
; }

}

  • HashRouter

    表示一个路由的根容器,所有路由有关的都包裹在该容器里面,一个网站使用一次HashRouter

    import React from ‘react’;
    import {
    HashRouter,
    Route,
    Link
    } from ‘react-router-dom’;
    import Home from ‘./component/Home.jsx’;
    import Movie from ‘./component/Movie.jsx’;
    import About from ‘./component/About.jsx’;

    export default class App extends React.Component {
    constructor(props) {
    super(props);

        this.state = {
    
        }
    }
    
    render() {
        return 
            

    这是网站的APP根组件


    首页   电影   关于
    ; }

    }

  • Route

    表示一个路由规则,
    属性:path、component、exact

    (path表示要匹配的路由,component表示要展示的组件)

    Route具有两种身份,一个是路由匹配规则、另一个是占位符(组件)

    • 匹配路由参数

      默认匹配规则是模糊匹配

      exact---------精确匹配

      /:type/:id----------匹配参数

    • 获取参数

      Movie ------- {this.props.match.params.type} — {this.props.match.params.id}

      import React from ‘react’;

      export default class Movie extends React.Component {
      constructor(props) {
      super(props);

          this.state = {
              routeParams: props.match.params
          }
      }
      
      render() {
          return 
      Movie ------- {this.state.routeParams.type} --- {this.state.routeParams.id}
      ; }

      }

    • Switch组件使用

      使用类似switch…case

  • Link

    表示一个路由的链接

    属性:to

     首页
    

UI框架—AntDesign

AntDesign组件------antd
参考网站:https://ant.design/index-cn

cnpm i [email protected] -S

  • 一般,第三方UI插件,他们的样式表文件都是以.css结尾,建议对scss和less文件进行模块化

  • 按需导入

    1.cnpm i [email protected] -D

    2.在.babelrc:
    “plugins”: [“transform-runtime”, [“import”, {“libraryName”: “antd”, “style”: “css”}]]
    3.import {
    DatePicker
    } from ‘antd’;
    4.render() {
    return


    这是网站的APP根组件







    首页  
    电影  
    关于










    ;
    }

  • import { Spin, Alert } from ‘antd’;-----加载组件

  • 评分组件

    import { Rate } from ‘antd’;

  • 分页组件

    import { Spin, Alert, Pagination } from ‘antd’;

  • 返回按钮组件

es6—fetch–API

用来获取数据
基于Promise封装的,存在跨域问题

fetch(“http://vue.studyit.io/api/getlunbo”, {mode: “no-cors”}).then(res => {
console.log(res);
});

fetchJsonp(“请求的url地址”)
.then(response => res.json() )
.then(data => console.log(data))
//注意: 第一个.then 中获取到的不是最终数据,而是一个中间的数据流对象;
// 注意: 第一个 .then 中获取到的数据, 是一个 Response 类型对象;
// 注意: 第二个 .then 中,获取到的才是真正的 数据;

  • Make JSONP request like window.fetch

    cnpm i fetch-jsonp -S ---------解决跨域问题

    import fetchJSONP from ‘fetch-jsonp’;

借助缓存–完成图片加载

getImages(_url) {
if (_url !== undefined) {
let _u = _url.substring(7);
return ‘https://images.weserv.nl/?url=’ + _u;
}
}


编程式导航

通过this.props.history.push(’/movie/’ + this.state.movieType + ‘/’ + page);

reactnative

在推出ReactNative之前,React ReactJS React.js都是指的是用来进行前端开发的一个框架

在推出ReactNative之后,React分为两大块,一个是ReactJs, 一个是ReactNative
react-native init mytest

采用React语法(jsx、component、refs、state、props)写android和iOS

参考:reactnative.cn
https://github.com/kunyashaw
https://github.com/facebook/react-native

调用ReactNative所封装的组件,来编写移动端的原生应用程序

搭建开发环境

方式一:create-react-native-app
全局安装create-react-native-app
npm install -g create-react-native-app
创建一个基于react-native的模板项目,名称叫my-app
create-react-native-app my-app
切换到my-app目录
cd my-app
启动开发服务器
npm start

方式二:react-native-cli
npm install -g react-native-cli
创建一个模板项目
react-native init my-app
启动开发服务器(配置连接服务器)
cd my-app
react-native start

使用弹性布局Flexbox布局

1.flexdirection
2.align items

webpack打包工具

合并(减少二次请求)、压缩(提高加载速度)、精灵图(减少二次请求)、图片的base64编码(和html一起下载)

解决各个包之间的复杂依赖关系,是前端的一个项目构建工具,它是基于Node.js开发

[email protected] 要打包的文件路径 打包好的输出文件路径
npm run dev

全局安装npm i webpack -g

可以处理js文件之间的相互依赖关系

处理js兼容问题

webpack.config.js

//入口entry(要打包的文件路径)和出口output(打包好的文件路径)
const path = require(‘path’);

module.exports = {
entry: path.join(__dirname, ‘./src/main.js’),
output:{
path: path.join(__dirname, ‘./dist’),
filename: ‘bundle.js’//指定输出的文件的名称
}
}

执行webpack。。。进行打包

path.resolve();
mode: ‘’ 设置环境

使用webpack-dev-server(@2.9.3)这个工具,来实现自动打包编译的功能

运行npm i [email protected] -D安装

webpack-dev-server
cnpm i [email protected] -D

2.9.4

常用命令

“dev”: “webpack-dev-server --open --port 3000 --contentBase src --hot”

=》npm run dev

–open(打开浏览器)
–port 3000(修改端口号)
–contentBase src(修改根路径为src)
–hot(无刷新重载,打补丁)
–host 192.168.1.1

在webpack中带s的都是数组

  • webpack-dev-server命令的另外一种使用方式

    在webpack.config.js中设置:
    devServer: {
    contentBase: ‘src’,
    open: true,
    port: 3000
    }

借助工具实现页面也加载到内存

1.cnpm i html-webpack-plugin -D

生成一个内存的页面、追加bundle.js

2.30.1

js默认只能打包处理js类型的文件,无法处理其他非js类型的文件

第三方loader加载器

cnpm i [email protected] [email protected] -D(处理打包css文件)

import ‘./css/index.css’;

module: {
rules: [
{test: /.css$/, use: [‘style-loader’, ‘css-loader’]}(调用顺序从右至左)
]
}

cnpm i less-loader@0 -D第三方loader加载器

cnpm i [email protected] -D

import ‘./css/index.less’;

{test: /.less$/, use: [‘style-loader’, ‘css-loader’, ‘less-loader’]}

cnpm i [email protected] -D第三方loader加载器scss文件

npm i [email protected] -D
cnpm i node-sass@4.* -D

webpack3.x的版本与webpack-dev-server3.x 的版本不兼容。

{
“name”: “webpack-senior”,
“version”: “1.0.0”,
“description”: “”,
“main”: “webpack.config.js”,
“scripts”: {
“test”: “echo “Error: no test specified” && exit 1”,
“dev”: “webpack-dev-server --open --port 3000 --hot”,
“pub”: “webpack --config webpack.pub.config.js”
},
“keywords”: [],
“author”: “”,
“license”: “ISC”,
“dependencies”: {
“antd”: “^2.13.10”,
“jquery”: “^3.2.1”,
“prop-types”: “^15.6.0”,
“react”: “^15.6.2”,
“react-dom”: “^15.6.2”,
“react-router-dom”: “^5.0.1”
},
“devDependencies”: {
“babel-core”: “^6.26.0”,
“babel-loader”: “^7.1.2”,
“babel-plugin-import”: “^1.6.2”,
“babel-plugin-transform-runtime”: “^6.23.0”,
“babel-preset-env”: “^1.6.1”,
“babel-preset-react”: “^6.24.1”,
“babel-preset-stage-0”: “^6.24.1”,
“clean-webpack-plugin”: “^0.1.17”,
“css-loader”: “^0.28.7”,
“extract-text-webpack-plugin”: “^3.0.2”,
“file-loader”: “^1.1.5”,
“html-webpack-plugin”: “^2.30.1”,
“node-sass”: “^4.6.0”,
“optimize-css-assets-webpack-plugin”: “^3.2.0”,
“sass-loader”: “^6.0.6”,
“style-loader”: “^0.19.0”,
“url-loader”: “^0.6.2”,
“webpack”: “^3.8.1”,
“webpack-dev-server”: “^2.9.4”
}
}

module: {

    rules: [
        {test: /\.css$/, use: ['style-loader', 'css-loader']},
        {test: /\.(png|gif|bmp|jpg)$/, use: 'url-loader?limit=5000'},
        {test: /\.scss$/, use: ['style-loader', 'css-loader', 'sass-loader']},
        {test: /\.jsx?$/, use: 'babel-loader', exclude: /node_modules/}
    ]
}

默认情况下,webpack无法处理css文件中的url地址,通过第三方模块进行处理

cnpm i [email protected] [email protected] -D(url-loader包内部依赖于file-loader,所以不需要配置file-loader)

{test: /.(png|gif|bmp|jpg|jpeg)$/, use: ‘url-loader?limit=5000’&name=[hash:8]-[name].[ext]},(?后面传参,当图片大小大于等于极限limit时不会转成base64字符串编码,name=[hash:8]-[name].[ext]打包后的文件名和扩展名还是原来的,【hash:8】表示生成哈希码从32位中截取8位)

hash(32位哈希值)

{test: /.(png|gif|bmp|jpg|jpeg)$/, use: ‘url-loader?limit=4981&name=images/[hash:8]-[name].[ext]’},

处理字体url-loader

{test: /.(eot|svg|ttf|woff|woff2)$/, use: ‘url-loader’}

在webpack中,默认只能处理一部分es6的新语法,一些更高级的es6语法或者es7语法,webpack是处理不了的,这时候,就需要借助于第三方的loader,来帮助webpack处理这些高级的语法

1.第一套包:cnpm i [email protected] [email protected] [email protected] -D
2.第二套包:cnpm i [email protected] [email protected] -D

然后打开webpack配置文件:
添加配置:
{test: /.jsx?$/, use: ‘babel-loader’, exclude: /node_modules/},
(exclude除了,为了webpack打包时,不处理node_modules里面的js文件)

在项目根目录新建一个.babelrc的Babel配置文件,这个配置文件,属于json格式(符合json语法规范、不能写注释、字符串使用双引号)内容如下:
{
“presets”: [“env”, “stage-0”, “react”],
“plugins”: [“transform-runtime”]
}(preset—语法,plugin–插件)

取消webpack的严格模式

cnpm i babel-plugin-transform-remove-strict-mode -D

通过babel-plugin-transform-remove-strict-mode来取消

在.babelrc中:
{
“plugins”: [“transform-remove-strict-mode”]
}

配置文件和发布配置文件

webpack.config.js
webpack.pub.config.js

“dev”: “webpack-dev-server --open --port 3000”,(测试)
“pub”: “webpack --config webpack.pub.config.js”(发布publish)

发布前自动删除dist目录借助clean-webpack-plugin插件

cnpm i [email protected] -D

plugins: [
new htmlWebpackPlugin({
template: path.join(__dirname, ‘./src/index.html’),
filename: ‘index.html’
}),
new cleanWebpackPlugin([‘dist’])
],(填写需要清除的文件夹)

分离第三方包

bundle.js中中存放自己的代码,第三方包的代码抽离出来
entry: {
app: path.join(__dirname, ‘./src/main.js’),
vendors: [‘jquery’]
(填写需要分离的第三方包名称)
},

new webpack.optimize.CommonsChunkPlugin({
name: ‘vendors’,
//分离的第三方包
filename: ‘vendors.js’
//第三方包打包后的名称
})

optimize(优化)

压缩js代码

new webpack.optimize.UglifyJsPlugin({
compress: {
压缩js选项
warnings: false
//移除警告
}
}),
new webpack.optimize.DedupePlugin({
‘process.env.NODE_ENV’: ‘“production”’
//生产环境
})

压缩HTML页面

参考:html-minifier-github
new htmlWebpackPlugin({
template: path.join(__dirname, ‘./src/index.html’),
filename: ‘index.html’,
minify: {
collapseWhitespace: true,
//清除多余的空格
removeComments: true,
//移除注释
removeAttributeQuotes: true
//移除属性上的双引号
}
}),

抽取css文件

cnpm i [email protected] -D
借助extract-text-webpack-plugin插件
参考网站:github.com/webpack-contrib/extract-text-webpack-plugin

{
test: /.css$/,
use: extractTextPlugin.extract({
fallback: ‘style-loader’,
use: ‘css-loader’,
publicPath: ‘…/’
(指定抽取css时,自动添加…/)
})
},

压缩css文件(抽取出来的css文件)

通过:cnpm i [email protected] -D

const optimizeCssAssetsPlugin = require(‘optimize-css-assets-webpack-plugin’);

new optimizeCssAssetsPlugin()

webpack相关项目文件复制问题

如果需要复制一个原有项目,不要复制node_modules,其他的都复制到新的项目文件夹,然后shift右键打开命令行窗口输入cnpm i即可,项目复制成功

React与vue的对比

组件化方面
1.什么是模块化:是从代码的角度来进行分析的;把-些可复用的代码,抽离为单个的模块;便于项目的维护和
开发;
2.什么是组件化:是从UI界面的角度来进行分析的;把一些可服用的UI元素,抽离为单独的组件;便于项目
的维护和开发;
3.组件化的好处:随着项目规模的增大,手里的组件越来越多;很方便就能把现有的组件,拼接为-个完墅的页
面;
4. Vue是如何实现组件化的:通过.vue 文件,来创建对应的组件;
。template结构
。script
行为
。style
样式
5. React如何实现组件化:大家注意,React中有组件化的概念,但是,并没有像vue这样的组件模板文件;
React中,一切都是以S来表现的:因此要学习React, JS要合格; ES6 和ES7 (async 和await)要会用:

XMind: ZEN - Trial Version

你可能感兴趣的:(前端,react,笔记,react.js,javascript,前端)