美文网首页
城市选择器组件

城市选择器组件

作者: 逸笛 | 来源:发表于2020-09-03 11:33 被阅读0次
    图片.png

    调用

    import CityChoose from "../../../components/CityChoose/index";
    
       <CityChoose
              className="city-choose-box"
              isOpened={this.state.cityRequireOpen}
              getUserSub={false}
              limit={3}
              onClose={this.handleCityRequireClose.bind(this)}
            ></CityChoose>
    
    import Taro, { Component } from "@tarojs/taro";
    import { View, Button, ScrollView } from "@tarojs/components";
    import { AtSearchBar } from "taro-ui";
    import classNames from "classnames";
    import api from "../../utils/network/request";
    import user from "../../utils/auth/user";
    import "./index.less";
    
    export default class Index extends Component {
      state = {
        searchName: "",
        current: [],
        currentName: [],
        currentLength: 0,
        cityData: [],
        hotCityData: [],
        searchCityData: [],
        scrollTop: 0,
        nowScrollTop: 0
      };
    
      componentWillMount() {
        this.getData();
      }
    
      componentDidMount() {}
    
      componentWillUnmount() {}
    
      getData() {
        const that = this;
        api.request({
          url: this.props.getUserSub
            ? "/bo/subCitysByFirstLetter"
            : "/public/citysByFirstLetter",
          data: {
            access_token: user.getToken()
          },
          success: function(res) {
            that.setState({ cityData: res.data.result });
          },
          error: function(error) {}
        });
    
        if (!this.props.getUserSub) {
          api.request({
            url: "/public/hotCitys",
            data: {
              access_token: user.getToken()
            },
            success: function(res) {
              that.setState({ hotCityData: res.data.result });
            },
            error: function(error) {}
          });
        }
      }
    
      handleSearchChange(value) {
        this.setState({
          searchName: value
        });
      }
    
      handleSearch() {
        const searchName = this.state.searchName;
        if (searchName === "") {
          return false;
        }
        this.setState({
          scrollTop: 0
        });
        api.request({
          url: "/public/citys",
          data: {
            name: searchName
          },
          success: res => {
            const result = res.data.result;
            if (result.length === 0) {
              Taro.showToast({
                title: "没有搜索到该城市,换个名字搜一下吧",
                icon: "none",
                duration: 1500
              });
            } else {
              this.setState({ searchCityData: result, scrollTop: -200 });
            }
          },
          error: function(error) {}
        });
      }
      onScroll(e) {
        this.setState({
          nowScrollTop: e.detail.scrollTop
        });
      }
    
      gotoAnchor(indexes) {
        const that = this;
        Taro.createSelectorQuery()
          .in(this.$scope)
          .select(`#${indexes}`)
          .boundingClientRect(rect => {
            that.setState({
              scrollTop: that.state.nowScrollTop + rect.top - 200
            });
          })
          .exec();
      }
    
      handleChooseCity(id, name) {
        let current = this.state.current;
        let currentName = this.state.currentName;
    
        const index = current.indexOf(id);
        if (index === -1) {
          if (this.props.limit == 1) {
            current = [id];
            currentName = [name];
          } else {
            if (this.props.limit == current.length) {
              Taro.showToast({
                title: `最多选择${this.props.limit}项`,
                icon: "none"
              });
              return;
            }
            current.push(id);
            currentName.push(name);
          }
        } else {
          current.splice(index, 1);
          currentName.splice(index, 1);
        }
        this.setState({
          current: current,
          currentName: currentName,
          currentLength: current.length
        });
      }
      componentWillReceiveProps(nextProps) {
        if (nextProps.cityrefresh) {
          this.setState({
            current: [],
            currentName: [],
            currentLength: 0
          });
        }
      }
      handleClose(e, status) {
        const data = [];
        const current = this.state.current;
        const currentName = this.state.currentName;
    
        for (const i in current) {
          data.push({
            id: current[i],
            name: currentName[i],
            cityrefresh: status == 1 ? false : true
          });
        }
    
        this.props.onClose(data);
      }
      render() {
        const { isOpened, getUserSub } = this.props;
        const {
          current,
          currentLength,
          searchCityData,
          hotCityData,
          cityData,
          scrollTop
        } = this.state;
        const character = [
          "A",
          "B",
          "C",
          "D",
          "E",
          "F",
          "G",
          "H",
          "J",
          "K",
          "L",
          "M",
          "N",
          "P",
          "Q",
          "R",
          "S",
          "T",
          "W",
          "X",
          "Y",
          "Z"
        ];
    
        const cName = classNames("city-modal", {
          "city-modal--active": isOpened
        });
    
        return (
          <View className={cName}>
            <View
              className="city-modal__overlay"
              onClick={this.handleClose.bind(this)}
            ></View>
            <View className="city-modal__container">
              <View className="city_change">
                {!getUserSub && (
                  <AtSearchBar
                    showActionButton
                    value={this.state.searchName}
                    onChange={this.handleSearchChange.bind(this)}
                    onActionClick={this.handleSearch.bind(this)}
                  />
                )}
                <ScrollView
                  className="city_bottom"
                  scrollY
                  scrollWithAnimation
                  scrollTop={scrollTop}
                  onScroll={this.onScroll}
                >
                  {!getUserSub && (
                    <View>
                      {searchCityData.length > 0 && (
                        <View className="place_city">
                          <View className="place_city_head">
                            <View className="location">搜索记录</View>
                          </View>
                          <View className="at-row at-row--wrap place_city_bottom">
                            {searchCityData.map((item, index) => {
                              const searchBoxClass = classNames(
                                "at-col",
                                "at-col-4",
                                {
                                  potch_city: current.includes(item.id),
                                  city: !current.includes(item.id)
                                }
                              );
    
                              return (
                                <View
                                  key={item.id}
                                  className={searchBoxClass}
                                  onClick={this.handleChooseCity.bind(
                                    this,
                                    item.id,
                                    item.name
                                  )}
                                >
                                  {item.name}
                                </View>
                              );
                            })}
                          </View>
                        </View>
                      )}
    
                      {/* <View className='place_city'>
                                            <View className='place_city_head'>
                                                <View className='location'>定位城市</View>
                                                <View>
                                                    <Image src={positioning} className="picter" />
                                                    <Text className='new_place'>重新定位</Text>
                                                </View>
                                            </View>
                                            <View className='at-row at-row--wrap place_city_bottom'>
                                            {current.indexOf(2) === -1 ?
                                                    <View className='at-col at-col-4 city' onClick={this.choose_city.bind(this, 2)}>长沙长沙长沙</View>
                                                    :
                                                    <View className='at-col at-col-4 potch_city' onClick={this.choose_city.bind(this, 2)}>长沙长沙长沙</View>
                                                }
                                            </View>
                                        </View> */}
                      <View className="place_city">
                        <View className="place_city_head">
                          <View className="location">热门城市</View>
                        </View>
                        <View className="at-row at-row--wrap place_city_bottom">
                          {hotCityData.map((item, index) => {
                            const searchBoxClass = classNames(
                              "at-col",
                              "at-col-4",
                              {
                                potch_city: current.includes(item.id),
                                city: !current.includes(item.id)
                              }
                            );
    
                            return (
                              <View
                                key={item.id}
                                className={searchBoxClass}
                                onClick={this.handleChooseCity.bind(
                                  this,
                                  item.id,
                                  item.name
                                )}
                              >
                                {item.name}
                              </View>
                            );
                          })}
                        </View>
                      </View>
                    </View>
                  )}
    
                  <View className="place_city">
                    <View className="place_city_head">
                      <View className="location">字母索引</View>
                    </View>
                    <View className="at-row at-row--wrap place_city_bottom">
                      {character.map((item, index) => {
                        return (
                          <View
                            key={item}
                            className="at-col at-col-1 citys"
                            onClick={this.gotoAnchor.bind(this, item)}
                          >
                            {item}
                          </View>
                        );
                      })}
                    </View>
                  </View>
    
                  <View>
                    {cityData.map(letterItem => {
                      return (
                        <View className="place_city" key={letterItem.key}>
                          <View className="place_city_head">
                            <View className="location" id={letterItem.key}>
                              {letterItem.title}
                            </View>
                          </View>
                          <View className="at-row at-row--wrap place_city_bottom">
                            {letterItem.items.map(item => {
                              const searchBoxClass = classNames(
                                "at-col",
                                "at-col-4",
                                {
                                  potch_city: current.includes(item.id),
                                  city: !current.includes(item.id)
                                }
                              );
    
                              return (
                                <View
                                  key={item.id}
                                  className={searchBoxClass}
                                  onClick={this.handleChooseCity.bind(
                                    this,
                                    item.id,
                                    item.name
                                  )}
                                >
                                  {item.name}
                                </View>
                              );
                            })}
                          </View>
                        </View>
                      );
                    })}
                  </View>
                </ScrollView>
                <View>
                  {currentLength === 0 ? (
                    <Button
                      className="no_choose"
                      onClick={this.handleClose.bind(this)}
                    >
                      取消
                    </Button>
                  ) : (
                    <Button
                      className="choose"
                      onClick={this.handleClose.bind(this, 1)}
                    >
                      确定(已选:{currentLength})
                    </Button>
                  )}
                </View>
              </View>
            </View>
          </View>
        );
      }
    }
    
    
    .city-modal {
      position: fixed;
      width: 100%;
      height: 100%;
      top: 0;
      left: 0;
      visibility: hidden;
      -webkit-transition: visibility 200ms ease-in;
      -o-transition: visibility 200ms ease-in;
      transition: visibility 200ms ease-in;
      z-index: 99999;
    
      .city-modal__overlay {
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        position: absolute;
        background-color: rgba(0, 0, 0, 0.3);
        // z-index: 2000;
        opacity: 0;
        display: none;
      }
    
      .city-modal__container {
        height: 85vh;
        width: 98vw;
        position: absolute;
        left: 1vw;
        bottom: 0;
        -webkit-transform: unset;
        -ms-transform: unset;
        transform: unset;
        border-radius: 12px;
        background-color: #fff;
        overflow: hidden;
        -webkit-transition: opacity 200ms ease-in;
        -o-transition: opacity 200ms ease-in;
        transition: opacity 200ms ease-in;
        z-index: 999;
        opacity: 0;
        display: none;
    
        .city_change {
          // height: 5000px;
          .city_bottom {
            margin-bottom: 20px;
            overflow: scroll;
            position: relative;
            height: 71vh;
    
            .place_city {
              padding: 0 25px;
              margin-top: 10px;
    
              :after {
                content: "";
                width: 215px;
              }
    
              .place_city_head {
                display: flex;
    
                .location {
                  font-size: 30px;
                  color: #333333;
                  font-weight: bold;
                  flex: 1;
                }
    
                .picter {
                  width: 26px;
                  height: 36px;
                }
    
                .new_place {
                  font-size: 30px;
                  color: #ebc87f;
                  margin-left: 18px;
                }
              }
    
              .place_city_bottom {
                display: flex;
                justify-content: space-between;
                flex-flow: row wrap;
    
                .city {
                  font-size: 30px;
                  color: #333333;
                  background-color: #f7f7f7;
                  min-width: 200px;
                  text-align: center;
                  margin-top: 23px;
                  padding: 10px;
                }
    
                .citys {
                  font-size: 30px;
                  color: #333333;
                  background-color: #f7f7f7;
                  min-width: 76px;
                  text-align: center;
                  margin-top: 10px;
                  margin-left: 10px;
                }
    
                .potch_city {
                  font-size: 30px;
                  color: #ffffff;
                  background-color: #ebc87f;
                  min-width: 200px;
                  text-align: center;
                  padding: 15px 5px;
                  margin-top: 23px;
                  padding: 10px;
                }
              }
            }
          }
          .no_choose&&.choose::after {
            display: none;
          }
          .no_choose {
            font-size: 35.75px;
            color: #ffffff;
            background-color: #d2d2d2;
            width: 90%;
            border-radius: 50px;
            bottom: 40px;
            margin: 10px auto 30px auto;
            border-radius: 50px;
            z-index: 99999;
          }
    
          .choose {
            font-size: 35.75px;
            color: #ffffff;
            background-color: #ebc87f;
            width: 90%;
            bottom: 40px;
            margin: 10px auto 30px auto;
            border-radius: 50px;
            z-index: 99999;
          }
        }
      }
    }
    
    .city-modal--active {
      visibility: visible;
    
      .city-modal__overlay {
        opacity: 1;
        display: block;
      }
    
      .city-modal__container {
        opacity: 1;
        display: block;
      }
    }
    
    .at-search-bar__placeholder-wrap {
      display: block;
      line-height: 30px;
    }
    
    
    

    相关文章

      网友评论

          本文标题:城市选择器组件

          本文链接:https://www.haomeiwen.com/subject/tcmnsktx.html