Teach you step by step to encapsulate a drop-down component of a company library with taro

content

foreword

foreword

Demand introduction

core code part

style section

Implementation idea introduction (interface call is executed in child component or parent component)

Summary 1

Implementation ideas introduction (get request passed in Chinese page can not get parameters) 

Summary 2

Implementation ideas introduction (how to change the drop-down paging) 

Summary 3

Implementation ideas introduction (how to control the value of the drop-down selection to be rendered to the input)

Summary 4

Implementation idea introduction (how to give the value obtained by the child component to the parent component) 

Summary 5

Implementation ideas introduction (how to control the bubbling of events)  

Summary 6

achieve effect


foreword

I am Gaoyao. When I had a brother at the peak, it was ranked 19th in the overall list of station c. It was called the front end Xiaoyao. It took me three years to create him. Now I want to surpass him in five years. Today is another day close to my brother. Life is inevitable Ups and downs are a big deal, and the will of the ballad is forever. It's easy to give up, but it must be cool to persevere.

foreword

How to encapsulate a component of a company library

Demand introduction

The first thing to achieve is

1 The first step is to enter characters in an input box and call the interface when the characters change

2 More than two characters start rendering the page

3 Return the value of the page

core code part

import Taro, { Component } from "@tarojs/taro";
import { View, Text, Input, Form, ScrollView } from "@tarojs/components";

import { AtList, AtListItem, AtAccordion } from "taro-ui";
import { searchCompanyLibrary } from "@/services/user";
import "./index.scss";
/********
 * @param placeholder String 默认请输入
 * @param title String 输入框名字【required】
 * @param clear Boolean 是否显示清楚按钮
 * @param searchCompanyLibrary Function 获取列表数据 [required] 接口请求
 *  @param searchCompanyLibraryList 回调传值 第一个参数为外层需要的文本值 
第二个参数为控制外面元素是不是存在的值
 *  @param companyName 用于编辑回显使用 外层传入
 *  @param  ScrollView 滚动取值
 * ****************** */
class FuzzyQuery extends Component {
  state = {
    applicantName: this.props.companyName || "",
    popLeft: 0,
    popWidth: 0,
    open: false,
    dataSource: [1, 2, 3],
    popTop: 0,
    selectItem: {},
    isSelectCompany: false,
    pageIndex: 1,
    pageSize: 10
  };
  componentDidMount() {
    this.props.onRef && this.props.onRef(this);
    setTimeout(() => {
      this.handleGetDom();
    }, 100);
    // this.handleGetDom();
  }
  handleGetDom = () => {
    let _this = this;
    Taro.createSelectorQuery()
      .select(".fuzzy-query .weui-input")
      .boundingClientRect(function(rect) {
        // rect.id; // 节点的ID
        // rect.dataset; // 节点的dataset
        // rect.left; // 节点的左边界坐标
        // rect.right; // 节点的右边界坐标
        // rect.top; // 节点的上边界坐标
        // rect.bottom; // 节点的下边界坐标
        // rect.width; // 节点的宽度
        // rect.height; // 节点的高度

        _this.setState({
          popLeft: rect.left,
          popWidth: rect.width,
          popTop: rect.height
        });
      })
      .exec();
  };
  //选中某一项时触发
  handleClick = (e, item) => {
    console.log(e, "e");
    e.stopPropagation();
    e.preventDefault();

    this.setState(
      {
        open: false,
        applicantName: item.name,
        selectItem: item
      },
      () => {
        const { open } = this.state;
        this.props.searchCompanyLibraryList &&
          this.props.searchCompanyLibraryList(item.name, open);
      }
    );
  };
  //当输入框发生变化时
  handleChange = async keyWord => {
    var company = keyWord.detail.value;
    //先编码
    var value = encodeURI(keyWord.detail.value);
    console.log(value, "value");

    //如果少于2个字符,是不调用接口的,此时不显示公司公司列表弹窗,且将数据清空
    if (company.length < 2) {
      this.setState(
        {
          applicantName: company,
          open: false,
          dataSource: [],
          pageIndex: 1
        },
        () => {
          const { open } = this.state;
          this.props.searchCompanyLibraryList &&
            this.props.searchCompanyLibraryList(company, open);
        }
      );
      Taro.showToast({
        title: "请输入不少于两个字符",
        icon: "none",
        mask: true
      });
    } else {
      const { pageIndex, pageSize, dataSource, open } = this.state;
      let params = { keyWord: decodeURI(value), pageSize, pageIndex };
      const data = await searchCompanyLibrary(params);
      this.setState(
        {
          open: true,
          applicantName: company,
          dataSource: data.data.data,
          pageIndex: 1
        },
        () => {
          const { open } = this.state;
          this.props.searchCompanyLibraryList &&
            this.props.searchCompanyLibraryList(company, open);
        }
      );
    }
  };

