一、關於命名
(1) 程式碼中命名均不能以下劃線或美元符號開始,也不能以下劃線或美元符號結束
[反例]_name / $Object / name_ / name$ / Object$
複製程式碼
(2)程式碼中命名嚴禁使用拼音與英文混合的方式,更不允許直接使用中文的方式
[反例]DaZhePromotion [打折] / getPingfenByName() [評分] / int 某變數 = 3
複製程式碼
(3)類名使用 UpperCamelCase 風格,必須遵從駝峰形式,第一個字母必須大寫
/**
*作者:郭翰林
* 時間:2018/8/3 0003 17:10
* 註釋:安心管分享頁面
*/
export default class AnXinSharePage extends PureComponent {
複製程式碼
(4)方法名、引數名、成員變數、區域性變數都統一使用 lowerCamelCase風格,必須遵從駝峰形式,第一個字母必須小寫
constructor(props) {
super(props);
this.isFromNative = this.props.navigation.state.params ? false : true;
this.params = this.props.navigation.state.params || this.props.screenProps;
this.state = {
/**
* 分數
*/
score: 200,
/**
* 百分比
*/
percent: "20%",
};
}
/**
* 作者:郭翰林
* 時間:2018/7/26 0026 16:40
* 註釋:繫結按鈕
*/
componentDidMount() {
this.props.navigation.setParams({onBack: this.onBack.bind(this)});
this.props.navigation.setParams({onShare: this.onShare.bind(this)});
}
複製程式碼
(5)常量命名全部大寫,單詞間用下劃線隔開,力求語義表達完整清楚,不要嫌名字長,記得加註釋便於後人理解
export const FamilyMemberKey = {
/**
* 關係
*/
RELATION: "relation",
/**
* 身份證號
*/
IDCARD: "idCard",
/**
* 姓名
*/
NAME: "name",
/**
* 性別
*/
SEX: "gender",
/**
* 地址
*/
ADDRESS: "address",
/**
* 生日
*/
BIRTHDAY: "birthday",
/**
* 英文名
*/
ENGNAME: "engName",
/**
* 手機號
*/
MOBILE: "mobile",
/**
* 身高
*/
HEIGHT: "height"
}
複製程式碼
(6)圖片命名、資料夾命名統一小寫
二、關於程式碼格式化
(1)IDE統一設定格式化規範,如下圖設定
(2)import 匯入,一個import獨佔一行import {Image, ImageBackground, NativeModules, ScrollView, StyleSheet, Text, View} from 'react-native';
import React, {PureComponent} from 'react';
import {StyleConfig} from "../../resources/style";
import {SafeAreaView} from "react-navigation";
import Button from 'react-native-button';
import {XAnimatedProgress} from '@xyz/react-native-xprogress';
複製程式碼
(3)外部樣式格式化,左括號必須強制換行,一個屬性獨佔一行,以強制換行右括號結尾
const styles = StyleSheet.create({
main: {
flex: 1,
},
messageStyle: {
marginTop: 65,
marginHorizontal: 43.5,
},
progressViewStyle: {
marginTop: 39,
alignItems: "center"
},
shareViewStyle: {
width: StyleConfig.screen_width,
marginTop: 67,
marginBottom: 37,
justifyContent: "center",
alignItems: "center"
},
});
複製程式碼
(4)少用行內樣式,如果是元件屬性則應換行展示
/**
* 作者:郭翰林
* 時間:2018/8/3 0003 12:15
* 註釋:繪製分數進度條
*/
renderProgressView() {
return (
<View style={styles.progressViewStyle}>
<XAnimatedProgress
style={{}}
fill={this.state.score}
rate={1500}
gradientStartColor="#ffffff"
gradientEndColor="#ffffff"
width={185}
height={220}
dashOffset={533}
innerPath="M88,188 C88,188 13,163 13,75.5 C13,13 25.5,13 88,13 C150.5,13 163,13 163,75.5 C163,163 88,188 88,188 Z"
progressWidth={15}
shadowOffset={0}
outerTransformOne="translate(-212.000000, -482.000000)"
outerTransformTwo="translate(212.000000, 482.000000)"
innerTransformOne="translate(-217.000000, -487.000000)"
innerTransformTwo="translate(212.000000, 482.000000)"
startTransparent={1}
endTransparent={0.2}
children={this.renderChildView}/>
</View>
);
}
複製程式碼
(5)提交程式碼之前必須格式化程式碼和刪除未使用的import
三、關於程式碼註釋
(1)類、類方法的註釋必須使用 Javadoc 規範,使用/***/格式,不得使用 //xxx 方式
/**
* 作者:郭翰林
* 時間:2018/8/3 0003 11:51
* 註釋:繪製頭部資訊和進度條
*/
renderHeaderView() {
let message;
if (this.state.score < 300) {
message = "近乎裸奔行走江湖的勇士,抵抗風險全靠精神意念。";
} else if (300 <= this.state.score && this.state.score < 550) {
message = "沒心沒肺沒煩惱,膽大心不細,全憑運氣好。";
} else if (550 <= this.state.score && this.state.score < 700) {
message = "徘徊在及格線邊緣的糾結症患者,完善保障要趁早哦。";
} else if (700 <= this.state.score && this.state.score < 800) {
message = "築起保障再去勇闖四方,像你這樣靠譜的人已經不多啦。";
} else {
message = "你就是傳說中那個能讓家人安全感爆棚,兼具責任與使命感的家庭守護衛士。";
}
return (
<View style={styles.messageStyle}>
<Text style={{fontSize: 24, color: StyleConfig.color_white, textAlign: "center"}}>{message}</Text>
{this.renderProgressView()}
</View>
);
}
複製程式碼
(2)所有的類都必須新增建立者資訊,以及類的說明
/**
* 作者:郭翰林
* 時間:2018/7/26 0026 8:48
* 註釋:更新家庭成員資料
*/
class UpdateFamilyMemberPage extends PureComponent {
複製程式碼
(3)方法內部單行註釋,在被註釋語句上方另起一行,使用//註釋
/**
* 作者:郭翰林
* 時間:2018/7/27 0027 20:11
* 註釋:獲取使用者資訊
* @returns {Promise<void>}
*/
async getUserInfo() {
this.userInfo = await UserBridge.getUser();
if (this.userInfo) {
//獲取性別
if (Platform.OS === "ios") {
const {gender} = this.userInfo;
this.setState({gender: gender});
} else {
const {linkman: {gender}} = this.userInfo;
this.setState({gender: gender});
}
//是否實名認證
const {authStatus} = this.userInfo;
this.setState({authStatus: authStatus});
}
}
複製程式碼
(4)JSX複雜頁面繪製應該抽出單獨元件,複雜邏輯應新增註釋標記
<ScrollView style={{flex: 1, backgroundColor: StyleConfig.color_background}}
contentContainerStyle={{paddingTop: 0, paddingBottom: 0}}
automaticallyAdjustContentInsets={false}
keyboardShouldPersistTaps="handled"
showsHorizontalScrollIndicator={false}
showsVerticalScrollIndicator={false}>
<View>
{/*個人資料*/}
<PersonalDataView
props={this.props}
isAdd={false}
isShowRelationship={this.state.insurantId ? true : false}
gender={this.state.gender}
authStatus={this.state.authStatus ? this.state.authStatus : -1}
/>
{/*生活習慣*/}
<LifeHabitView props={this.props}/>
{/*職業資訊*/}
<JobInfoView props={this.props}/>
{/*財務資訊*/}
<FinanceInfoView props={this.props}/>
<View style={{height: 44, alignItems: 'center', marginTop: 30}}>
<XLargeButton onPress={() => this.filterUpdate()}>儲存</XLargeButton>
</View>
<View style={{alignItems: 'center', marginTop: 30, marginBottom: 40}}>
<Text style={styles.textStyle}>個人資訊僅用於給你提供新一站服務時使用。</Text>
</View>
</View>
</ScrollView>
複製程式碼
import { View,StyleSheet,} from 'react-native';
import React, {PureComponent} from 'react';
import PropTypes from 'prop-types';
import ItemSectionView from "./ItemSectionView";
import Picker from '../../../components/views/picker/index';
import {XListItem} from '../../../components/antd/XList';
import {FamilyMemberKey,OftenDrinking,OftenDriving,OftenExercising,OftenSmoking} from "../constants/FamilyMemberConst";
/**
* 作者:郭翰林
* 時間:2018/7/26 0026 18:08
* 註釋:生活習慣頁面
*/
export default class LifeHabitView extends PureComponent {
static propTypes = {
props: PropTypes.any,
}
constructor(props) {
super(props);
this.state = {};
}
render() {
const {getFieldProps} = this.props.props.form;
return (
<View style={{flex:1}}>
<ItemSectionView sectionName={"生活習慣"}/>
{/*經常開車*/}
<Picker data={OftenDriving} cols={1}
title={"經常開車"}
{...getFieldProps(FamilyMemberKey.OFTENDRIVING, {
rules: [{required: true}],
})}
>
<XListItem arrow={"horizontal"}>經常開車</XListItem>
</Picker>
{/*經常運動*/}
<Picker data={OftenExercising} cols={1}
title={"經常運動"}
{...getFieldProps(FamilyMemberKey.OFTENEXERCISING, {
rules: [{required: true}],
})}
>
<XListItem arrow={"horizontal"}>經常運動</XListItem>
</Picker>
{/*經常吸菸*/}
<Picker data={OftenSmoking} cols={1}
title={"經常吸菸"}
{...getFieldProps(FamilyMemberKey.OFTENSMOKING, {
rules: [{required: true}],
})}
>
<XListItem arrow={"horizontal"}>經常吸菸</XListItem>
</Picker>
{/*經常飲酒*/}
<Picker data={OftenDrinking} cols={1}
title={"經常飲酒"}
{...getFieldProps(FamilyMemberKey.OFTENDRINKING, {
rules: [{required: true}],
})}
>
<XListItem arrow={"horizontal"}>經常飲酒</XListItem>
</Picker>
</View>
);
}
}
const styles = StyleSheet.create({
});
複製程式碼
(5)不允許殘留註釋程式碼,註釋掉的確認不用的程式碼應當刪除
(6)關於註釋模板,複製以下程式碼到IDE設定->Setting進行如下圖設定
註釋: $c$
* 時間: $a$ $b$
* @author XXX
複製程式碼
在需要使用的註釋的地方,使用快捷鍵調出註釋,然後回車,打c回車或者Tab。具體使用如果有不明白的地方,百度“IDE設定Live Templates”
四、關於程式碼編寫規範
(1)Props屬性一定要寫方法檢測
static propTypes = {
props: PropTypes.any,
isAdd: PropTypes.bool,
isShowRelationship: PropTypes.bool,
gender: PropTypes.number,
authStatus: PropTypes.number
}
複製程式碼
(2)如果元素內沒有子檢視,則標籤應該閉合
<LifeHabitView props={this.props}/> //正確
<LifeHabitView props={this.props}></LifeHabitView>//錯誤
複製程式碼
(3)內部變數使用let,常量不變值使用const,不要再使用var
//請求介面
const response = await AnXinServe.checkRepeatIdCard(params);
if (response) {
console.log("檢測家庭成員" + JSON.stringify(response));
if (response.msg) {
this.setState({errorMsg: response.msg.msg});
this.setState({modalErrorVisiable: true});
return;
}
if (response.familyMemberDTO) {
let {insurantId, loginId} = response.familyMemberDTO;
if (insurantId) {
this.forms = forms;
this.insurantId = insurantId;
this.setState({isLoading: false});
this.showCoverDialog();
return;
}
if (loginId) {
this.setState({isLoading: false});
this.showIsMeDialog();
return;
}
this.addMember(params);
} else {
this.addMember(params);
}
}
複製程式碼
(4)儘量採用解構賦值的寫法獲取引數,不要使用xxxx.xxx.xxx的方式獲取引數
let {insurantId, loginId} = response.familyMemberDTO;
複製程式碼
(5)關於一對多選值,不要採用if else和switch方式獲取,儘量採用預設Map,然後從Map中獲取的方式拿到想要的值。
_selectDefaultImage(rowData) {
const relation = rowData.relation;
const loginId = rowData.loginId;
if (rowData.gender == 1 && loginId) { //投保人是男
if (loginId) {
return defaultImage.husband;
} else {
if (relation == 1) {
return defaultImage.wife
}
if (relation == 2) {
return defaultImage.father
}
if (relation == 3) {
return defaultImage.mother
}
if (relation == 4 || relation == 6) {
return defaultImage.gonggong_yuefu
}
if (relation == 5 || relation == 7) {
return defaultImage.popo_yuemu
}
if (relation == 8) {
return defaultImage.boy_bady
}
if (relation == 9) {
return defaultImage.girl_baby
}
}
} else {
if (loginId) {
return defaultImage.wife;
} else {
if (relation == 1) {
return defaultImage.husband
}
if (relation == 2) {
return defaultImage.father
}
if (relation == 3) {
return defaultImage.mother
}
if (relation == 4 || relation == 6) {
return defaultImage.gonggong_yuefu
}
if (relation == 5 || relation == 7) {
return defaultImage.popo_yuemu
}
if (relation == 8) {
return defaultImage.boy_bady
}
if (relation == 9) {
return defaultImage.girl_baby
}
}
}
return defaultImage.husband;
}
複製程式碼
/**
* 作者:郭翰林
* 時間:2018/8/1 0001 9:49
* 註釋:設定頭像對應關係
*/
setHeaderImageMap() {
this.headerImageMap.set(0, require('../../resources/images/anXin/user_man.png'));
this.headerImageMap.set(1, require('../../resources/images/anXin/user_women.png'));
this.headerImageMap.set(2, require('../../resources/images/anXin/father.png'));
this.headerImageMap.set(3, require('../../resources/images/anXin/mother.png'));
this.headerImageMap.set(4, require('../../resources/images/anXin/gongong_or_yuefu.png'));
this.headerImageMap.set(5, require('../../resources/images/anXin/popo_or_yuemu.png'));
this.headerImageMap.set(6, require('../../resources/images/anXin/gongong_or_yuefu.png'));
this.headerImageMap.set(7, require('../../resources/images/anXin/popo_or_yuemu.png'));
this.headerImageMap.set(8, require('../../resources/images/anXin/boy_baby.png'));
this.headerImageMap.set(9, require('../../resources/images/anXin/girl_baby.png'));
this.headerImageMap.set(10, require('../../resources/images/anXin/anxin_car.png'));
this.headerImageMap.set(11, require('../../resources/images/anXin/anxin_house.png'));
this.headerImageMap.set(12, require('../../resources/images/anXin/anxin_cash.png'));
this.headerImageMap.set(-1, require('../../resources/images/anXin/anxin_add.png'));
}
/**
* 作者:郭翰林
* 時間:2018/8/2 0002 9:56
* 註釋:獲取顯示頭像
*/
getItemHeaderImg(dataItem) {
//是本人
if (dataItem.relation < 2 && dataItem.relation !== -1) {
if (dataItem.gender === 0) {
//女
return this.headerImageMap.get(1);
} else {
//男
return this.headerImageMap.get(0);
}
} else {
return this.headerImageMap.get(dataItem.relation);
}
}
複製程式碼
(6)關於陣列合並,不要採用for迴圈的方式合併,採用ES6推薦的方式合併陣列
/**
* 作者:郭翰林
* 時間:2018/7/31 0031 19:29
* 註釋:獲取家庭成員列表
* @returns {Promise<void>}
*/
async getUserLists() {
const params = {};
params.joinEvalution = 1;
params.loginId = await UserBridge.getLoginId();
this.setState({isLoading: true});
const response = await AnXinServe.familyMemberList(params);
console.log("第三方保單-獲取保障物件" + JSON.stringify(response));
this.setState({isLoading: false});
if (response) {
if (response.familyMemberDTOList) {
let defaultDatas = [
{relation: 10, name: "車輛"},
{relation: 11, name: "房屋"},
{relation: 12, name: "銀行卡"},
{relation: -1, name: "新增新成員"},
];
this.datas = [...response.familyMemberDTOList, ...defaultDatas];
this.setState({listData: this.transDatas(-1)});
}
}
}
複製程式碼
(7)判空使用!==null的形式去判空不要使用變數本身去判空,否則變數為0會引起BUG
async getUserInfo () {
this.userInfo = await UserBridge.getUser()
if (this.userInfo!==null) {
const {gender} = this.userInfo
if (gender) {
this.setState({gender: gender})
}
}
}
複製程式碼
(8)state變數應當事先在constructor()中宣告,不涉及頁面重新整理的變數不應寫入state中
constructor (props) {
super(props)
this.state = {
modalMeVisiable: false,
modalCoverVisiable: false,
modalErrorVisiable: false,
isLoading: false,
gender: 1,
errorMsg: '',
}
this.insurantId = ''
/**
* 表單資料
* @type {{}}
*/
this.forms = {}
this.joinEvalution = props.navigation.state.params.joinEvalution
}
複製程式碼
(9)儘量使用箭頭函式,不要使用this.XXXX.bind(this)的函式 普通函式中this物件的指向是可變的,但是在箭頭函式中,它是固定的
function foo() {
setTimeout(() => {
console.log('id:', this.id);
}, 100);
}
var id = 21;
foo.call({ id: 42 });
// id: 42
複製程式碼
箭頭函式可以讓this指向固定化,這種特性很有利於封裝回撥函式
var handler = {
id: '123456',
init: function() {
document.addEventListener('click',
event => this.doSomething(event.type), false);
},
doSomething: function(type) {
console.log('Handling ' + type + ' for ' + this.id);
}
};
複製程式碼
上面程式碼的init方法中,使用了箭頭函式,這導致這個箭頭函式裡面的this,總是指向handler物件。否則,回撥函式執行時,this.doSomething這 一行會報錯。 this指向的固定化,並不是因為箭頭函式內部有繫結this的機制,實際原因是箭頭函式根本沒有自己的this,導致內部的this就是外層程式碼塊 的this。正是因為它沒有this,所以也就不能用作建構函式。 (10)使用ES6的語法的匯出和匯入即export和import (11)關於常量定義不建議在常量類中書寫屬性方法,如果需要定義方法最好使用類引用Static函式的方式。
import { NativeModules, Platform, StatusBar } from 'react-native'
export default class Common {
static async getTopOfSafeArea () {
if (Platform.OS === 'ios') {
return await NativeModules.CommonUtilBridge.getTopOfSafeArea()
} else {
return StatusBar.currentHeight
}
}
static async getTopEdgeOfSafeArea () {
if (Platform.OS === 'ios') {
return await NativeModules.CommonUtilBridge.getTopEdgeOfSafeArea()
} else {
return StatusBar.currentHeight
}
}
static async getBottomOfSafeArea () {
if (Platform.OS === 'ios') {
return await NativeModules.CommonUtilBridge.getBottomOfSafeArea()
} else {
return 0
}
}
static async addPolicyToWallet (policyId, callback) {
if (Platform.OS === 'ios') {
await NativeModules.CommonUtilBridge.addPolicyToWallet(policyId, callback)
}
}
static async uploadPoilcy (file, callback) {
await NativeModules.CommonUtilBridge.uploadPolicy(file, callback)
}
}
複製程式碼