博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[react-control-center tutorial 2] 动态配置模块
阅读量:6905 次
发布时间:2019-06-27

本文共 8456 字,大约阅读时间需要 28 分钟。

目录回顾


今天我们将通过此文告诉cc用户,除了startup,cc也提供configure来配置模块相关信息哦^_^

启动时配置模块

通过我们知道,可以在startup时将模块的storereducercomputedinit一次性配置好

如下例子,我们定义两个模块loginproduct,以及重写cc的内置模块$$global

  • login模块相关代码
// code in models/login/index.jsimport reducer from './reducer';import state from './state';import init from './init';export default {reducer, state, init}复制代码
// code in models/login/state.jsexport default {    loading:false,    onlineCount:0,    failReason:'',    uid:0,    username:'',    role:'',}复制代码
// code in models/login/reducer.jsimport api from 'service/user';function changeLoading(loading){    return {loading}}async function loginWithPassword({payload:{username,password}, dispatch}){    await dispatch('login/changeLoading', true);    // 等价于写  await dispatch({module:'login', type:'changeLoading', payload:true});    // 备注,如果这里确定来来自于login模块的组件实例调用的this.$$dispatch('updatePassword',{uid,password})    // 这里还可以简写为dispatch('changeLoading', true),因为此dispatch句柄默认是去改变的模块就是触发该updatePassword函数的$$dispatch调用实例所属的模块        const {success, message, data} = await api.loginWithPassword(username,password);    if(success){        const {uid, username, role, customizedBorderColor} = data;        //派发到$$global模块修改相应的状态        dispatch('$$global/changeBorderColor', customizedBorderColor);        return {loading:false, uid, username, role};    }else return {loading:false, failReason:message};}async function updatePassword({payload:{uid,password}, dispatch}){    await dispatch('login/changeLoading', true);    const {success, message, data} = await api.updatePassword(uid,password);    if(success) return {loading:true};    else return {loading:false, failReason:message};}export default {    changeLoading,    loginWithPassword,    updatePassword,}复制代码
//code in models/login/init.jsimport api from 'service/userApi';export default setState=>{    api.getOnlineCount().then(onlineCount=>{        setState({onlineCount});    });}复制代码
  • product模块相关代码
// code in models/product/index.jsimport reducer from './reducer';import state from './state';export default {reducer, state}复制代码
// code in models/product/state.jsexport default {    loading:false,    pageSize:10,    currentPage:0,    totalPage:0,    totalCount:0,    productList:[],}复制代码
// code in models/product/reducer.jsimport api from 'service/product';import cc from 'react-control-center';function changeLoading(loading){    return {loading}}async function _fetchProduct(currentPage, pageSize){    const {list:productList, totalCount} = await api.fetchProduct(currentPage, pageSize);    const totalPage = Math.ceil(totalCount/pageSize);    return {productList, totalCount, totalPage};}async function nextPage({dispatch, moduleState}){    await dispatch('changeLoading', true);    const {currentPage, pageSize} = moduleState;    const nextPage = currentPage+1;    const {productList, totalCount, totalPage} = await _fetchProduct(nextPage, pageSize);    return {loading:false, productList, totalCount, totalPage, currentPage:nextPage};}async function prevPage({dispatch, moduleState}){    await dispatch('changeLoading', true);    const {currentPage, pageSize} = moduleState;    const nextPage = currentPage-1;    const {productList, totalCount, totalPage} = await _fetchProduct(nextPage, pageSize);    return {loading:false, productList, totalCount, totalPage, currentPage:nextPage};}async function changePageSize({dispatch, moduleState, payload:pageSize}){    await dispatch('changeLoading', true);    const {currentPage} = moduleState;    const {productList, totalCount, totalPage} = await _fetchProduct(currentPage, pageSize);    return {loading:false, productList, totalCount, totalPage, pageSize};}async function refreshCurrentPage({dispatch, moduleState}){    await dispatch('changeLoading', true);    const {currentPage, pageSize} = moduleState;    const {productList, totalCount, totalPage} = await _fetchProduct(currentPage, pageSize);    return {loading:false, productList, totalCount, totalPage};}//上传统计用户的刷新行为,因为该函数不返回任何新的state,将不触发cc组件实例的渲染function uploadRefreshBehavior(){    const loginModuleState = cc.getState('login');    const {uid} = loginModuleState    api.uploadRefreshBehavior({uid, action:'refreshCurrentPage'});}//cc并不强制要求每一个reducer函数都返回一个新的片断state,该方法通过dispatch组合了另外两个reducer函数function refreshCurrentPageAndTrack({dispatch}){    dispatch('refreshCurrentPage');    dispatch('uploadRefreshBehavior');}export default {    changeLoading,    nextPage,    prevPage,    changePageSize,    refreshCurrentPage,    uploadRefreshBehavior,    refreshCurrentPageAndTrack,}复制代码
  • $$global模块相关代码
// code in models/global/index.jsimport reducer from './reducer';import state from './state';import computed from './computed';export default {reducer, state, computed}复制代码
// code in models/global/state.jsexport default {    customizedBorderColor:'#FFFFFF',}复制代码
// code in models/global/reducer.jsfunction changeBorderColor({payload:customizedBorderColor}){    return {customizedBorderColor};}复制代码
//code in models/global/computed.jsexport default {    customizedBorderColor(customizedBorderColor){        return `1px solid ${customizedBorderColor}`;    }}复制代码

