本节主要是类库使用的案例
回顾生命周期三个阶段
我们先来回顾一下创建时期的5阶段
- getDefaultProps 设置组件的默认属性,返回一个对象;
- getInitialState 设置初始化状态,返回一个对象,保存组件默认状态,可以获取组件的属性,可以用属性设置状态;
- componetWillMount 组件即将被创建,属性和状态都已经而已经可以获取;
- render 渲染输出虚拟dom,这些元素还不能使用;
- componentDinMount 组件构建完成,这个阶段可以使用上一个阶段创建的虚拟dom元素;
this.props
this.state
this.setState
我们再来回顾一下更新时期(成长期)的5个阶段,组件每一次状态或属性的更新都会调用一遍这五个阶段的方法;
1、componentWillReceiveProps:表示组件将要接收新的属性有个参数:nextProps 表示新的属性在这个方法中,我们可以获取到组件更新的属性,这个方法只有当组件更新属性的时候才会被调用;状态更新不会被调用。
2、shouldComponentUpdate:表示判断组件是否应该更新,返回一个布尔值,true表示要对组件更新,false不要对组件更新,后面阶段就不会再执行;接收两个参数,第一个参数nextprops表示下一个属性,第二个参数nextstate表示下一个状态;如果return false,后面三个阶段方法就不再会执行;
3、componentWillUpdate:表示组件将要被更新,接收两个参数,第一个参数nextprops表示下一个新属性,第二个参数nextstate表示下一个新状态;
4、render:表示重新渲染组件,所以创建的五个阶段中render会调用多次的原因就在于这,更新的时候也会调用;输出一个dom树。
5、componentDidUpdate:表示组件已经被更新,接收两个参数,第一个参数表示原来的属性,第二个参数表示原来的状态;
最后我们回顾下组件的销毁时期
componentWillUnmount:组件在dom树中删除时执行;
==================================================================================
类库的使用
1. 我们有一个放大镜的类库,代码如下:
var Imagezoom = function(dom,url,width){
this.dom = dom;
this.url = url;
this.width = width;
//创建盒子元素和图片元素
this.imgDom = document.createElement('img')
this.divDom = document.createElement('div')
this.init()
}
Imagezoom.prototype={
init:function(){
var me = this;
this.loadImage(function(){
//图片加载成功后创建视图
me.creatView()
//为img绑定事件
me.bindEvent(me)
})
},
//图片加载后要创建视图,
loadImage:function(fn){
var me = this;
var img = new Image();
img.onload = function(){
me.zoom = img.width / me.width;//倍数
me.height = me.width * img.height /img.width;
me.imgWidth = img.width;
me.imgHeight = img.height;
fn()
}
img.src = this.url;
},
//创建放大器的视图
creatView:function(){
this.dom.className = 'img-zoom';
this.dom.style.width = this.width+'px';
//设置图片和盒子的宽度和高度
this.imgDom.style.width = this.width + 'px';
this.imgDom.style.height = this.height + 'px';
this.divDom.style.width = this.width + 'px';
this.divDom.style.height = this.height + 'px';
//设置图片
this.imgDom.src = this.url;
this.divDom.style.background ='url('+ this.url +')'
this.dom.appendChild(this.imgDom);
this.dom.appendChild(this.divDom);
},
bindEvent:function(me){
this.imgDom.onmousemove = function(e){
// console.log(e.x ,e.y)
var x = e.offsetX*me.zoom ;
var y = e.offsetY*me.zoom ;
// console.log(x ,y)
//边界,向左移动,大图坐标点x加上盒子的宽度divDom.width 要小于图片的宽度
if(x + me.width < me.imgWidth){
me.divDom.style.backgroundPositionX= -x+ 'px';
};
// console.log(y,me.height,me.imgHeight)
if(y + me.height < me.imgHeight){
me.divDom.style.backgroundPositionY= -y+ 'px';
}
}
}
}
2. 我们HTML上引用:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>使用非react类库</title>
<style>
*{
margin: 0;
padding: 0;
list-style: none;
}
.img-zoom{
position: relative;
}
.img-zoom div{
position: absolute;
top: 0;
left:100%;
}
</style>
</head>
<body>
<div id="app"></div>
<div id="app2"></div>
<script src="js/imagezoom.js"></script>
<script src="react.js"></script>
<script src="react-dom.js"></script>
<script src="js/23.js"></script>
<script >
// new Imagezoom(document.getElementById('app'),'3d.jpg',400)
// new Imagezoom(document.getElementById('app2'),'3d.jpg',400)
</script>
</body>
</html>
3. jsx代码如下:
//创建一个容器组件
var Main = React.createClass({
getInitialState:function(){
return {
url:'3d.jpg',
width:200
}
},
render:function(){
return (
<div>
<div className="imgzoom" ref="imgzoom"></div>
</div>
)
},
componentDidMount:function(){
//页面已经创建到可以实例化
new Imagezoom(this.refs.imgzoom,this.state.url,this.state.width)
}
})
ReactDOM.render(<Main/> ,document.getElementById('app'))
============================================================================
另一个案例
如果要用Jquery库:
html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>使用非react类库</title>
<style>
*{
margin: 0;
padding: 0;
list-style: none;
}
</style>
</head>
<body>
<div id="app"></div>
<script src="js/jquery.js"></script>
<script src="react.js"></script>
<script src="react-dom.js"></script>
<script src="js/24.jsx"></script>
</body>
</html>
jsx代码:
var NewsList = React.createClass({
getInitialState:function(){
return {
list:['特朗普新馆商人三把火','被怼了回去','特朗普不是强势政府']
}
},
getNewsList:function(){
return this.state.list.map(function(value,index){
return (<li key={index}>{value}</li>)
})
},
render:function(){
return(
<div>
<ul id="news_list">{this.getNewsList()}</ul>
</div>
)
},
//jq
componentDidMount:function(){
$('#news_list li').css('background','green');
var me = this;
//5秒后增加新的
setTimeout(function(){
me.setState({
list:me.state.list.concat(['法院起诉特朗普','特朗普却在度假','特朗普推特大骂澳大利亚'])
})
},5000)
},
componentDidUpdate:function(){
$('#news_list li').css('background','yellowgreen');
}
})
ReactDOM.render(< NewsList />,document.getElementById('app'))
我们会发现,componentDidMount这个阶段我们用jquery对背景颜色进行了更改,但是延迟5秒执行的新闻并不会有背景颜色,这是因为,创建的5个阶段只会执行一次,所以我们在更新的5个阶段的第五个阶段componentDidUpdate再次执行jquery代码;