  //触底函数
  onScrollToUpper = async () => {
    console.log("我在触底");

    const { pageIndex, pageSize, dataSource, applicantName } = this.state;
    let applicantNameList = encodeURI(applicantName);
    let params = {
      keyWord: decodeURI(applicantNameList),
      pageSize,
      pageIndex: pageIndex + 1
    };
    const data = await searchCompanyLibrary(params);
    console.log(dataSource, "dataSource");
    console.log(data.data.data, "data");
    this.setState({
      // open: true,
      // applicantName: applicantName,
      dataSource: [...dataSource, ...data.data.data],
      pageIndex: pageIndex + 1
    });
  };
  render() {
    const {
      applicantName,
      popLeft,
      popWidth,
      open,
      popTop,
      dataSource
    } = this.state;
    console.log(dataSource, "dataSource");
    const scrollStyle = {
      zIndex: 100,
      height: "250px"
    };
    const { placeholder = "请输入", title = "", clear = false } = this.props;
    return (
      <View
        className="position-relative fuzzy-query"
        id="fuzzy-query"
        onRef={node => (this.fuzzyWrap = node)}
      >
        <Form>
          <View className=" input-wrap">
            <View className="flex-between input-item">
              <Text className="input_title">{title}</Text>
              <View
                className={
                  clear && applicantName
                    ? "search-input-show-clear"
                    : "search-input-wrap"
                }
              >
                <Input
                  placeholderStyle="color:#f8f8f8"
                  className="search-input"
                  value={applicantName}
                  onChange={this.handleChange}
                  placeholder={placeholder}
                ></Input>
              </View>
              {clear && applicantName && (
                <div
                  className="at-input__icon "
                  onClick={() =>
                    this.setState({
                      applicantName: "",
                      dataSource: [],
                      open: false
                    })
                  }
                >
                  <span className="taro-text at-icon 
at-icon-close-circle at-input__icon-close"></span>
                </div>
              )}
            </View>
          </View>
        </Form>

        <View
          style={
   
   { top: `${popTop * 2}px` }}
          className={
            open
              ? "show-fuzzy-pop position-absolute fuzzy-query-pop"
              : "position-absolute fuzzy-query-pop"
          }
        >
          <ScrollView
            scrollY
            style={scrollStyle}
            scrollWithAnimation
            onScrollToLower={this.onScrollToUpper} 
// 使用箭头函数的时候 可以这样写 `onScrollToUpper={this.onScrollToUpper}`
          >
            <View
              style={
   
   {
                paddingLeft: `${popLeft - 12}px`,
                width: `${popWidth}px`
              }}
            >
              <AtList>
                {dataSource.length > 0 &&
                  dataSource.map(item => {
                    return (
                      <AtListItem
                        title={item.name}
                        onClick={e => this.handleClick(e, item, "selectItem")}
                      />
                    );
                  })}
              </AtList>
            </View>
          </ScrollView>
        </View>
      </View>
    );
  }
}

export default FuzzyQuery;

style section

