zoukankan      html  css  js  c++  java
  • taro3.x: 查询组件封装

    查询组件:

    import React, { useState, useEffect } from 'react'
    import Taro from '@tarojs/taro'
    import classnames from 'classnames'
    import { map, includes } from 'lodash'
    import { View, Text, Input, RichText, ScrollView } from '@tarojs/components'
    
    import api from '@services/api'
    import app from '@services/request'
    import { keywordcolorful } from '@utils/index'
    import storage from '@utils/storage'
    import useNavData from '@hooks/useNavData'
    import NavBar from '@components/navbar/index'
    import './index.scss'
    
    export interface ISearchOption {
      type: string
      name: string
    }
    
    interface ISearchProps {
      searchTitle: string
      searchOption: any[]
      searchRemark?: string
      searchUrl: string
      onItemClick: (any, ISearchOption) => void
    }
    
    const Search = (props: ISearchProps) => {
      const isMultiply = props.searchOption.length > 1
      const INIT_OPTION = props.searchOption[0]
      const INIT_HISTORIES = storage.getItem('histories', `search_${INIT_OPTION.name}`) || []
      const { contentHeight } = useNavData()
      const [clear, setClear] = useState(false)
      const [hotList, setHotList] = useState([])
      const [matcheList, setMatcheList] = useState([])
      const [searchValue, setSearchValue] = useState("")
      const [searchHistories, setSearchHistories] = useState(INIT_HISTORIES)
      const [option, setOption] = useState<ISearchOption>(INIT_OPTION)
      const [showOption, setShowOption] = useState<boolean>(false)
    
      useEffect(() => {
        app.request({ url: api.getSearchHotList }, { isMock: true, loading: false })
          .then((result: any) => {
            setHotList(result || [])
          })
      }, [])
    
      Taro.setNavigationBarColor({
        frontColor: '#000000',
        backgroundColor: '#f7f7f7',
        animation: {
          duration: 400,
          timingFunc: 'easeIn'
        }
      })
    
      const handleItemClick = (item: any) => {
        let ids = map(searchHistories, 'id')
        if (!includes(ids, item.id)) {
          searchHistories.push(item)
        }
        storage.setItem('histories', searchHistories, `search_${option.name}`)
        props.onItemClick(item, option)
      }
    
      const handleInput = (event) => {
        let keyValue = event.currentTarget.value
        if (keyValue) {
          setClear(true)
        } else {
          setClear(false)
        }
        setSearchValue(keyValue)
        updateKeyList(keyValue)
      }
    
      const updateKeyList = (keyValue) => {
        app.request({
          url: props.searchUrl,
          data: { kw: keyValue }
        }, { isMock: true, loading: false })
          .then((result: any) => {
            setMatcheList(result || [])
          })
      }
    
      const clearSearchValue = () => {
        setClear(false)
        setSearchValue("")
      }
    
      const handleCancel = () => {
        Taro.navigateBack()
      }
    
      const handleClearClick = () => {
        storage.clear(`search_${option.name}`)
        setSearchHistories([])
      }
    
      const handleSwitchOption = (item: ISearchOption) => {
        if (item.type === option.type) {
          return
        }
        setOption(item)
        setShowOption(false)
        setSearchHistories(storage.getItem('histories', `search_${item.name}`) || [])
      }
    
      const renderSearchKeys = (title, className, keyList, allowClear = false) => {
        if (keyList && keyList.length > 0) {
          return (
            <View className={classnames("search-record", className)}>
              <View className="search-header clearfix">
                <Text className="title">{title}</Text>
                {allowClear && <Text className="iconfont iconclear1" onClick={handleClearClick}></Text>}
              </View>
              <View className="search-list clearfix">
                {keyList.map((item: any) => {
                  return <Text
                    key={item.id}
                    className="item"
                    onClick={() => handleItemClick(item)}
                  >{item.name}
                  </Text>
                })}
              </View>
            </View>
          )
        }
      }
    
      const renderSearOption = () => {
        return props.searchOption.map((item: ISearchOption, index: number) => (
          <View
            key={index}
            className={classnames('options-item', option.type === item.type && 'actived')}
            onClick={() => handleSwitchOption(item)}
          >{item.name}
          </View>
        ))
      }
    
      return (
        <View className="search">
          <NavBar title={props.searchTitle} back={true} backgroundColor="#f7f7f7" color="#000" />
          <View className="search-wrapper clearfix">
            <View className="search-content">
    
              <View className="search-label" onClick={() => setShowOption(!showOption)}>
                <Text className="search-label-text">{option.name}</Text>
                <Text className={classnames('iconfont', isMultiply ? 'iconarrow-down-bold' : 'iconsearch')}></Text>
              </View>
              <Input className="search-input" placeholder={props.searchRemark} onInput={handleInput} value={searchValue} autoFocus></Input>
    
              {clear && <Text className="iconfont iconclear" onClick={clearSearchValue}></Text>}
    
              {showOption &&
                <View className="search-options">
                  <View className="triangle-up">
                    <Text className="cover"></Text>
                  </View>
                  {renderSearOption()}
                </View>
              }
            </View>
            <Text className="search-cancel" onClick={handleCancel}>取消</Text>
          </View>
          <ScrollView scrollY style={{ maxHeight: contentHeight - 50 }}>
            {searchValue ?
              <View className="search-matches">
                {
                  matcheList.map((item: any, index: number) => {
                    return (
                      <View className="match-item" key={index} onClick={() => handleItemClick(item)}>
                        <RichText nodes={keywordcolorful(item.name, searchValue)} />
                        <View className="address">{item.address}</View>
                      </View>
                    )
                  })
                }
              </View> :
              <View className="search-category">
                {renderSearchKeys('搜索历史', 'search-history', searchHistories, true)}
                {renderSearchKeys('热门搜索', 'search-hot', hotList)}
              </View>
            }
          </ScrollView>
        </View>
      )
    }
    
    export default Search

    使用:

    import React from 'react'
    import Taro from '@tarojs/taro'
    import { View } from '@tarojs/components'
    
    import api from '@services/api'
    import Search, { ISearchOption } from '@components/search'
    import './index.scss'
    
    const HouseSearch = () => {
    
      const searchOption: ISearchOption[] = [
        { type: "newhouse", name: "新房" },
        { type: "esf", name: "二手房" }
      ]
    
      const handleItemClick = (item: any, option: ISearchOption) => {
        Taro.navigateTo({
          url: `/pages/${option.type}/index?id=${item.id}&name=${item.name}`
        })
      }
    
      return (
        <View className="house-search">
          <Search
            searchTitle="搜索"
            searchOption={searchOption}
            onItemClick={handleItemClick}
            searchRemark="请输入楼盘名称或地址"
            searchUrl={api.getSearchKeyList}
          ></Search>
        </View>
      )
    }
    
    export default HouseSearch
  • 相关阅读:
    C#:类的成员--属性
    C#:类的成员--字段
    C#:try语句
    solaris11 format zpool
    solaris硬盘格式化分区
    Linux使用pam_tally2.so模块限制登录失败锁定时间
    shell脚本if语句的多种条件参数
    系统重启后,mr程序不生成当前时间段的MRx文件问题
    hadoop学习笔记--找到执行hadoop的入口
    STREAMING HIVE流过滤 官网例子 注意中间用的py脚本
  • 原文地址:https://www.cnblogs.com/Nyan-Workflow-FC/p/13679574.html
Copyright © 2011-2022 走看看