# react-division **Repository Path**: lingyunruo/react-division ## Basic Information - **Project Name**: react-division - **Description**: 拆分react状态逻辑页面 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2022-01-06 - **Last Updated**: 2022-09-13 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## 简介 > 用于组织react代码并分离数据模型,控制器模型,和页面模型。 ### 一、主要API - bindModel > 数据模型进行实例化, > > 使用: > > ```js > class Model1 { > data = { > name: 'abc', > pageInfo: { > current: 0 > } > } > } > > bindModel({ > m1: Model1 > }); > ``` > > - bindAction > 逻辑类进行实例化并关联 > > 使用: > > ```js > class Action1 { > toggle1 = () => { > const name = this.models.m1.get('name'); > > this.models.m1.set({ > name: 'bcd' > }); > } > } > > class Action2 { > toggle2 = () => { > this.models.m1.set({ > 'pageInfo.current': 1 > }); > this.actions.a1.toggle1(); > } > } > > class Action3 { > toggle = () => { > this.actions.a2.toggle2(); > this.actions.a1.toggle1(); > } > } > > bindAction({ > a1: Action1, > a2: Action2 > }) > ``` > > - render > 关联页面数据和逻辑, 只需要关联组件使用到的action和model就行了 > > 使用: > > ```js > render({ > actions: ['a1', 'a2'], > models: ['m1'] > })(class Home extends React.Component { > constructor(props) { > super(props) > } > > render() { > return ( >
> {this.props.m1.name} > >
> ); > } > }) > ``` ### 二、数据模型 通过class定义一个数据,并且通过bindModel,创建数据模型实例。class内有几个必须属性: | 名称 | 说明 || |-----|------| | data | 数据结构与初始化,定义数据结构和初始化最初数据 | 数据模型有几个默认方法: - set:参数为一个或者两个,并且修改会触发两个事件,一个是change事件,另一个是change:\[key\]事件,key为当前更新的属性名称 - 当参数是一个的时候,参数必须是一个对象,对象内为需要更新的数据和属性。且属性如果带‘.’或者'[]'符号,会递归数据找到需要更新的数据。例如 set({'a.b['c']': '9'}') - 当参数是两个的时候,第一个参数是更新的key,第二个参数是更新的值 - get:接受一个参数,参数可以是一个字符串和一个数组 - 参数为字符串的时候,参数作为属性名,返回该属性值,找不到值时返回null,如:get('a.c[0]') - 参数为数组的时候,数组作为属性名数组,返回与数组顺序相同的属性值 - getType:返回数据类型,通过Object.prototype.toString.call实现 - has:接受一个字符串作为参数,判断数据内该属性值,是否为undefined或者为null,是返回false,不是返回true - deepClone:接受最多一个对象作为参数,进行深拷贝,如果不传参数,则默认拷贝data属性,返回拷贝后的值 - previous:接受最多一个字符串作为参数,返回上一次修改的值,如果不传参数,会返回上一次修改的整个对象 - on: 接受两个参数,订阅事件,第一个参数为事件名称,第二个参数为回调函数 - off:取消订阅 - trigger:触发事件 model示例 ```js // ./demo/model.js export default class { data = { name: '姓名不重要' } } ``` action里调用model示例 ```js // ./demo/action.js export default class { changeName() { this.models.m1.set({ name: '明天在来' }); console.log(this.models.m1.get('name')); } } ``` 组件里使用model内定义的数据示例 ```js // ./demo/Home.js import React from 'react'; import {render, bindModel, bindAction} from '../src/frame'; import ChildPage from './Child'; import Action1 from './action'; bindAction({ action1: Action1 }); const Home = render({ actions: ['action1'], models: ['m1'] })((props) => { const {m1, action} = props; return (
{m1.name}
); }); export default Home ``` ### 三、控制器 通过class定义一个包含了逻辑处理方法的类,并通过bindAction方法,将控制器类实例化。 类默认的属性 - models:action通过这个属性调用数据模型的方法,models是个对象,存储的是所有创建的数据模型实例。 - actions:同组件引用的其他action,是个对象,属性为组件绑定action的时候指定的属性 - $instance:可以通过这个属性,拿到使用该类的所有组件实例 静态属性 - extends:接收一个数组,数组内是该类需要继承的其他父类,且父类也可以有extends属性,以实现多重继承 action示例 ```js // ./demo/action.js import Action3 from './action3'; export default class { static extends = [Action3] changeName() { this.models.m1.set({ name: '明天在来' }); } initData() { console.log(this.models); setTimeout(() => { this.changeName(); this.models.m1.testName(); this.showAbc(); this.showAbcde(); }, 6000); console.log(this.models.m1.get('name')); } } ``` ### 四、渲染API render函数,是将数据模型和控制器和页面关联起来的函数。render函数被调用两次,第一次调用传入配置参数。第二次调用传入一个组件,组件的props会传入action和绑定的model。 配置参数: - actions:数组,数组元素为调用bindAction时给定的名称 - models:数组,该组件需要用到的数据模型名称,注意在配置model之前需要确保它被bindModel调用过。 > 注意models在这里只跟组件绑定,与action无关,任意action都可以拿到所有的models。models内的元素可以是字符串和数组,如果是字符串,必须是定义的model名称,如果是数组,数组第一个元素是model名称,剩下元素是要依次要监听的字段,比如 [modelName, rowIndex, colKey] render方法示例 ```js // ./demo/Child.js import React from 'react'; import {render, bindModel, bindAction} from '../src/frame'; import Action2 from './action2'; import Model2 from './model2'; bindModel({ m2: Model2 }); bindAction({ a2: Action2 }); const Child = render({ actions: ['a2'], models: ['m2'] })(({props, state, action}) => { const {m2} = props; console.log(props); return (
{m2.childName}
); }); export default Child; ``` ### 五、完整示例 ```js import React from 'react'; import ReactDom from 'react-dom'; import {bindStore, bindAction, render} from '../index'; class ModelP { aaa = 0 } class Model extends ModelP { data = { name: '999' } } class ActionP { aaa = 0 } class Action { static extends = [ActionP] toggle = () => { } } bindStore({ m1: Model }); bindAction({ a1: Action }) class Home extends React.Component { constructor(props) { super(props); } componentDidMount() { setTimeout(() => { this.props.models.m1.set({ name: '888' }); }, 5000); } render() { const {m1} = this.props; return (
{m1.name}
); } } const Page = render({ actions: ['a1'], models: ['m1'] })(Home); ReactDom.render(, document.getElementById('root')); ```