【C端小程序】taro-ui 实现商品二级联动以及城市字母索引器(含有热门城市)

项目场景

    将后端通过接口传递过来的二级商品数据,以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>
        )
    }
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ayaahooo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值