.fuzzy-query{
  .at-list::after{border-top:0;}
  .fuzzy-query-pop{
    // border: 1px solid #e8e8e8;
    box-sizing: border-box;
    z-index:100;
    width: 100%;
    background: #fff;
    // opacity: 0;
    max-height:0;
    overflow: hidden;
    transition:max-height 0.5s ;
    .at-list__item{
      padding:20px;
      font-size: 28px;
    }
    .at-list__item::after{left:0;}
  }
  .show-fuzzy-pop{
    max-height:800px;

    z-index: 100;
    // overflow-y: scroll;
  }
  .input-wrap{
margin-left: 32px;

color:#333;
font-size: 28px;
.input-item{
  position: relative;
  padding:24px 0 ;
  &::after{
  content: '';
  position: absolute;
  -webkit-transform-origin: center;
  -ms-transform-origin: center;
  transform-origin: center;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
  pointer-events: none;
  top: -50%;
  left: -50%;
  right: -50%;
  bottom: -50%;
  border: 0 solid #d6e4ef;
  -webkit-transform: scale(0.5);
  -ms-transform: scale(0.5);
  transform: scale(0.5);
  border-bottom-width: 1PX;
}}
    .input_title{
      width:172px;
      margin-right: 16px;
    }
    .search-input-wrap{width:calc(100% - 172px);position: relative;
    .fuzzy-clear{position: absolute;right:0;width:32px;height:32px}}
    .search-input-show-clear{width:480.12px;position: relative;
    .fuzzy-clear{position: absolute;right:0;width:32px;height:32px}}

input::-webkit-input-placeholder {
  color: rgb(204,204,204);
}

input::-moz-placeholder {
  /* Mozilla Firefox 19+ */
  color: rgb(204,204,204);
}

input:-moz-placeholder {
  /* Mozilla Firefox 4 to 18 */
  color: rgb(204,204,204);
}

input:-ms-input-placeholder {
  /* Internet Explorer 10-11 */
  color: rgb(204,204,204);
}

  }

}

Implementation idea introduction (interface call is executed in child component or parent component)

  const { pageIndex, pageSize, dataSource, open } = this.state;
      let params = { keyWord: decodeURI(value), pageSize, pageIndex };
      const data = await searchCompanyLibrary(params);

Summary 1

Call the interface in the child component and render the page

Implementation ideas introduction (get request passed in Chinese page can not get parameters) 

  let applicantNameList = encodeURI(applicantName);
    let params = {
      keyWord: decodeURI(applicantNameList),
      pageSize,
      pageIndex: pageIndex + 1
    };

Summary 2

First encode with encodeURI and then decode with decodeURI

Implementation ideas introduction (how to change the drop-down paging) 

 //触底函数
  onScrollToUpper = async () => {
    console.log("我在触底");

    const { pageIndex, pageSize, dataSource, applicantName } = this.state;
    let applicantNameList = encodeURI(applicantName);
    let params = {
      keyWord: decodeURI(applicantNameList),
      pageSize,
      pageIndex: pageIndex + 1
    };
    const data = await searchCompanyLibrary(params);
    console.log(dataSource, "dataSource");
    console.log(data.data.data, "data");
    this.setState({
      // open: true,
      // applicantName: applicantName,
      dataSource: [...dataSource, ...data.data.data],
      pageIndex: pageIndex + 1
    });
  };

Summary 3

The ScrollView wrapping sets the height of the scroll bar to bottom out and executes the data with the spread operator

Implementation ideas introduction (how to control the value of the drop-down selection to be rendered to the input)

{dataSource.length > 0 &&
                  dataSource.map(item => {
                    return (
                      <AtListItem
                        title={item.name}
                        onClick={e => this.handleClick(e, item,
 "selectItem")}
                      />
                    );
                  })}

Summary 4

The event is bound to one more parameter for assignment. Click to trigger the assignment to complete the assignment.

Implementation idea introduction (how to give the value obtained by the child component to the parent component) 

 this.props.searchCompanyLibraryList &&
            this.props.searchCompanyLibraryList(company, open);

Summary 5

Simple child components pass values ​​to parent components

Implementation ideas introduction (how to control the bubbling of events)  

 this.props.searchCompanyLibraryList &&
            this.props.searchCompanyLibraryList(company, open);

Summary 6

open to control the display and hide of the outer dom element

achieve effect

Guess you like

Origin blog.csdn.net/geyaoisnice/article/details/123681919