背景:PC端的CRM系统第一阶段已经开发完毕.使用技术为:JS + AntDesignPro.如今开始开发企业微信.须要使用的技术为:TS + AntDesignMobile.由于公司以前有人开发过企业微信版,因此直接拉的别人搭好的架子.
开发以前,反复浏览TS的官网,AntDesignMobile的官网.html
与AntDesignPro目录是差很少的.简单说下.开发代码仍是在src下面的pages里面.assets里面放的通常都是图标.components里面都是本身封装的组件.layouts里面是鉴权.interceptors.ts文件里面是获取token的地方.umirc.ts里面是链接后端服务器地址的.开发服务器,测试服务器,生产服务器等.react
目录结构:ios
上代码:
services层:axios
import axios from 'axios'; /** * 首页列表 */ export async function listHome(data : any) { return axios.post(`/${process.env.APIPREFIX}/ticket/listHome`, data); }
model层:后端
import * as services from './service'; export default { namespace: 'home', effects: { // 首页列表 *listHome({ data, callback} : any, { put, call }: any) { const datas = yield call(services.listHome, data); yield put({ type: 'save', payload:{listHome : datas.data} , }); if (datas.code === '0000') { callback && callback(datas.data); } }, }, reducers: { save(state : any, { payload } : any) { return { ...state, ...payload, }; }, } }
index.tsx:服务器
/** * title: '昆药CRM' */ import React from 'react'; import { List } from 'antd-mobile'; import router from 'umi/router'; import styles from './index.less'; import { connect } from 'dva'; import IconBlock from './components/IconBlock'; import { Flex } from 'antd-mobile'; const Item = List.Item; const Brief = Item.Brief; const namespace = 'home'; const mapStateToProps = (state: any) => { const states = state[namespace]; return { ...states, }; }; const mapDispatchToProps = (dispatch: any) => ({ // 首页列表 listHome(data: any, callback: any) { dispatch({ type: `${namespace}/listHome`, data, callback, }); }, }); class Home extends React.Component { constructor(props: any) { super(props); this.state = { menu: [], order: { groupTitle: '订单相关查询', menuList: [], }, // 订单类 invoiceFinancial: { groupTitle: '回款相关查询', menuList: [], }, // 发票财务类 masterData: { groupTitle: '主数据查询', menuList: [], }, // 主数据类 }; } componentDidMount() { this.getList(); } // 获取首页图标 getList = () => { const { listHome }: any = this.props; listHome({}, (res: any) => { res.menus && res.menus.map((val: any) => { val.children.map((value: any) => { if (value.menuName === '订单类') { const { order }: any = this.state; this.setState( { order: { ...order, menuList: value.children, }, }, () => { const { order }: any = this.state; this.setState({ menu: [order] }); }, ); } if (value.menuName === '发票财务类') { const { invoiceFinancial }: any = this.state; this.setState( { invoiceFinancial: { ...invoiceFinancial, menuList: value.children, }, }, () => { const { menu, invoiceFinancial }: any = this.state; this.setState({ menu: [invoiceFinancial, ...menu] }); }, ); } if (value.menuName === '主数据类') { const { masterData }: any = this.state; this.setState( { masterData: { ...masterData, menuList: value.children, }, }, () => { const { menu, masterData }: any = this.state; this.setState({ menu: [masterData, ...menu] }); }, ); } }); }); }); }; // 跳转 jump = (path: any) => { const { menuList, dispatch }: any = this.props; let key: any = ''; let menuList1 = menuList.menuData.menuList; let query = (arr: any, index: number) => { if (arr.path === path) { key = index && index; } else if (arr.children.length > 0) { arr.children.map((i: any) => { query(i, index); }); } }; menuList1.map((item: any, index: number) => { query(item, index); }); dispatch && dispatch({ type: 'global/changeLayoutCollapsed', payload: false, }); localStorage.setItem('menuNav', key.toString()); router.push({ pathname: path, }); }; render() { const { menu }: any = this.state; return ( <div style={{marginBottom:50}}> <img src={require('../../assets/icons/banner.png')} style={{width:'100%',marginBottom:20}}/> {menu && menu.map((value: any) => ( <div key={value.groupTitle}> <span className={styles.section_title}>{value.groupTitle}</span> <Flex wrap="wrap"> {value.menuList.map((item: any, index: number) => ( <IconBlock key={index} titleName={item.menuName} iconPath={item.icon} method={() => this.jump(item.url)} /> ))} </Flex> </div> ))} </div> ); } } export default connect(mapStateToProps, mapDispatchToProps)(Home);
components-IconBlock.tsx:微信
import React from 'react'; import styles from './style.less'; interface IconBlockProps { titleName: string, iconPath: string, method: (e: React.MouseEvent) => void; } const IconBlock: React.FC<IconBlockProps> = ({ titleName, iconPath, method }) => { return ( <div className={styles.blockWrapper} onClick={method}> <div className={styles.icon}> <img src={iconPath}/> </div> <div className={styles.title}>{titleName}</div> </div> ) } export default IconBlock;
头部:
底部:antd
1:注入model层的时候,一直报错:.
实在是第一次用ts.真不会写..这个类型整死我了... 搞了几个小时...
换了好几种写法.. 最后才解决了...解决方法:把connect放在页面底部.export default connect(mapStateToProps, mapDispatchToProps)(Home);
2:ESlint 真的很严格.. 提交代码的时候.一直给我报错.. 一贯急躁的我处处看ts写法问题... 最后发现... 是个人标签前面多打了个空格... 我真的要被本身气死了....
3:页面样式问题.AntDesignMobile和AntDesignPro的组件仍是有不少不同的.好比AntDesignPro有的Row和Col,Text等等都没有了.. 这个写起来真的好不习惯..AntDesignMobile有Flex布局.可是这个API用起来和原生的区别真的不大.....
写代码几个小时后就容易疲劳.而后列表循环展现图标的时候.把Flex标签放循环里面了.样式就可想而知.一塌糊涂.. 这么浅显的BUG我居然仍是创造出来了... 写出来.警告本身.之后不可再犯.app