DvaJS的model属性
namespace
namespace为model 的命名空间,同时也是他在全局 state 上的属性,只能用字符串,不支持通过 .
的方式创建多层命名空间
// model/test.js
const TestModel = {namespace: "test"
};
export default TestModel// pages/test/test.js
import { connect } from 'dva';export default
@connect()
class Test extends React.Component {componentDidMount() {const { dispatch } = this.propsdispatch({type: 'test/**'}/*** 这里的type: 'test/**' test就是我们在namespace中设置的model命名* test/** "/"后为effects中的方法*/}
}
state
state属性 model中用于数据存储
// model/test.js
const TestModel = {namespace: "test",state: {data: [1, 2, 3],str: 'model-state'}
};
export default TestModel// pages/test/test.js
import { connect } from 'dva';
/*** connect(({ test }) => ({}))* 通过connect建立namespace名为test的model与当前组件的链接* 并读取model中的state与当前组件的props进行绑定*/
export default
@connect(({ test }) => ({data: test.data,str: test.str
}))
class Test extends React.Component {componentDidMount() {const { data, str } = this.propsconsole.log(data, str) // [1, 2, 3] 'model-state'}
}
effects
effects用于处理异步操作和业务逻辑,不能直接修改state,由action触发,可以触发action,可以和服务器进行交互,可以获取全局state的数据
effects 有三种属性 put, call, select
put
put 用于触发action
// model/test.js
const TestModel = {namespace: "test",state: {data: [1, 2, 3]},effects: {* fetch({ payload }, { put }) {yield put({type: 'setData'})// [1, 2, 3]},* update({ payload }, { put }) {yield put({type: 'fetch'})// [1, 2, 3]}/*** yield put() 触发action 可以调用reducers和effects中的方法*/},reducers: {setData(state, { payload }) {console.log(payload)return {...state,data: payload}}}
};
export default TestModel
call
call 用于调用异步逻辑,支持promise
// model/test.js
import { queryList } from '@/services/test';
const TestModel = {namespace: "test",state: {},effects: {* fetch({ payload }, { call }) {const data = yield call(queryList, payload)console.log(data) // data为queryList请求的返回结果/*** yield call() * 第一个参数为异步操作请求函数* 第二个参数为函数所传递的值*/}}
};
export default TestModel
select
select 用于从state获取数据
// model/test.js
const TestModel = {namespace: "test",state: {data: [1, 2, 3]},effects: {* fetch({ payload }, { select }) {const data = yield select(state => state.test.data)console.log(data) // [1, 2, 3]}/*** 通过select 获取state中的数据, test为namespace名*/}
};
export default TestModel
put与put.resolve
yield put直接调用reducers,堵塞 => 同步
yield put调用非reducers,非堵塞 => 异步
yield put.resolve调用,堵塞 => 同步
export default const TestModel = {effects: {* asyncInitData({ payload }, { put }) {yield put({type: 'initData',payload: payload})},// 使用yield put 调用reducers* reducersBtn(_, { put }) {console.log('1')yield put({type: "initData",payload: '2'})console.log('3')// 打印结果为 1, 2, 3},// 使用yield put 调用effects* button(_, { put }) {console.log('1')yield put({ type: 'asyncInitData',payload: '2'})console.log('3')// 打印结果为 1, 3, 2},// 使用yield put.resolve 调用effects* resolveBtn(_, { put }) {console.log('1')yield put.resolve({ type: 'asyncInitData',payload: '2'})console.log('3')// 打印结果为 1, 2, 3}},reducers: {initData(state, { payload }) {console.log(payload)return {...state,...payload}}}
}
callback和Promise
在effects中定义用于处理异步操作和业务逻辑的方法,我们可以通过callback或者promise获取一个返回值
(state的值无法即使更新时可以使用)
callback
// model.js
export default const TestModel = {namespace: 'test',effects: {* query({ payload, callback }, { call }) {const response = yield call(query, payload)if (callback) callback(response)}}
}
// test.jsx
import React, { useEffect } from 'react';const Test = (props) => {useEffect(() => {dispatch({type: 'test/query',callback: (res) => {console.log(res)}}).then(res => {console.log('queryCbd-res: ', res)})})
}
**
Promise
effects中的方法会return 返回一个Promise对象
// model.jsexport default { namespace: 'test', effects: { * query({ payload }, { call }) { const response = yield call(query, payload) return new Promise(function(resolve, reject){ if (response.code == 200) { resolve(response.data) } reject(response) }) // 或者写成return response effects会return一个proimse对象 //return response } },}
// test.jsximport React, { useEffect } from 'react';const Test = (props) => { useEffect(() => { dispatch({ type: 'test/query' }).then(res => { console.log('test/query: ', res) }) })}
reducers
reducers 用于处理同步操作,唯一可以修改state的地方,有action触发
// model/test.jsconst TestModel = { namespace: "test", state: { data: [1, 2, 3] }, effects: { * fetch(_, { put, select }) { const data = yield select(state => state.test.data) yield put({ type: 'setData', payload: data }) const newData = yield select(state => state.test.data) console.log(newData) // [2, 4, 6] } }, reducers: { // 在reducers中进行一些数据的修改, 并返回更新state中的数据 setData(state, { payload }) { return { ...state, data: payload.map(item => item * 2) } }, /** setData(state, action) { const { payload } = action return { ...state, data: payload.map(item => item * 2) } } */ }};export default TestModel
同时我们在页面也可以通过dispatch对触发reducers去修改state中得数据源
import React, { useEffect } from 'react';const Test = (props) => { useEffect(() => { dispatch({ type: 'test/setData', payload: [2, 4, 6] }) })}
subscriptions
subscription 是订阅,用于订阅一个数据源,根据需要dispath相应的action,在app.start()时被执行
数据源可以是当前的时间,服务器的websocket链接,keyboard输入(鼠标,键盘),geolocation变化,history路由变化等
// model/test.jsimport key from 'keymaster'; // Keymaster是一个简单的微型库,用于在Web应用程序中定义和分发键盘快捷键const TestModel = { namespace: "test", state: {}, effects: {}, reducers: {}, subscriptions: { /** * 这里的setup方法可以随便命名, * 当监听有变化时就会依次执行 * dispatch和history 如文档中一样 * dispatch 可以调用effects与reducers中的方法 * history 获取当前路由的信息 */ setup({ dispatch, history }) { // 监听当前浏览器的页面大小变化, 页面发生改变时就会触发dispatch方法 window.onresize = (e) => { // dispatch({ type: 'effects'}) console.log(e) } }, keyboard({ dispatch }) { // 监听当鼠标在页面中点击时触发 document.addEventListener('click',() => { console.log('鼠标点击时触发') }) }, keyEvent({ dispatch }) { // 监听ctrl + up键点击时触发 key('ctrl+up', () => { console.log('ctrl+up') }) }, watchHistory({ dispatch, history }){ // 获取当前页面的所有路由信息 history.listen((location) => { console.log(location) }) } }};export default TestModel
connect 与 @connect
connect 的作用是将组件和models结合在一起,将models中的state数据绑定到组件的props中,并提供一些额外的功能,如dispatch
connect 方法返回的也是一个react组件
connect 方法传入的第一个参数是 mapStateToProps 函数,该函数需要返回一个对象,用于建立 State 到 Props 的映射关系
connect 接收一个函数,返回一个函数
connect()()
export default connect(({ user, login, global = {} }) => ({ userInfo: user.userInfo, login: login.userLogin, notices: global.notices}))(BasicLayout);// BasicLayout 为组件 class BasicLayout extends React.Component {}
@connect
@connect 为ES7中的语法( @Decorator 装饰器 )
@方法名 可以对一些对象进行装饰包装然后返回一个被包装过的对象,可以装饰的对象包括:类,属性,方法等
export default@connect(({ user, login, global = {} }) => ({ userInfo: user.userInfo, login: login.userLogin, notices: global.notices}))class BasicLayout extends React.Component {}
DvaJS的model属性相关推荐
- 用一个类根据Model属性生成SQL语句
想到写这个的原因是我和我的一个朋友在写一个开源项目的时候,我负责了数据库的持久化存储部分,结果他看到了我的数据库数据存储结构之后直接傻眼了,因为个人比较简单粗暴,直接把一个数据Model归档成为二进制 ...
- laravel 5.1 Model 属性详解
<?phpnamespace Illuminate\Database\Eloquent;/*** 下面提到某些词的含义:* 1.覆盖: 在继承该类 \Illuminate\Database\El ...
- html model 属性值,如何将Model属性编辑为HTML
我为果园创建了模块 . 我有以下型号: public class SliderPart : ContentPart { [Required] public string Slide1 { get { ...
- runtime 任意类型 model 数据库方便存储
//这里边直接上代码 之后我在慢慢地讲解 之后我的QQ:378254160 我有DEMO 方便你们的使用联系我备注 runtime+数据库+任意model类型 当然有时候也是有局限的 //Data ...
- ASP.NET MVC基于标注特性的Model验证:DataAnnotationsModelValidator
对于ASP.NET MVC基于标注特性的Model验证,很多人只知道应用在数据类型及其属性上用于定义验证规则和错误消息的ValidationAttribute.通过<ASP.NET MVC以Mo ...
- 我眼中的Linux设备树(三 属性)
三 属性(property) device_type = "memory"就是一个属性,等号前边是属性,后边是值.节点是一个逻辑上相对独立的实体,属性是用来描述节点特性的,根据需要 ...
- (四) View/Model 全解(mvc)
转自:http://www.cnblogs.com/zhangziqiu/archive/2009/03/18/Aspnet-MVC-4.html 一.摘要 本文讲解在Action中向View传递Mo ...
- echarts树状图点击展开子节点_CPU眼里的结构设备树节点及属性详解
1 设备树(device tree)简介DTSpec定义一个devicetree的约束来描述硬件设备,boot引导程序将设备树传递给用户程序的内存空间中,并传递给用户相应设备树的指针.设备树为一个树形 ...
- 2.Knockout.Js(监控属性Observables)
前言 1.创建一个ViewModel <script type="text/javascript">//1.创建一个ViewModelvar myViewModel = ...
最新文章
- PHP无限分类-PHP100代码篇
- 00069_DateFormate
- 微服务架构的核心要点和实现原理
- 从零开始实现 ASP.NET Core MVC 的插件式开发(九) - 如何启用预编译视图
- .NET Core 学习资料精选:进阶
- 高效率的全组合算法(Java版实现)
- 好文分享—— RNN基本原理以及基于Pytorch实践
- 第十六周助教心得体会
- xp系统打开internet服务器,xp系统浏览器无法打开internet选项的解决方案
- 直击人心的数据可视化设计作品
- 计算机辅助设计论文结论,计算机辅助设计在平面设计中存在的问题论文
- 一带一红网红基地推出O2O网红直播过年模式
- 《卡耐基三部曲》(Yanlz+VR云游戏+Unity+SteamVR+云技术+5G+AI+人性的弱点+人性的优点+语言的突破+术业有专攻+世界观+人生观+价值观+志同道合+不卑不亢+立钻哥哥++==)
- 买零食 HihoCoder - 1272
- WebForm(二)——控件和数据库连接方式
- Trans论文的发表流程(George E.Ponchak)
- 分枝限界法求解流水线作业调度问题
- 面向 C++ 的测试驱动开发
- 监测京东商品价格波动
- Python基础教程:基本数据类型之布尔类型(Boolean)