一、常用的几个目录:
config :配置文件
config.js :路由定义文件&&代理路径文件
defaultSettings.js :主题颜色以及标题配置文件
plugin.config.js :没怎么用过的配置文件
mock:mock数据文件,用于本地开发使用
public:静态图片资源
src :开发项目文件(主要在此目录下进行发)
assets :存放平台logo
components :全局组件文件夹
layouts :全局布局文件
locales:国际化文件
models :数据仓库,每个文件都需要一个命名空间 ,定义全局请求函数
pages:页面文件
service : 全局service 发起请求文件
utils :工具文件 其中会有自定义request.js
平时主要用4个文件:mock、page、models、services
二、module内容具体分析
在model中存在 namespace(命名空间,用来区分不同的页面之间的数据),state(该命名空间下的数据),effects(一些异步请求的api方法定义在这里),reducers(用来修改state的一些函数定义在reducers下)
文件包含以下几个模块(实际上都是javascript对象):
state => 数据构成
effects => 处理异步action,采用generator的相关概念,将异步转化成同步写法。
reducers => 处理同步action,相当于redux中的reducer函数,纯函数(即相同的输入得到相同的输出)
routes 业务组件,通常是需要连接数据仓库的组件。我们通过connect连接数据仓库之后可以通过this.props获取到数据和dispatch方法,并使用dispatch派发action来达到更新state(即更新数据仓库)的操作。
components 通用组件(纯组件),通常是一些复用性很强的组件,不需要连接数据仓库。通过props传递数据,父组件传递相同的props,会渲染相同的页面。不做任何业务上的处理。
services 所有的请求都写在这里,官方已经为我们封装了request方法,我们只需要传入参数即可。
三、整体的一个运行流程如下:
进入页面,在页面的componentDidMount钩子函数中调用model的effect中的方法,该方法调用service文件夹下的统一管理的请求函数。
获取到服务器返回值,在model的effect中拿到,并且调用model下的reducer,调用model的reducers对请求的数据进行处理,将model的state进行改变,页面自动进行渲染。
四、在工作中的例子
mock(一开始使用假数据模式)
1 let list = [],//所有数据 2 id = 123; 3 4 //初始化 5 for(let i =1,i<21;i++){ 6 const item = { 7 appId:"T"+(100+i), 8 appName:`应用${i}`, 9 status:(i % 3).toString() 10 }; 11 list.unshift(item); 12 } 13 const OK = { 14 domain:null, 15 type:"s", 16 code:"AAAAA" 17 }; 18 const createApplication = (req,res) =>{ 19 const newData = {...req.body.tAtpApplication,appId:"T" +id++}; 20 list.unshift(newData); 21 res.json:{ 22 reply:{ 23 returnCode:ok, 24 tAtpApplication:newData 25 } 26 }); 27 } 28 const deleteApplication = (req,res) =>{ 29 list.forEach((item,index)=>{ 30 if(item.appId == req.body.appId){ 31 list.splice(index,1) 32 } 33 }); 34 res.json:{ 35 reply:{ 36 returnCode:ok, 37 tAtpApplication:req.body 38 } 39 }); 40 } 41 . 42 . 43 . 44 export default { 45 "POST /api/queryApplicationList" :queryApplicationList, 46 "POST /api/createApplicationList" :createApplicationList, 47 "POST /api/deleteApplicationList" :deleteApplicationList, 48 }
module
1 import{ 2 queryApplicationList, 3 createApplication, 4 deleteApplication 5 } form "@/services/autotest/application"; 6 7 export default { 8 namespace:"autotestApplication", 9 state:{ 10 data:{} 11 } 12 } 13 14 effects:{ 15 *queryApplicationList({payload,callback},{call,put}){ 16 const response = yieId call (queryApplicationList,payload); 17 if (response.returnCode.type ==="s"){ 18 yieId put({ 19 type:"save", 20 data:response.tAtpApplication, 21 //data:response 22 }); 23 if (callback) callback(); 24 } 25 . 26 . 27 . 28 reducers:{ 29 save(state,action){ 30 return {...state,data:action.data || {} }; 31 }, 32 }
service
1 import request from "@/utils/request"; 2 3 export async function queryApplicationList(payload){ 4 return request("/api/queryApplicationList",{ 5 method:"POST", 6 data:payload 7 }): 8 } 9 export async function createApplicationList(payload){ 10 return request("/api/createApplicationList",{ 11 method:"POST", 12 data:payload 13 }): 14 } 15 export async function deleteApplicationList(payload){ 16 return request("/api/deleteApplicationList",{ 17 method:"POST", 18 data:payload 19 }): 20 }
pages
1 ...略 2 @connect (({autotestApplication}) =>({ 3 data:autotestApplication.data 4 })) 5 class Application extends Component { 6 constructor (props){ 7 super(props); 8 this.state = { 9 data:[] 10 } 11 } 12 } 13 14 componentDidMount(){ 15 this.queryAppList(this.state.param); 16 } 17 18 //删除应用 19 handleDelete = key =>{ 20 const {dispatch} = this.props; 21 dispatch({ 22 type:"autotestApplication/deleteApplication", 23 payload:{appId:key}, 24 callback:()=>{ 25 } 26 this.queryAppList 27 }