代碼規(guī)范
案例
多選組件的實(shí)現(xiàn)
UI樣式
傳參
CommonSelector.propTypes = {
// 標(biāo)題
headerTitle: PropTypes.string,
// 是否展示全選
showSelectAll: PropTypes.bool,
// 是否需要展開收起
showExpandAndCollapse: PropTypes.bool,
sliceIndex: PropTypes.number,
// 選項(xiàng)列表
dataList: PropTypes.array,
// 已選列表
selectedList: PropTypes.array,
// 選項(xiàng)更改方法
onSelectChange: PropTypes.func
}
樣式
<View className="filter-item-wrap">
{showSelectAll && (
<Text
className={`filter-item ${selectedList.length === dataList.length ? 'chosen' : ''}`}
onClick={toggleSelectAll}>
全部
</Text>
)}
{!showExpandAndCollapse && (
<Block>
{dataList.map(item => {
return (
<Text
className={`filter-item ${selectedList.includes(item.value) ? 'chosen' : ''}`}
key={item.value}
onClick={(e) => {handleSelectChange(e)}}
data-value={item.value}
>
{item.label}
</Text>
)
})}
</Block>
)}
</View>
邏輯處理
// 點(diǎn)擊全部
function toggleSelectAll() {
let list = []
if (selectedList.length === dataList.length) {
list = []
} else {
list = dataList.map(item => item.value)
}
onSelectChange(list)
}
// 點(diǎn)擊子項(xiàng)
function handleSelectChange(e) {
const {value} = e.currentTarget.dataset
if (selectedList.includes(value)) {
selectedList = selectedList.filter(item => item !== value)
} else {
selectedList.push(value)
}
onSelectChange(selectedList)
}
外部使用
// 變量
purchaseIntentionList: [ // 潛力客戶選項(xiàng)
{ value: 'A1', label: 'A1' },
{ value: 'A2', label: 'A2' },
{ value: 'A3', label: 'A3' },
{ value: 'B1', label: 'B1' },
{ value: 'B2', label: 'B2' },
{ value: 'C', label: 'C' },
{ value: '', label: '未分類' }
],
chooseList: [] // 選擇的潛力標(biāo)簽
// change function
handlePotentialLabelSelect(selectedList) {
this.setState({
chooseList: selectedList
})
this.restartRequest()
}
// 組件傳值
{/* 潛力客戶篩選 */}
<CommonSelector
headerTitle="潛力客戶"
showExpandAndCollapse={true}
sliceIndex="3"
dataList={this.state.purchaseIntentionList}
selectedList={this.state.chooseList}
onSelectChange={this.handlePotentialLabelSelect.bind(this)}>
</CommonSelector>
思考:“全部”這個(gè)選項(xiàng)是否應(yīng)該作為選項(xiàng)由父組件傳入旅赢,還是直接放入子組件中钞楼,作為特殊處理蜈亩?
purchaseIntentionList: [
{ label: '全部', value: null },
...
]
樣式切換方式
常見場景:選中狀態(tài)與非選中狀態(tài)
1谅辣、使用模板字符串
<Text
className={`filter-item ${selectedList.length === dataList.length ? 'chosen' : ''}`}
onClick={toggleSelectAll}>
全部
</Text>
2修赞、使用classnames
<Button
className={classNames(
'save-button-item',
currentSelect ? '' : 'opacity-save-button'
)}
onClick={this.confirmTransferDealerOfEnquiry.bind(this)}
>
確定
</Button>
思考:是否可以使用模板字符串,或者有什么其他更好地方法?
插件的使用的取舍:自己封裝or直接用相關(guān)插件
案例:時(shí)間日期處理
日期方法
插件:moment.js
公共方法的拆分的維度
// 根據(jù)不同的版本設(shè)置不同的顏色
addSaasVersionColor() {
const { garageList } = this.state
if (garageList.length > 0) {
garageList.forEach(item => {
const color = saasVersionColorMap[item.packageType]
if (color) {
item.textColor = color.textColor
item.bgColor = color.bgColor
}
})
}
this.setState({
garageList
})
}
節(jié)點(diǎn)
<View
className="version-show"
style={{color: garage.textColor, background: garage.bgColor}}
>
{versionTypeMap[`${garage.buyFlag}-${garage.packageType}`]}
</View>
UI樣式
組件封裝的標(biāo)準(zhǔn)柏副?復(fù)用性的判定
state 的粒度問題
class components extends Components {
constructor(props) {
super(props)
this.state = {
// 省市區(qū)相關(guān)
areaState: {
districtCodes: [],
pageAreaData: [],
firstIndex: 0,
secondIndex: 0,
showArea: false
}
}
}
}
class components extends Components {
constructor(props) {
super(props)
this.state = {
// 省市區(qū)相關(guān)
districtCodes: [],
pageAreaData: [],
firstIndex: 0,
secondIndex: 0,
showArea: false
}
}
}
// 接收后端接口數(shù)據(jù)
class components extends Components {
constructor(props) {
super(props)
this.state = {
// 省市區(qū)相關(guān)
garageTotalCount: 0, // 數(shù)量
purchaseTotalAmount: 0, // 成交金額合計(jì)
purchaseCommissionTotalAmount: 0, // 抽傭合計(jì)
purchaseCommissionGrossTotalAmount: 0 // 抽傭毛利合計(jì)
}
}
}
async getGarageRanking() {
const {
pageNum,
pageSize
} = this.state
const requestData = this.formatRequestData()
const rankRes = await IncomeApi.getGaragePage(requestData, {pageNum, pageSize})
if (rankRes.success && rankRes.data) {
this.setState({
garageTotalCount: rankRes.data.totalCount || 0,
purchaseTotalAmount: rankRes.data.purchaseTotalAmount || 0,
purchaseCommissionTotalAmount: rankRes.data.purchaseCommissionTotalAmount || 0,
purchaseCommissionGrossTotalAmount: rankRes.data.purchaseCommissionGrossTotalAmount || 0
})
}
}
思考:是直接用一個(gè)data對(duì)象保存所有的數(shù)據(jù)勾邦,還是單獨(dú)保存每一項(xiàng)目
頁面數(shù)據(jù)默認(rèn)展示值的處理
<View className="purchase-info">
<View className="info-item">{ (dealer.purchaseCount || 0) + '單'}</View>
<View className="line"></View>
<View className="info-item">¥{dealer.purchaseTotalAmount || 0}</View>
<View className="line"></View>
<View className="info-item">¥{(dealer.purchaseCommissionTotalAmount || 0 )}</View>
</View>
長函數(shù)
// 處理配件展示數(shù)據(jù)
handleQuotationDetail(quotationDetail) {
if(quotationDetail.oldApp==='1'){
//oldApp=1證明是老版本app,需要移除掉serviceQuotationProductGroupList
delete quotationDetail["serviceQuotationProductGroupList"]
}
if (
quotationDetail.serviceQuotationProductGroupList &&
quotationDetail.serviceQuotationProductGroupList.length > 0
) {
let partListFormat = [];
for (
let index = 0;
index < quotationDetail.serviceQuotationProductGroupList.length;
index++
) {
const element = quotationDetail.serviceQuotationProductGroupList[index];
if (element.productList.length == 1) {
let item = element.productList[0];
partListFormat.push({
...item,
productList: element.productList
});
} else {
let recommendPart =null
if(element.showTips){
recommendPart=element.productList.find(ele => ele.selectType) || null;
}else{
recommendPart=element.productList.find(ele => ele.recommendType) || null;
}
if(element.showTips){
recommendPart.showTips=element.showTips
}
partListFormat.push({
...recommendPart,
productList: element.productList
});
}
}
quotationDetail.serviceQuotationProductList = partListFormat;
//是否擁有不同品質(zhì)配件
quotationDetail.haveDifferentQualitiesPart = quotationDetail.serviceQuotationProductList.some(
ele => ele.productList.length > 1
);
}
//設(shè)置了滿減優(yōu)惠 滿足門檻將discountsUseAmount復(fù)制為discountsAmount
quotationDetail.discountsAmount = this.calculateDiscount(quotationDetail);
return quotationDetail;
}