一.三大设计模式:MVC MVP MVVC
MVC:
V:view 用户界面
C:Controller 控制器:业务逻辑
M:Model 模型:数据保存
MVC主要处理逻辑为:View触发事件,controller响应并处理逻辑,调用Model,Model处理完成后将数据发送给View,View更新。所有的通信都是单向
MVP:
V:view
P:Presenter
M :Model
MVP模型中,以Presenter为核心,负责从model获取数据,并填充到View中。该模型使得Model和View不再有联系,且View被称为“被动视图”,暴露出setter接口
V 和 P 是可以双向通信
P和M 是可以双向通信
V和M 不发生联系通过P,P相当于中间商
MVVM: react 和 vue 就是用的MVVM里面的V 因为它是虚拟DOM,anguler/ember采用的是MVVM模式
V:view
VM:viewMode
M:Mode
MVVM模型中,是以VM为核心,但是不同于MVP,MVVM采用了数据双向绑定的方案,替代了繁琐复杂的DOM操作。该模型中,View与VM保持同步,View绑定到VM的属性上,如果VM数据发生变化,通过数据绑定的方式,View会自动更新视图;VM同样也暴露出Model中的数据。
二.MPA和SPA(多页面和单页面)
vue和react是SPA应用
单页面只有一个入口
路由和页面构成映射关系去渲染页面
三.React核心思想:
React是封装组件,各个组件维护自己的状态和UI,当状态变更,自动更新渲染整个组件。
四.jsx:
jsx是js里面可以写html,HTML里面可以写js如:
var arr = [<h1>菜鸟教程</h1>,<h2>学的不仅是技术,更是梦想!</h2>];
ReactDOM.render( <div>{arr}</div>, document.getElementById('example') );
五.前端的组件化和模块化:
组件化侧重于UI层面
模块化侧重于功能开发
六.组件:
1.函数式组件:
无状态
直接定义函数的形式,不存在state,只会有props,它没有生命周期函数。
function Hello(){
return <h1> hello react </h1>
}
ReactDom.render(<Hello/>,document.getElementById('root'))
2.函数式无状态组件传值:props
这里函数里面的props是个形参 是个对象,可以写任意,只是为了语义化我们写props
function Hello(props){
return <h1> hello {prps.name}</h1>
}
ReactDom.render(<Hello name="react"/>,document.getElementById('root'))
3.类组件有状态组件:
使用class定义,extends继承React.Component,有state进行数据的存储和管理,
同时还可以拥有props,有生命周期函数。
<script type="text/babel">
class Hello extends React.Component {
//有状态组件必须使用render方法进行渲染,它是生命周期里面非常基础和底层的方法
render(){
return <h1> hello react </h1>
}
}
ReactDom.render(<Hello/>,document.getElementById('root'))
</script>
4.类组件传参:
1.props传参:类组件必须用this.props和函数组件里的必须使用形参不一样
<script type="text/babel">
class Hello extends React.Component {
render(){
return <h1> hello {this.props.name}</h1>
}
}
ReactDom.render(<Hello name="react"/>,document.getElementById('root'))
</script>
2.state 状态
script type="text/babel">
class Hello extends React.Component {
constructor(){
//super把属性传递给父级的构造对象
//子类必须在constructor构造器中调用super方法,从而得到父类的this对象,否则this是没有的就会报错
super()
this.state={
name:'react'
}
}
render(){
return <h1> hello {this.state.name}</h1>
}
}
ReactDom.render(<Hello/>,document.getElementById('root'))
</script>
3.state简写
script type="text/babel">
class Hello extends React.Component {
state={
name:'react'
}
render(){
return <h1> hello {this.state.name}</h1>
}
}
ReactDom.render(<Hello/>,document.getElementById('root'))
</script>
5.事件处理
script type="text/babel">
class Hello extends React.Component {
constructor(){
super()
this.state={
name:'react'
}
this.changeName=this.changeName.bind(this)
}
//如果使用函数的形式直接定义,要在constructor中绑定this 改变this指向
//要么就使用箭头函数changeName=()=>{}
changeName(){
this.setState({
age:'HaHa'
})
//React中为什么要用setState去修改状态?
//React没有实现类似于Vue2中Object.defineProperty或者vue3的proxy方式来监听数据的变化
//所以需要通过setState通知react改变状态,setState是继承自Component,当我们调用setState的时候会重新执行render方法
}
render(){
return <div>
<h1> hello {this.state.name}</h1>
<button onClick={this.changeName}>更改姓名</button>
</div>
}
}
ReactDom.render(<Hello/>,document.getElementById('root'))
</script>
6.事件处理简写
script type="text/babel">
class Hello extends React.Component {
state={
name:'react'
},
ChangeName(){
this.setState({
name:'33'
})
}
render(){
return <div>
<h1> hello {this.state.name}</h1>
<button onClick={this.changeName.bind(this)}>更改姓名</button>
//或者onClick={()=>this.changeName()}
</div>
}
}
ReactDom.render(<Hello/>,document.getElementById('root'))
</script>
7.函数组件和类组件混用
<script type="text/babel">
function Login(props){
return <button onClick={props.updated}>login</button>
}
function Logout(props){
return <button onClick={props.updated}>logout</button>
}
class App extends React.Component{
state={
isLogin:false
}
updateState=()=>{
this.setState({
isLogin:!this.state.isLogin
})
}
render(){
const {isLogin}=this.state
return <div>
isLogin ? <Login updated={this.updateState} /> :<Logout updated={this.updateState} />
</div>
}
}
ReactDom.render(<App/>,document.getElementById('root'))
</script>