UNPKG

wiz-frameworks

Version:

wizlong react framework

462 lines (382 loc) 12.9 kB
# wiz-frameworks ## 目录 * [概述](#概述) * [安装](#安装) * [使用](#使用) * [许可证](#许可证) * [技术栈](#技术栈) * [框架提供的概念](#框架提供的概念) * [项目启动流程介绍](#启动流程介绍) * [框架提供的工具](#框架提供的工具) ## 概述 wiz-frameworks是wizlong的框架项目,封装了React项目的启动流程和一些框架工具。 ## 安装 npm install git+https://gitlab.wizlong.com/sgm/wiz-frameworks.git ## 使用 ```js import init from 'wiz-frameworks'; let app = init({ //路由参数 createRoutes, //静态模型 models:[login,systemMenu], //动态模型 appDevModels: appDevModels(), //本地设置 initLocalSetting: { env: require('./constants/constants_env'), files: require('./constants/constants_file'), urls: require('./constants/constants_url') }, //全局变量 initGlobal: { Storage:Storage, wizNotice:WizNotice }, //网络检查 networkCallback:(networkCallback)=>{ log.info('networkCallback:',networkCallback; }, //插件 use:[ createLoading(),v { onError: exception } ], //请求对象 request:{ ... }, //请求默认设置 requestConfig:{ ... }, //路由 router:{ ... }, //路由参数 createRoutes:{ ... }, //日志参数 recodeLog: true, recodeLogParams: { userLogKey: app_user_log_key, sysLogKey: app_sys_log_key, } }); export default app; ``` ## 许可证 [MIT](http://opensource.org/licenses/MIT) Copyright (c) 2018 - forever Naufal Rabbani ## 技术栈 * [React](https://react.docschina.org) * [ECMAScript 6](https://es6.ruanyifeng.com) * [Dva](https://dvajs.com) ## 框架提供的概念 * [数据模型](#数据模型) * [容器与组件](#容器与组件) ### 数据模型 ##### 1. 数据模型的概念 数据模型指的是[Dva](https://dvajs.com)中的[model](https://dvajs.com/guide/concepts.html#models)(Dva中包含了Redux,model是Dva对Redux流程简化的一种用法),简单来说,Redux是为了统一管理多样和复杂的state(指的是[React](https://react.docschina.org) 的state),使用Redux帮助我们处理数据流转的过程。model中处理了核心的三件事情:注册state,处理state,返回新的state。 ##### 2. 数据模型的定义 framework支持两种定义model的方式 *2.1 静态模型* 静态模型是Dva中model的使用方式,在项目启动时进行加载。 数据模型例子如下: ```js import { routerRedux } from '../../utils' import { requestUrl } from 'wiz-frameworks' export default { //标记model namespace: 'login', state: { loggedIn: false, message: '', user: {}, }, subscriptions: { setup({ history, dispatch }) { return history.listen((params) => { let { pathname } = params; if (pathname.indexOf('/sign/login') !== -1) { storage.removeStorage('user'); storage.removeStorage('token'); } }); } }, //处理state effects: { *login({ payload }, { call, put }) { if (network()) { const { code, msg, token, data } = yield call(requestUrl.post, constants.urls.kUrlLogin, payload); if (code == 0) { storage.setStorage('user', data); storage.setStorage('token', token) log.info('storage.getStorageInfo():',storage.getStorageInfo()) yield put({ type: 'loginSuccess', payload: data }); yield put(routerRedux.replace('/home')); } else { yield put({ type: 'loginError', payload: { message: msg } }); } } else { wizNotice.error('请求失败,当前网络不可用'); } }, *logout(_, { put }) { } }, //返回新的state reducers: { loginSuccess(state, { payload }) { return { ...state, loggedIn: true, message: '', user: payload }; }, loginError(state, { payload }) { let timeStamp = new Date().getTime(); return { ...state, loggedIn: false, message: payload.message, loginTimeStamp: timeStamp }; }, } }; ``` *2.2 动态模型* 动态模型是framework提供的快速配置model的方式,主要用于从接口获取数据。model可以在localDevModel.js中进行配置(也提供从接口中获取的方式) 动态模型配置方式如下: ```js let modelConfig = { businessName: 'testLogin',//业务名称 modelType: 'entity', action: { doLogin: {//action方法名 api: urls.kUrlLogin,//url是全局变量 methodType: 'POST',//接口的请求方式 params: ['password', 'username'],//接口需要传参 returnField: {}//返回值的获取 }, }, initData: {}//初始化state } ``` ##### 3. 数据模型的流程 在framework中,数据模型的使用分为三个步骤: *3.1 doAction作出获取数据的动作* ```js this.doAction({ path: 'testLogin/doLogin', payload: { key: 'test@Login', apiParams: { pageNum: 1, pageSize: 1 } }, }) ``` *3.2 从Redux的state中获取数据* ```js const mapStateToProps = (state, ownProps) => { const { testLogin } = state; //根据businessName 和 key 获取数据 const test = modelUtils.getModelEntity(testLogin, 'test@Login'); //获取loading的方式 const load = modelUtils.getLoadingState(state,'testLogin') //将数据放入容器的props return { testLogin: test, ...load }; }; ``` *3.3 通过propsAndStateOnChange监听实例属性的变化* ```js //对所需要的实例属性进行监听 propsAndStateOnChange = { testLogin: this._testLogin.bind(this) } //监听方法,入参与shouldComponentUpdate的相同 _testLogin(nextProps,nextState){ //do something } ``` ### 容器与组件 ##### 1. 组件的概念 [组件化](https://blog.csdn.net/jane617_min/article/details/79573019)是React中的重要概念,framework使用的是wiz-components封装的WizComponent(wiz-components中已介绍,此处不再赘述) ##### 2. 容器的概念 Dan(React的作者)认为可以把组件分为两类,一类是纯展示类(外貌协会的,只负责UI,更关心长成什么样),另一类是容器类(靠脑子的组织者,一般不直接包含UI,而是内部再包着 纯展示类或容器类组件,更关心怎么工作的)。至此,framework把页面称为容器,一个容器代表了页面上面的一个页面,组件组成了容器。所以WizContainer诞生了。 ######WizContainer做了什么? 1. WizContainer继承了WizComponent(当然,WizContainer也是组件,但是framework把它定义为容器) 2. 封装了生命周期的所有方法,在WizContainer中使用生命周期请在方法前加上```_```,例如```_componentDidMount``` >在JavaScript的变量名或函数名前加“_” 。 >在变量名或函数名前加下划线,一般表示“私有”。是约定俗成的开发规范,没有强制限制,类似于类名首字母大写。加下划线,还能有效防止重名。 3. 提供了Redux的dispatch的封装```doAction``` ```js this.doAction({ path: 'testLogin/doLogin', payload: { key: 'testLogin', apiParams: { username: 'mll', password: '123456' } }, }) ``` 4. 提供了路由工具```jumpPage``` ```js this.jumpPage('replace', '/sys', { name: 'mll', age: 18 }) ``` ## 启动流程介绍 启动流程的基础是参照dva的启动项目流程 ### dva应用的最简结构 ```js // 创建应用 const app = dva(); // 注册 Model app.model({ namespace: 'count', state: 0, reducers: { add(state) { return state + 1 }, }, effects: { *addAfter1Second(action, { call, put }) { yield call(delay, 1000); yield put({ type: 'add' }); }, }, }); // 注册视图 app.router(() => <ConnectedApp />); // 启动应用 app.start('#root'); ``` ### 框架启动流程 框架是通过framworks中的init()方法进行启动,启动流程中处理的内容如下: 1. [本地设置](#本地设置) 2. [全局变量](#全局变量) 3. [网络监控](#网络监控) 4. [加载数据模型](#加载数据模型) 5. [插件](#插件) 6. [请求](#请求) 7. [loading](#loading) 8. [记录日志](#记录日志) 9. [初始化路由](#初始化路由) 10. [初始化模版组件](#初始化模版组件) #### 本地设置 设置全局的constants内容,目前constants中存放了urls、env、file的内容。url存放接口调用地址,env存放系统的业务设置,file记录了文件地址 ##### 使用方式 ```js let logo = constants.file.sys_main_logo let loginUrl = constants.urls.kUrlLogin let htmlTitle = constants.env.app_html_title ``` #### 全局变量 全局变量是将常用的组件或者工具等放入global中,方便直接使用,目前框架默认存放了log、storage、wizNotice、network。 ##### 使用方式 ```js log.info('项目启动后,全局变量在任何地方都可以直接使用') wizNotice.error('请求失败,当前网络不可用') storage.setStorage('mll','mll so cool') if(network.getNetworkState()){ log.info('网络畅通!') }else{ log.info('断线了!') } ``` #### 网络监控 网络监控主要是监控网络连接状态,当网络连接状态变化时进行相关提醒 #### 加载数据模型 在framework启动时将动态模型和静态模型配置到dva中 #### 插件 插件指的是Dva配套的一些工具的使用,目前framework默认使用dva-loading(Dva的插件)和onError(framework提供) #### 请求 framework启动时设置了默认的请求对象,目的对请求的统一管理和简化请求的使用方式,目前使用的请求工具是[cmn-utils](http://npm.taobao.org/package/cmn-utils/v/0.1.1)的request #### loading framework启动时设置了默认的loading渲染工具 #### 记录日志 framwork主要记录用户行为日志和系统日志,主要记录在Storage,后续待实现上传服务器 *1. 系统日志* 目前系统日志记录了错误日志,当浏览器页面Error时记录。 *2. 用户行为日志* *2.1 路由日志* 当路由发生变化时记录的日志,通过监听路由路径实现。 *2.2 接口路由* 当请求发送时记录日志,通过记录用户doAction时的状态变化实现。 *2.3 操作路由* 当用户点击元素时记录日志,记录标记有两种: *2.3.1 页面元素中含有`data-wiz-log`标记* *2.3.2 init方法中传入需要监控的元素的标签,比如:`['button','a']`* #### 初始化路由 frameworks会在项目启动时初始化路由,并且简化了配置路由的方式,详细见rotue目录内index.js ```js const _routesConfig = [{ path: '/', title: '', indexRoute: '/home', component: MainLayout, childRoutes: [ { key: 'login', title: '登录', path: '/sign/login', component: Login }, { key: 'home', title: '首页', path: '/home', component: Home }, { key: '404', title: '页面没有找到', path: '', component: P404 }, ] }] ``` #### 初始化模版组件 ##### 1. 模版的概念 framework引入模版概念是想通过配置的方式完成前台的一些页面,模版的概念就是将一些组件可以通过配置的方式渲染出来。项目默认将wiz-components中的组件全部模版化了。 ##### 2. 模版的使用 不使用模版的页面: ```js import { WizRate } from 'wiz-components' class Test { render(){ return( <WizRate key = {'WizRate'} allowHalf = {true} defaultValue = {2.5} /> )} } ``` 使用模版的界面: ```js import { templateUtils } from 'wiz-frameworks' class Test { render(){ return templateUtils.getComponentByConfi([{ name: 'WizRate', params: { key: 'WizRate', allowHalf: true, defaultValue: 2.5 } }]) } } ``` ## 框架提供的工具 * [框架启动方法](#框架启动的方法) * [模版的概念与使用](#模版的概念与使用) * [WizContainer](#WizContainer) * [WizLayoutTemplate](#WizLayoutTemplate) * [WizReduxTemplate](#WizReduxTemplate) ### 框架启动方法 framework的```init()```中的启动流程提供了单独使用的方法,可以单独使用 ### 模版的概念与使用 [初始化模版组件](#初始化模版组件)内已描述,此处不再赘述 ### WizContainer [容器与组件](#容器与组件)内已描述,此处不再赘述 ### WizLayoutTemplate 通用布局模版组件,基于[Antd](https://ant.design/index-cn)的[Layout](https://ant.design/components/layout-cn/#header),实现配置化。用法详见sgm-lmsweb-react-demo的例子 ### WizReduxTemplate 通用获取数据模版组件,实现了通过配置即可以通过动态模型获取数据。用法详见sgm-lmsweb-react-demo的例子