前端主流开发框架,react,vue,angular三分天下各执己见,随意一点火星便能引起框架大战,可是框架选择主观性自己就很强,所以这里就不评说了,一较高下不是几句话说得清的,我我的比较喜欢react,也只是由于其余的我用的很少,也许只是先入为主那么简单。react带给咱们的颠覆我在这里就不班门弄斧了,大神们已经讲太多了。虽然react好用,不过始终是个基础框架,react最大的亮点在于它的状态管理,然鹅,使用原生react最大的不爽也是在于状态管理。使用原生react容易形成状态管理混乱的问题,为了解决这个问题,后来FB提出flux的思想,慢慢发展出redux,以及成熟的react-redux和mobx。我的认为react-redux很成熟很好用,有些缺点可是并不伤大雅,mobx以不一样的思路来解决这个问题,并且比react-redux更加小巧一点,也不错。不过,有时候成熟度越高,也就意味着限制越多,一些庞大的项目因为自己项目的复杂性,再引入react-redux却是很合适,可是当咱们的项目没有大到使用react-redux这些框架,一旦引入这类框架就会发现,我其实只想要让你管管个人状态,但你管的太宽了,全部的路径都给我规划完了,好比我在客厅,须要喊一声在卧室的老婆,我本来只是想喊一嗓子就行了,结果你也让我打个电话,杀鸡用牛刀我不反对,不过你这把刀太沉了,反而影响了个人效率这就不合适了吧。好吧,react-reudx&mobx,拜拜,咱们真的不合适。html
既然不合适,那咱们只能另觅新欢了,从react出发,或许咱们能够本身倒腾一个简单可用的状态管理框架呢。那么咱们来分析一下咱们最大的需求是什么呢,react原生状态管理最大的问题在哪呢?就是任意两个组件之间通讯的问题,我须要的是两个组件之间的通讯,是绝密的,不须要中间任何节点的感知。这固然有办法,利用事件机制嘛,好吧,咱们此次稍微不那么low一点,既然是react的套餐,那仍是要稍微要点血缘关系的。那究竟怎么搞?咱们先来整理一下思路,其实这个思路能够参考一下flux,redux的设计,咱们也须要一个中央数据中心store,对咱们的数据进行集中式管理,任意节点之间的通讯其实都是经过这个store进行的。那具体如何作,让咱们回归本质,react的通讯是如何体现的,是由某个节点发起的某个动做致使状态变化,而后该状态变化同步到UI的变化,因此归根结底,就是这个简单的公式,store->UI。任意节点状态的变化,映射到中央数据管理中心store,由store进行广播出去,这就是实现了最简单的中心化状态管理。举个简单的栗子来进行说明。前端
我定义了一个store,就是个管理state的对象,里面有个bindContext方法,每次装载组件的时候会把组件对象实例装入数组contexts,setState方法其实就是将每个组件分别调用一次setState。而后我定义了一个App组件,里面挂载Module1和Module2两个组件,Module2下挂载一个SubModule21的子组件。当我每次须要组件之间通讯,好比SubModule21中点击“清空Module1的值”按钮,这个就是SubModule21与Module1组件之间的通讯,其实Module1并无感知到是谁在对它进行操做,咱们更新的实际上是store中的数据状态,并由它统一下发到组件。代码以下:
index.html代码:vue
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>测试</title>
</head>
<body>
<div id="page-container"></div>
</body>
</html>复制代码
import React from 'react';
import ReactDOM from 'react-dom';
/**
* 统一状态管理对象
*/
let store = {
//目标组件对象
contexts: [],
//state数据
state: {
},
//注册绑定组件与状态数据,用于setState
bindContext(_context) {
this.contexts.push(_context);
return this.state;
},
setState(bs_state, context) {
this.contexts.map((item) => {
React.Component.prototype.setState.call(item, bs_state);
})
}
}
/**
* 入口组件
*/
class App extends React.Component {
constructor() {
super();
store.bindContext(this);
}
render() {
return ( < div >
< Module1 / >
< Module2 / >
< /div>
)
}
}
/**
* siblings1
*/
class Module1 extends React.Component {
constructor() {
super();
this.state = Object.assign({}, store.bindContext(this));
}
render() {
return ( < div >
< p > -- -- -- --Module1-- -- -- -- - < /p> < input type = "number"
value = {
this.state.m1Var
}
onChange = {
this.setValue
}
/> < /div>
)
}
setValue(e) {
console.log(e.target.value);
store.setState({
m1Var: e.target.value
})
}
}
/**
* siblings2
*/
class Module2 extends React.Component {
constructor() {
super();
this.state = Object.assign({}, store.bindContext(this));
}
render() {
return ( < div >
< p > -- -- -- -- - Module2-- -- -- -- - < /p>
兄弟节点Module1的值: {
this.state.m1Var
} < SubModule21 / >
< /div>
)
}
}
/**
* Module2的子组件
*/
class SubModule21 extends React.Component {
constructor() {
super();
this.state = Object.assign({}, store.bindContext(this));
}
render() {
return ( < div >
< p > -- -- -- - SubModule21-- -- -- -- < /p> < button onClick = {
this.clean
} > 清空Module1的值 < /button> < /div>
)
}
clean() {
store.setState({
m1Var: ""
})
}
}
ReactDOM.render( < App / > , document.getElementById("page-container"));复制代码
不知道并你们注意到没有,这个思路必定程度上是逆react开发的,由于即便是父子组件之间,实际上是没有经过props进行联系的,都是统一使用setState来进行数据的下发,几乎抛弃了props。彷佛是有点问题,可是细细想来实际上是没有问题的,由于react本来就是数据驱动的,setState和props只是不一样场景下传递数据的方式罢了,不一样的设计思路,只是方式就会有所区别。核心,仍是在于状态数据的变化。react
本篇只是将其中的核心思想进行简单的呈现,相信你们会发现这段代码存在不少的问题,很明显store对象存在部分逻辑问题,细细分析会发现一些亟需优化的点,而且大量存在bindContext这样的样板代码十分不优雅,不过这并不影响咱们呈现核心思想。固然只有核心思想仍是不够的,须要进行继续完善,最终的目的是完成一个简约却五脏俱全的框架。
好吧,此次高潮有点短暂。。。redux
或许这个算不上一个真正的框架,多是个非主流的玩意儿,但会让咱们在不须要redux或者mobx的时候多一种选择。优秀的框架有不少不少,但咱们不能一直只是当个使用者,咱们须要一同参与建设,即便最后出来的玩意可能只有咱们本身使用,这个思想或许没人认同,那又何妨,咱们知道咱们比创造出这玩意以前的咱们更加牛逼了。我会尽可能使用react原生提供的一些特性来完成,或许能够从中发现更多react中未曾关注到的点。我相信,技术,是须要多玩玩的。数组
欢迎拍砖!!!bash