redux和mobx都是react比较热门的状态管理工具,从个人操作来看,我觉得mobx相对更简单,单向数据流,业务逻辑比较清晰,现在来简单介绍一下.
MobX 的理念是通过观察者模式对数据做出追踪处理,在对可观察属性的作出变更或者引用的时候,触发其依赖的监听函数,在React中即是在 @observer 中对组件进行数据更新,监听,并渲染到视图层面.
简单原理来说:先通过 @observable设置可观察数据 (state),然后通过@observer这个观察者去订阅组件内的可观察数据,当通过@action对可观察数据修改的时候,@observer会马上对组件进行数据更新并渲染到视图层面.
@observable //可观察的数据 observable 的属性值在其变化的时候mobx会自动追踪并作出响应
@observer //观察者 订阅数据
@action //动作(Action) 执行修改State(observable) 的函数
可观察的属性值, 在他们改变的时候则会触发观察监听的函数
@computed // 计算属性 get和set可以用来控制computed的行为:
//get:基于state值,通过一些计算得到的新值并返回给调用者。
//set:get的相反运算,参数为一个值,由该值进行get函数中的反运算,得到对应的state值并赋予state。
cnpm i mobx ~~~~mobx-react -S //安装mobx
项目中新建一个mobx文件夹,然后新建shopcar.js
//引入mobx的主文件 并进行相关验证
import { observable, action, computed, } from "mobx";
import { axios } from "&"; //数据请求文件,我之前封装在项目utils里面了, &是别名设置
class Shopcar {
//显示购物车列表
@observable carList = [] //定义购物车的列表数据
//action执行动作 得到商品列表
@action getCarList = async (url) => {
const res = await axios.get(url);
this.carList = res.data.result;
}
//删除选中
@action delSelect=()=>{
axios.post("/react/delSelect").then(res=>{
this.carList=this.carList.filter(item=>!item.checked);
//将没有选中的商品过滤出来
})
}
//单选
@action changeOneChecked=(checked,goodsid)=>{
axios.post("/react/changeChecked",{
goodsid,
checked
}).then(res=>{
this.carList=this.carList.map((item)=>{
if(item.goodsid==goodsid){
item.checked=checked
}
return item; //每一个商品
})
})
}
//全选
@action changeQuan=(checked)=>{
axios.post("/react/changeChecked",{
checked
}).then(res=>{
this.quan=checked
})
}
//选中单个数量 包含加和减 利用flag的正负
@action changeOneCount=(goodsid,flag)=>{
axios.post("/react/changeCount",{
goodsid,
flag
}).then(res=>{
this.carList=this.carList.map((item)=>{
if(item.goodsid==goodsid){
item.count+=flag?1:-1;
}
return item; //每一个商品
})
})
}
//通过输入数值直接修改购物车里面的具体数值
@action changeOneCountNum=(goodsid,count)=>{
axios.post("/react/changeCount",{
goodsid,
count
}).then(res=>{
this.carList=this.carList.map((item)=>{
if(item.goodsid==goodsid){
item.count=count
}
return item; //具体修改多少就数据库有插入多少
})
})
}
//得到总数
@computed get carTotal() {
var carTotal = 0; //设置默认值
this.carList.forEach((item) => {
carTotal += item.count
})
return carTotal;
}
//得到购物车选中的数量数量
@computed get carNum() {
var carNum = 0;
this.carList.forEach((item) => {
if (item.checked) {
carNum += item.count
}
})
return carNum;
}
//得到选中的商品去订单页面
@computed get checkedGood(){
var checkedGood=[]
this.carList.forEach((item) => {
if (item.checked) {
// checkedGood += item
checkedGood.push(item);
}
});
return checkedGood
}
//得到总价 等于数量乘以价格
@computed get total() {
var total = 0;
this.carList.forEach((item) => {
if (item.checked) {
total += item.count * item.good.jiage
}
})
return total;
}
//全选事件
@computed get quan(){
var quan = true;
this.carList.forEach(item=>{
if(!item.checked){
quan = false;
}
})
return quan;
}
//监听并改变全选事件
set quan(newVal) {
this.carList = this.carList.map((item) => {
item.checked = newVal;
return item;
})
}
}
//底下以构造函数的方式暴露
export default new Shopcar();
view视图文件下渲染实现购物车shopcar/index.js
import shopcar from "~/mobx/shopcar"
import { observer } from "mobx-react";
import { success } from "&/axios"; //封装的axios拦截器
@observer
class Shopcar extends Component {
componentDidMount() {
//运用mobx得到购物车列表信息
shopcar.getCarList("/react/shopcar/showshoppingcar")
}
//自定义函数
//单选
checkOne = e => {
console.log(e); //可以拿到goodsid 和checked
shopcar.changeOneChecked(e.target.checked, e.target.goodsid)
}
//全选
checkAll = e => {
console.log(e);
console.log(e.target.checked);
shopcar.changeQuan(e.target.checked);
}
//加数量
add = (goodsid, count) => {
shopcar.changeOneCount(goodsid, true)
}
//减数量
reduce = (goodsid, count) => {
shopcar.changeOneCount(goodsid, false)
}
//改具体的数值 使用v避免与e同名
changeCount = (goodsid, v) => {
console.log(v.target.value);
if (v.target.value > 1) {
//字符串要转数字
shopcar.changeOneCountNum(goodsid, v.target.value * 1);
}
}
//删除选中
delSelect = () => {
shopcar.delSelect();
}
render() {
const {
carList,
carNum,
total,
quan,
checked,
checkedGood
} = shopcar
}
}
export default Shopcar
ok了.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。