列出实际项目开发中的经验、技巧,还有曾经年少无知时一起挖过的坑...
欢迎大家来吐槽,推荐开发经验技巧。
后续不断更新...
目录(原谅简书中无法使用的目录跳转吧)
Exp1:节省时间之测试模式
时间就是金钱
实际项目开发中,我们需要一整套的开发测试模式,便于我们开发,开发模式/发布模式仅需要一个开关来控制,快捷高效。犹如之前做游戏一样,LOCAL_MODE
开启就变成单机游戏,关闭就成为网络游戏。
下面是我实际开发中的一部分
// 全局的配置表
var GlobalConfig = {
DEV_MODE: false, // true开发模式 false发布模式
SANDBOX_MODE: false, // 沙盒模式
TEST_MODE: true, // 测试模式,仅在【开发模式】下有效
TEST_VIEW: 'views.TestView', // 直接跳转的测试界面
TEST_VIEW_PARAMS: { // 测试界面的传入参数【手动模拟】
id: 100,
}
};
// 发布模式下强制关闭【沙盒模式】
GlobalConfig.SANDBOX_MODE = GlobalConfig.DEV_MODE ? GlobalConfig.SANDBOX_MODE : false
// 发布模式下强制关闭【测试模式】
GlobalConfig.TEST_MODE = GlobalConfig.DEV_MODE ? GlobalConfig.TEST_MODE : false
DEBUG_MODE 开发/发布
用来标志是开发模式还是发布模式的开关
SANDBOX_MODE 沙盒模式
实际项目中需要模拟填充一些数据。而这些数据在正式发布或者特定测试时又不需要。
例如:注册流程,需要注册手机号、账号、密码、姓名、身份证、住址等信息,这时候就可以用到沙盒模式了
需求:
- 每次填写注册信息麻烦,我们需要快速的测试整个注册流程
- 在【开发模式】下,我们有时候也需要手动填充一些数据测试,这时候需要关闭【沙盒模式】
- 测试数据保留,方便我们下次再次使用
- 测试数据在【发布模式】时要关掉,不能影响上线产品的数据
实际项目中,注册账号
中使用到的沙盒模式
this.state = {
account: '',
pwd: '',
pwdex: '',
};
if (config.SANDBOX_MODE) {
this.state.account = utils.sandboxAccount()
this.state.pwd = utils.sandboxPwd()
this.state.pwdex = this.state.pwd
}
TEST_MODE 快速测试模式
直接跳转到我们需要的界面,快速测试数据,而不需要每次都走通整个流程才到测试界面
TEST_MODE: true, // 测试模式,仅在【开发模式】下有效
TEST_VIEW: 'views.TestView', // 直接跳转的测试界面
TEST_VIEW_PARAMS: { // 测试界面的传入参数【手动模拟】
id: 100,
}
Exp2:继承的实际应用
实际开发中,会遇到多种界面,非常类似,如我们开发中的,通过电话号码查询、通过邮件查询、通过QQ号码查询,这些界面逻辑非常的相似,查询开始要转同样的菊花,查询结束要取消菊花,查询不到提示同样的信息等等。如果分开写,不仅逻辑复杂且不易维护,如果后期增加了N个同样的界面,维护成本就成倍的提升了。
解决方案:继承
和组件并不冲突,如都转菊花, 我们可以将菊花放到一个组件中统一维护,但是涉及到搜罗的逻辑,我们只能通过继承来实现。
基类
export default class SearchBase extends Component {
constructor(props) {
super(props);
}
componentWillMount() {
this.onInit()
}
onInit() { //overrite
// 初始化函数
}
onSendMsgSucceed(data) {
// do sth.. send msg succeed...
}
onSendMsgFailed() { //overrite
// do sth.. send msg failed...
}
onStartSearch(text) { // overrite
// 开始搜索
}
render() {
return (
<Text>test</Text>
);
}
}
派生类
export default class SearchPhone extends SearchBase {
// 初始化函数
onInit() {
super.onInit()
// SearchPhone init is here...
}
/**
* overrite
* 开始查询数据,派生类覆盖查询的消息
* @param text
*/
onStartSearch(text) { // overrite
let is_phone = utils.isPhone(text);
if (isPhone) {
ReqSearchInfoByPhone(text,
(succ)=> {
let data = succ[0]
this.onSendMsgSucceed(data)
}, (failed)=> {
this.onSendMsgFailed()
}
);
}
}
}
相同的逻辑,放到基类SearchBase中,需要覆盖的逻辑,重载基类中的函数并重新实现
注意:
- 派生类中的
constructor
中必须实现super(props)
,因为es6的class,是先构造基类的this,然后是派生类才能使用this - 正常使用应该是
let com = new SearchPhone()
com.init()
这样能先调用基类的构造函数,然后是派生类的构造函数,因为组件的调用是RN来控制的, 我们无法加入一个init函数,好在实在构造函数之后,且在渲染之前,我们所有将此函数作为一个初始化函数触发点
componentWillMount() {
this.onInit()
}