react
在react学习中,需要安装两个包react@16.1.1 react-dom@16.1.1
react这个包是专门用来创建react组件、组件生命周期等等
react-dom里面主要封装了和DOM操作相关的包
cnpm i react@15.6.2 react-dom@15.6.2 -S
reactjs
在react中,不能直接像vue中手写HTML元素
https://reactjs.org 概述:一个javascript库、构建用户界面的
核心库只关注视图层
简介
react起源于Facebook的内部项目(Instagram)
React的核心思想:组件化(封装组件,复用组件)
声明式语法-----只需要知道怎么使用即可,不需要知道内部如何实现的
、
learn once write anywhere
学完ReactJs之后,可以使用基于ReactJs语法的ReactNative去做Android/ios开发
- React简介
- 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 <div>
{this.state.cmts.map((item, i) => {
return <div key={i}>
(唯一的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(<h3>{item.user}</h3>);
});*/
return <div>
{this.state.cmts.map((item, i) => {
return <CommentItem key={i} user={item.user} content={item.content}></CommentItem>;或者
return <CommentItem key={i} {...item}></CommentItem>;
})}
</div>;
}
}
- 组件
无状态组件—没有生命周期函数
有状态组件----存在生命周期函数
- 无状态组件
没有this.state私有数据属性
function Hello(props) {
return props;
}
- 案例
import React from ‘react’;
export default function CommentItem(props) {
return <div style={{border: ‘1px solid #ccc’, margin: ‘10px 0’, paddingLeft: 15}}>
<h3 style={{color: ‘purple’, fontSize: 16}}>评论人:{props.user}
<p style={{color: ‘red’, fontSize: 14}}>评论内容:{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(
<div>
<MyHeader myTitle="hello"></MyHeader>
<MyHeader myTitle="welcome"></MyHeader>
</div>, document.querySelector('#app'));
- 单向数据流
- children属性
this.props.children
var myList = React.createClass({
render() {
return
- { React.Children.map(this.props.Children, (child) => {
return child;
}) } - ;
}
});
ReactDOM.render(
<div>
<myList>
<li>1</li>
<li>2</li>
</myList>
</div>, document.querySelector('#app'));
父子组件传递属性和方法
<MyButton btnName=“注册” myClick={ this.handleRegister }>
调用方法:
return <input type=“button” value={ this.props.btnName } onClick={ this.props.myClick } />;
- 子组件传参给父组件
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的使用
存在默认值,可修改、添加值
<h1 style={{ opacity: 0.5 }}>
todoslist
参考:http://todomvc.com/
Diff算法
tree diff
component diff
element diff
DOM diff都是交给React框架处理
JSX语法
能够让我们在js文件中书写类似于html那样的代码、快速定义虚拟DOM结构(符合XML规范的JS语法)
cnpm i babel-preset-react@6.24.1 -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 <div style={{border: ‘1px solid #ccc’, margin: ‘10px 0’, paddingLeft: ‘15px’}}>(外层{}表示要写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
<h3 style={{color: ‘purple’, fontSize: 16}}>评论人:{props.user}
<p style={{color: ‘red’, fontSize: 14}}>评论内容:{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 <div>
<h1>这是count计数器</h1>
<input type="button" value='+1'/>
<hr/>
<h3>当前的数量是:{this.props.initCount}</h3>
</div>;
}
}
- 使用propTypes做类型校验
1.需要安装prop-types第三方包
cnpm i prop-types@15.6.0 -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
<h5 style={{color: this.context.color}}>这是孙组件
;
}
static contextTypes = {
color: PropsTypes.string
}
react-router-dom路由的基本使用
https://reacttraining.com/react-router/ 参考网站:其中网站选择web、手机APP选择native
cnpm i react-router-dom@5.0.1 -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 <Router>
<div>
<h1>这是网站的APP根组件</h1>
<hr/>
<Link to="/home">首页</Link>
<Link to="/movie">电影</Link>
<Link to="/about">关于</Link>
<hr/>
<Switch>
<Route path="/home">
<Home></Home>
</Route>
<Route path="/movie">
<Movie></Movie>
</Route>
<Route path="/about">
<About></About>
</Route>
</Switch>
</div>
</Router>;
}
}
- 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 <HashRouter>
<div>
<h1>这是网站的APP根组件</h1>
<hr/>
<Link to="/home">首页</Link>
<Link to="/movie">电影</Link>
<Link to="/about">关于</Link>
<hr/>
<Route path="/home" component={Home}></Route>
<Route path="/movie" component={Movie}></Route>
<Route path="/about" component={About}></Route>
</div>
</HashRouter>;
}
}
- 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 <div>
Movie ------- {this.state.routeParams.type} --- {this.state.routeParams.id}
</div>;
}
}
- Switch组件使用
使用类似switch…case
- Link
表示一个路由的链接
属性:to
<Link to="/home">首页</Link>
UI框架—AntDesign
AntDesign组件------antd
参考网站:https://ant.design/index-cn
cnpm i antd@2.13.10 -S
- 一般,第三方UI插件,他们的样式表文件都是以.css结尾,建议对scss和less文件进行模块化
- 按需导入
1.cnpm i babel-plugin-import@1.6.2 -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’;
<Rate disabled defaultValue={this.props.rating.average / 2}> - 分页组件
import { Spin, Alert, Pagination } from ‘antd’;
<Pagination onChange={ this.pageChanged } defaultCurrent={this.state.nowPage} pageSize={this.state.pageSize} total={this.state.total}> - 返回按钮组件
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;
}
}
<img className="img" src={this.getImages(this.props.images.small)} alt=""/>
编程式导航
通过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开发
webpack@3.8.1 要打包的文件路径 打包好的输出文件路径
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 webpack-dev-server@2.9.3 -D安装
webpack-dev-server
cnpm i webpack@3.8.1 -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 style-loader@0.19.0 css-loader@0.28.7 -D(处理打包css文件)
import ‘./css/index.css’;
module: {
rules: [
{test: /.css$/, use: [‘style-loader’, ‘css-loader’]}(调用顺序从右至左)
]
}
cnpm i less-loader@0 -D第三方loader加载器
cnpm i less@1.5 -D
import ‘./css/index.less’;
{test: /.less$/, use: [‘style-loader’, ‘css-loader’, ‘less-loader’]}
cnpm i sass-loader@6.0.6 -D第三方loader加载器scss文件
npm i node-sass@4.6.0 -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 url-loader@0.6.2 file-loader@1.1.5 -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 babel-core@6.26.0 babel-loader@7.1.2 babel-plugin-transform-runtime@6.23.0 -D
2.第二套包:cnpm i babel-preset-env@1.6.1 babel-preset-stage-0@6.24.1 -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 clean-webpack-plugin@0.1.17 -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 extract-text-webpack-plugin@3.0.2 -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 optimize-css-assets-webpack-plugin@3.2.0 -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