Taro+react+TaroUi封装一个公司库的下拉组件

简介: Taro+react+TaroUi封装一个公司库的下拉组件

前言

歌谣 歌谣 如何封装一个公司库的一个组件


需求介绍

首先要实现的是


1第一步 需要在一个input框中输入字符 当字符发生变化的时候进行接口的调用


2超过两个字符开始渲染页面


3将页面的值返回出去


核心代码部分

``` 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 ( {title}


{clear && applicantName && (




<span className="taro-text at-icon

1.

at-icon-close-circle at-input__icon-close">


)}




<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} > ${popLeft - 12}px, width: ${popWidth}px }} > {dataSource.length > 0 && dataSource.map(item => { return ( ); })}


export default FuzzyQuery; ```




样式部分

``` .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-listitem{ padding:20px; font-size: 28px; } .at-listitem::after{left:0;} } .show-fuzzy-pop{ max-height:800px;


z-index: 100;

// overflow-y: scroll;

1.

2.

} .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); }


}


} ```




实现思路介绍(接口调用在子组件执行还是父组件)

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




总结1

子组件中进行接口的调用并进行页面的渲染


实现思路介绍(get请求传入中文页面获取不到参数)

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




总结2

先用encodeURI编码再用decodeURI解码


实现思路介绍(如何改变下拉的分页)

``` //触底函数 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
});


}; ```




总结3

ScrollView包裹 设置出现滚动条的高度 触底执行 并对数据用扩展运算符拼接


实现思路介绍(如何控制下拉选择的值渲染到input上)

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




总结4

事件多绑定一个参数进行赋值 点击触发 完成赋值


实现思路介绍(如何把子组件获取的值给到父组件)

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




总结5

简单的子组件向着父组件传值


实现思路介绍(如何控制事件的冒泡)  

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




总结6

open去控制外层dom元素的显隐


实现效果

image.png


相关文章
|
27天前
|
前端开发 UED 索引
React 图片灯箱组件 Image Lightbox
图片灯箱组件是一种常见的Web交互模式,用户点击缩略图后弹出全屏窗口展示大图,并提供导航功能。本文介绍了基于React框架的图片灯箱组件开发,涵盖初始化状态管理、图片加载与预加载、键盘和鼠标事件处理等常见问题及解决方案。通过`useState`和`useEffect`钩子管理状态,使用懒加载和预加载优化性能,确保流畅的用户体验。代码案例展示了组件的基本功能实现,包括打开/关闭灯箱、切换图片及键盘操作。
127 80
|
11天前
|
移动开发 前端开发 JavaScript
React 视频播放控制组件 Video Controls
本文介绍了如何使用 React 构建视频播放控制组件(Video Controls),涵盖基本概念、创建步骤和常见问题解决。首先,通过 HTML5 `&lt;video&gt;` 标签和 React 组件化思想,实现播放/暂停按钮和进度条等基础功能。接着,详细讲解了初始化项目、构建 `VideoControls` 组件及与主应用的集成方法。最后,针对视频无法播放、控制器状态不同步、进度条卡顿和音量控制失效等问题提供了具体解决方案,并介绍了全屏播放和自定义样式等进阶功能。希望这些内容能帮助你在实际项目中更好地实现和优化视频播放功能。
83 40
|
26天前
|
移动开发 前端开发 JavaScript
React 视频播放器组件:Video Player
本文介绍了如何使用 React 和 HTML5 `&lt;video&gt;` 标签构建自定义视频播放器组件。首先,通过创建基础的 React 项目和 VideoPlayer 组件,实现了基本的播放、暂停功能。接着,探讨了常见问题如视频加载失败、控制条样式不一致、性能优化不足及状态管理混乱,并提供了相应的解决方案。最后,总结了构建高效视频播放器的关键要点,帮助开发者应对实际开发中的挑战。
110 27
|
29天前
|
前端开发 JavaScript API
React 图片放大组件 Image Zoom
本文介绍如何使用React创建图片放大组件(Image Zoom),提升用户体验。组件通过鼠标悬停或点击触发放大效果,利用`useState`管理状态,CSS实现视觉效果。常见问题包括图片失真、性能下降和移动端支持,分别可通过高质量图片源、优化事件处理和添加触摸事件解决。易错点涉及状态管理混乱、样式冲突和过多事件绑定,建议使用上下文API、CSS模块及优化事件绑定逻辑。高级功能扩展如多张图片支持和自定义放大区域进一步丰富了组件的实用性。
58 25
|
25天前
|
存储 编解码 前端开发
React 视频上传组件 Video Upload
随着互联网的发展,视频内容在网站和应用中愈发重要。本文探讨如何使用React构建高效、可靠的视频上传组件,涵盖基础概念、常见问题及解决方案。通过React的虚拟DOM和组件化开发模式,实现文件选择、进度显示、格式验证等功能,并解决跨域请求、并发上传等易错点。提供完整代码案例,确保用户能顺畅上传视频。
128 92
|
30天前
|
移动开发 前端开发 JavaScript
React 图片裁剪组件 Image Cropper
本文介绍了在React中实现图片裁剪功能的方法,涵盖基础知识、常见问题及解决方案。首先,通过第三方库如`react-image-crop`或`cropperjs-react`可轻松实现图片裁剪。接着,针对性能和兼容性问题,提供了优化图片加载、处理裁剪区域响应慢、解决浏览器差异等方案。最后,通过代码案例详细解释了如何创建一个基本的图片裁剪组件,并提出了优化建议,如使用`React.memo`、添加样式支持及处理大图片预览,帮助开发者避免常见错误并提升用户体验。
116 67
|
6天前
|
移动开发 前端开发 UED
React 音频预览组件:Audio Preview
本文介绍如何使用 React 构建音频预览组件,涵盖基础实现、常见问题及解决方案。通过 HTML5 `&lt;audio&gt;` 标签和 React 状态管理,实现播放控制。解决文件路径、浏览器兼容性等问题,并优化性能,避免状态不同步和内存泄漏,提升用户体验。
54 22
|
2月前
|
前端开发 UED 开发者
React 悬浮按钮组件 FloatingActionButton
悬浮按钮(FAB)是常见的UI元素,用于提供突出的操作。本文介绍如何在React中使用Material-UI创建美观的FAB组件,涵盖基本概念、实现方法及常见问题解决。通过代码示例和优化技巧,帮助开发者提升用户体验,确保按钮位置、颜色、交互反馈等方面的表现,同时避免无障碍性和性能问题。
134 80
|
1天前
|
移动开发 前端开发 JavaScript
React 视频播放控制组件 Video Controls
本文深入探讨了如何使用React创建功能丰富的视频播放控制组件(Video Controls)。首先介绍了React与HTML5 `&lt;video&gt;` 标签的基础知识,展示了如何通过状态管理和事件处理实现自定义控件。接着分析了常见问题如视频加载失败、控件样式不一致、状态管理混乱和性能问题,并提供了相应的解决方案。最后通过完整代码案例详细解释了播放、暂停、进度条和音量控制的实现方法,帮助开发者在React中构建高质量的视频播放组件。
36 17
|
8天前
|
移动开发 前端开发 UED
React 音频播放器组件 Audio Player
本文介绍如何使用React创建功能丰富的音频播放器组件。基于HTML5 `&lt;audio&gt;` 标签,结合React的状态管理和事件处理,实现播放、暂停、进度和音量控制等功能。通过代码示例展示基本实现,并探讨常见问题如自动播放限制、进度条不更新、文件加载失败及多实例冲突的解决方案。同时,避免易错点如忽略生命周期管理、错误处理和性能优化,确保高效开发与良好用户体验。
62 23