将他们配置到cc的StartUpOption

// code in startup-cc.jsimport loginModel from 'models/login';import productModel from 'models/product';import globalModel from 'models/global';import cc from 'react-control-center';function myMiddle1(executionCotext, next){    console.log(executionCotext);    // here write your code    next();}function myMiddle2(executionCotext, next){    console.log(executionCotext);    // here write your code    next();}const models = [    {module:'login',model:loginModel},    {module:'product',model:productModel},    {module:'$$global',model:globalModel},];const store={}, reducer={}, init={}, computed={};models.forEach(item=>{    const {module, model:{state, reducer:_reducer, init:_init, computed:_computed}} = item;    if(state)store[module]=state;    if(_reducer)reducer[module]=_reducer;    if(_init)init[module]=_init;    if(_computed)computed[module]=_computed;});cc.startup({    isModuleMode:true,    store,    reducer,    init,    computed,    // 注意,此处配置了中间件函数,任何cc实例触发了改变state的行为,    // cc都会前调用中间件函数链然后才开始改变state, 为第三方编写插件预留了可操作入口,例如计划中的rcc-state-changging-logger    middlewares:[myMiddle1, myMiddle2]});复制代码

动态配置模块

cc同样支持在startup之后,通过cc.configure动态的添加新的模块(注意,此方法一定要在startup后调用哦),以上代码可以改造为

// code in startup-cc.jsimport cc from 'react-control-center';function myMiddle1(executionCotext, next){    console.log(executionCotext);    // here write your code    next();}function myMiddle2(executionCotext, next){    console.log(executionCotext);    // here write your code    next();}cc.startup({    isModuleMode:true,    middlewares:[myMiddle1, myMiddle2]});复制代码
// code in configure-cc.jsimport loginModel from 'models/login';import productModel from 'models/product';import globalModel from 'models/global';import cc from 'react-control-center';const models = [    {module:'login',model:loginModel},    {module:'product',model:productModel},    {module:'$$global',model:globalModel},];const store={}, reducer={}, init={}, computed={};models.forEach(item=>{    const {module, model:{state, reducer:_reducer, init:_init, computed:_computed}} = item;    const option = {};    if(_reducer)option.moduleReducer = _reducer;    if(_init)option.init=_init;    if(_computed)option.computed=_computed;    cc.configure(module, state, option);});复制代码
//code in App.jsimport 'startup-cc.js';//注意此处一定是先引入startup-cc.jsimport 'configure-cc.js';复制代码

cc.configure同样也可以不需要在一处文件里集中式的调用,这样方便用户按照自己的习惯和理解来组织代码

  • 此时用户的文件结构可能如下
|________components|     |________Login|     |     |________model|     |     |     |________state.js|     |     |     |________reducer.js|     |     |     |________init.js|     |     |     |________index.js|     |     |________index.js复制代码
  • components/Login/model/index.js里负责完成cc.configure的调用
import moduleReducer from './reducer';import state from './state';import init from './init';import cc from 'react-control-center';cc.configure('login', state, {moduleReducer, init});复制代码
  • components/Login/index.js里引用components/Login/model,触发cc动态加载login模块
// code in components/Login/index.jsimport React from 'react';import cc from 'react-control-center';import './model';@cc.register('Login',{module:'login', sharedStateKeys:'*'});export default class Login extends React.Component{    //......}复制代码

总结,cc弹性的设计cc.configure方便用户灵活和组织代码和配置模块,同时也方便用户开发自己的cc组件发布到npm,这样其他用户引用你的组件时,不需要勾出你的stateinitcomputed等属性配置在StartUpOption


附:

转载地址:http://mwmdl.baihongyu.com/

你可能感兴趣的文章
oracle中日期格式的转换
查看>>
CISCO路由器端口故障状态及解决
查看>>
同步传输与异步传输
查看>>
我的2014--新的开始,新的征程,加油!
查看>>
JS图片无缝、平滑滚动代码,多用于推广页面
查看>>
排序算法(一)
查看>>
使用jconsole监控tomcat性能情况
查看>>
ligerui grid行编辑示例
查看>>
linux安装或移植zencart系统
查看>>
动态权限
查看>>
MySQL 主从复制
查看>>
LayoutBuilder 构建一个窗口大小的widget树。 并可以获取widget 的狂宽高
查看>>
Python OpenCV学习笔记之:图像金字塔
查看>>
3月上旬中国数据域名总量跌至22.8万个 增长略有波动
查看>>
9月15日全球域名商(国际域名)解析量排行榜TOP20
查看>>
12月初全球域名商解析新增保有量15强:万网称王
查看>>
3月末全球域名商域名解析量23强:爱名网跌至第十七
查看>>
web报表开发FineReport教程之父子格设置
查看>>
无功功率补偿的方法
查看>>
Linux监控平台搭建(添加自定义监控项目、配置邮件告警、测试告警、不发邮件的问题处理)...
查看>>