项目场景
将后端通过接口传递过来的二级商品数据,以taro-ui为框架,利于Picker组件,实现二级联动。
以taro-ui为框架,利于AtDrawer、AtIndexes组件,实现城市字母索引器
taro-ui官方文档🔗
效果如下⬇️
1. 商品二级联动
2. 城市字母索引表(包含热门城市)
具体实现:
1. 前期数据准备
⭕️ 调用商品接口得到的数据是一个二维数组对象。
⭕️ cityData为城市及热门城市json文件
tips:如需文件,则直接点击👉city.json
2.完整代码实现
tips:该部分代码为当前申请表单的完整实现 。
- SubForm.js
import Taro, { Component, getWifiList, useEffect, useState } from '@tarojs/taro';
import { View, Image, ScrollView,Picker} from '@tarojs/components';
import { connect } from '@tarojs/redux'
import { AtForm, AtInput,AtDrawer, AtButton,AtList, AtListItem,AtIndexes,AtModal, AtFloatLayout, Toast} from 'taro-ui'
import cityData from '../../../assets/city.json'
import './index.scss';
import { check_mobile ,check_string} from '../../../utils/utils'
let cityList = []
cityData.map((item,index)=>
cityList[index]=
{
title:item.letter,
key:item.letter,
items:item.list,
}
)
//索引组件中明确要求的三个键名,对cityData,二维对象文件进行特殊处理
@connect(({ merchantenter ,loading}) => ({
...merchantenter,
loading: loading.models.merchantenter,
})) //跨域代理
export default class SubForm extends Component {
constructor (props) {
super(props);
this.openshowDrawer=this.openshowDrawer.bind(this)
}
state = {
value: '', //联系人
telvalue:'', //联系方式
shopvalue:'', //店铺名称
isshowDrawer:false, //是否显示城市抽屉
getcategoryArray:[],
categoryArray:[], //存放所有商品列表
//层级选择器
categoryIndex: [0, 0],
onlyArray: [
[],
[]
],
setCategory:'',
setCity:'',
hotCityList:[],
}
componentDidMount(){
const { dispatch } = this.props;
dispatch({
type: 'merchantenter/getSelectAll',
payload: {
channel: 1
},
callback: res => {
if(res.code === 1){
this.setState({
getcategoryArray:res.data
})
this.getlist(res.data)
}else{
message.error(res.data.msg)
}
}
})
const newCityList=cityList;
const hotCity = []
newCityList.map(item=>(
item.items.map(_item=>{
if(_item.type == 'hot'){
hotCity.push(_item)
}
})
))
console.log(newCityList,"newCityList",hotCity,"hotCity")
this.setState({
hotCityList:hotCity
})
}
getlist(getdata){
const {categoryArray,categoryIndex,onlyArray}=this.state;
const data = {
categoryArray: getdata, //所有的商品
categoryIndex: categoryIndex, // [0,0] [父类第几项,子类第几项]
onlyArray: onlyArray, //[[],[]]
};
for (let i = 0; i < data.categoryArray.length; i++) {
data.onlyArray[0].push(data.categoryArray[i].label); //存放总父类
}
//获取总子类 [{},{},...]
for (let j = 0; j < data.categoryArray[categoryIndex[0]].children.length; j++) {
data.onlyArray[1].push(data.categoryArray[categoryIndex[0]].children[j].label);
}
this.setState({
categoryArray: data.categoryArray, //所有的商品
categoryIndex: data.categoryIndex,
onlyArray: data.onlyArray,
})
}
handleChange (value) {
this.setState({
value:value
})
}
telHandleChange (value) {
this.setState({
telvalue:value
})
}
shopHandleChange (value) {
this.setState({
shopvalue:value
})
}
onChange=(e)=>{
const {categoryArray}=this.state
const indexArr = e.detail.value //记录下标
const categoryText = `${categoryArray[indexArr[0]].label} ${categoryArray[indexArr[0]].children[indexArr[1]].label} `
this.setState({
setCategory:categoryText
})
}
onColumnChange=(e)=>{
const { dispatch } = this.props;
const {getcategoryArray,categoryIndex,onlyArray,categoryArray}=this.state
const newCategoryArray = getcategoryArray //总商品类目
const newCategoryIndex = categoryIndex
const newOnlyArray = onlyArray
newCategoryIndex[e.detail.column] = e.detail.value;
const searchColumn = (getcolumn) => {
if (getcolumn==0){
newCategoryIndex[1] = 0;
}
for (let i = 0; i <newCategoryArray.length; i++) {
let arr = [];
if (i == newCategoryIndex[0]) {
for (let j = 0; j < newCategoryArray[i].children.length; j++) {
arr.push(newCategoryArray[i].children[j].label); //arr存放父类对应的children 总子类
}
newOnlyArray[1] = arr; //将获取的子类放入
}
}
};
switch (e.detail.column) {
case 0:
searchColumn(e.detail.column);
break;
case 1:
searchColumn(e.detail.column);
break;
}
//这里要清空原来的数据进行数据更新
this.setState({
// onlyArray:[[],[]],
categoryIndex:newCategoryIndex
})
}
onsubmit(){
const { dispatch,save} = this.props
const { value, telvalue, shopvalue,cityData,setCategory,setCity} = this.state;
const param = this.$router.params;
if (value.length == 0) {
Taro.showToast({
title: '请输入您的姓名',
icon: 'none',
mask: true,
});
return;
} else if (!check_string(value)) {
Taro.showToast({
title: '请输入正确的姓名',
icon: 'none',
mask: true,
});
return;
}
else if (telvalue.length == 0) {
Taro.showToast({
title: '请输入您的手机号码',
icon: 'none',
mask: true,
});
return;
} else if (!check_mobile(telvalue)) {
Taro.showToast({
title: '请输入正确手机号码',
icon: 'none',
mask: true,
});
return;
} else if (shopvalue.length == 0) {
Taro.showToast({
title: '请填写店铺名称',
icon: 'none',
mask: true,
});
return;
}else if (!check_string(shopvalue)) {
Taro.showToast({
title: '请输入正确的店铺名称',
icon: 'none',
mask: true,
});
return;
}
let _this = this
dispatch({
type:'merchantenter/submit',
payload:{
contactName:value,
telephone:telvalue,
businessScope:setCategory,
shopName:shopvalue,
city:setCity
},
callback: res => {
if (res.code==1) {
Taro.showToast({
title: res.msg,
icon: 'none',
mask: true,
});
_this.setState({
value: '',
telvalue: '',
shopvalue:'',
setCategory: '',
setCity:'',
})
} else {
Taro.showToast({
title: res.msg,
icon: 'none',
mask: true,
});
}
},
});
}
//打开城市选择抽屉
openshowDrawer(){
console.log("点击开启城市抽屉")
this.setState({
isshowDrawer:true,
})
}
//关闭城市选择抽屉
closeshowDrawer(){
this.setState({
isshowDrawer:false,
})
}
onClick(item){
this.setState({
setCity:item.name,
isshowDrawer:false
})
}
getHot(item){
this.setState({
setCity:item.name,
isshowDrawer:false
})
}
render(){
const {isshowDrawer,dispatch,categoryIndex,onlyArray,setCategory,setCity,hotCityList,shopvalue,value,telvalue}=this.state
return (
<View className='submitform'>
<AtInput
name='value'
//title='姓名'
type='text'
placeholder='姓名:'
maxLength={16}
value={this.state.value}
onChange={this.handleChange.bind(this)}
/>
<AtInput
name='telvalue'
border={false}
//title='手机号'
type='phone'
placeholder='手机号:'
value={this.state.telvalue}
onChange={this.telHandleChange.bind(this)}
/>
<View className='runpicker' >
<Picker mode='multiSelector'
range={onlyArray}
onChange={this.onChange} value={categoryIndex} onColumnChange={this.onColumnChange.bind(this) }
>
{ setCategory?
(
<View className='con-run'>
{setCategory}
</View>
)
:
(
<View className='picker'>
经营范围:
</View>
)
}
</Picker>
</View>
<AtInput
name='shopvalue'
type='text'
placeholder='店铺名称:'
maxLength={16}
value={this.state.shopvalue}
onChange={this.shopHandleChange.bind(this)}
/>
<View className='city'
onClick={()=>this.setState({isshowDrawer:true})}
>
{
setCity?
(
<View className='con-run'>
{setCity}
</View>
)
:
(
<View className='picker'>
城市:
</View>
)
}
</View>
<AtDrawer
className='drawer'
show={isshowDrawer}
mask
>
<AtIndexes
topKey='热'
list={cityList}
onClick={this.onClick.bind(this)}
>
<View className='custom-area'>
<View className='top'>
<View className='top-title'>城市选择
<View className='top-left' onClick={(e)=>this.setState({isshowDrawer:false})}>✖️</View>
</View>
</View>
<View className='at-indexes__list-title' >热门城市</View>
<View className='drawer-hot'>
{
hotCityList.map((item,index)=>(
<View
key={index}
className='drawer-hot-item'
onClick={(e)=>this.getHot(item)}
>
<View className='font'>
{item.name}
</View>
</View>
))
}
</View>
</View>
</AtIndexes>
</AtDrawer>
{/*提交按钮 */}
<View className='bottom' onClick={this.onsubmit.bind(this)}/>
</View>
)
}
}