react 实现tab切换 三角形筛选样式

256 阅读5分钟

本文已参与「新人创作礼」活动, 一起开启掘金创作之路。

*一般我们在写移动端的时候 会有一些筛选的效果 效果如下: *

image.png

通过上下效果来进行筛选 接下来直接上demo 这次使用的是react的class 类组件

import React, { Component } from 'react'
import { LeftOutline, SearchOutline } from 'antd-mobile-icons'
import { NavLink } from 'react-router-dom'
class serach extends Component {
  constructor(props) {
    super(props)
    this.state = {
      sousuo: '',
      // tab 数据渲染
      lis: ['发布时间', '产品价格', '收藏量', '评论量'],
      // tab切换默认标识
      acyive: 0,
      // 定义空字符串 不点击 不高亮
      active2: '',
      // 定义空字符串 不点击 不显示
      show: '',
    }
  }
  // 获取seach值
  seacrsh = (e) => {
    this.setState({
      sousuo: e.target.value,
    })
  }
  // 函数结束
  tab = (index) => {
    console.log(index)
    this.setState({
      acyive: index,
      show: '',
    })
  }
  // 切换内部  下面三角形点击函数
  // 判断切换 如果点击了内部 触发了冒泡可以用e.stopPropagation()解决,在此需要判断如果没有点击tab 就点击了tab内的上下三角形筛选 就需要 改变tab acyive 标识
  tabqh2 = (e, index) => {
    e.stopPropagation()
    if (index == 0) {
      this.setState({
        acyive: 0,
      })
    } else if (index == 1) {
      this.setState({
        acyive: 1,
      })
    } else if (index == 2) {
      this.setState({
        acyive: 2,
      })
    } else {
      this.setState({
        acyive: 3,
      })
    }
    console.log(index)

    console.log(this.state.acyive)
    this.setState({
      active2: index,
      show: 1,
    })
  }
  // 上面三角形点击点击函数
  tabqh = (e, index) => {
    e.stopPropagation()
    console.log(index)
    if (index == 0) {
      this.setState({
        acyive: 0,
      })
    } else if (index == 1) {
      this.setState({
        acyive: 1,
      })
    } else if (index == 2) {
      this.setState({
        acyive: 2,
      })
    } else {
      this.setState({
        acyive: 3,
      })
    }
    console.log(this.state.acyive)
    this.setState({
      active2: index,
      show: 0,
    })
  }

  render() {
    return (
      <div className="lxf_serach">
        {/* top */}
        <div className="lxf_serach_top">
          <div className="lxf_serach_top_centent">
            <div className="lxf_serach_top_centent_nei">
              <div className="left">
                <NavLink to="">
                  <LeftOutline fontSize={20} color="white" />
                </NavLink>
              </div>
              <div className="center">
                <img src={require('../lxf/imger/sousuo.png')} alt="" />
                <input
                  type="text"
                  placeholder="请搜索"
                  onChange={this.seacrsh}
                  style={{ textIndent: '30px' }}
                />
              </div>
              <div className="right">
                <span>搜索</span>
              </div>
            </div>
          </div>
        </div>
        {/* /top */}
        {/*选项卡  */}
        <div className="lxf_serach_xxk">
          <div className="lxf_serach_xxk_centen">
            <div className="lxf_serach_xxk_centen_qy">
              <ul>
                {this.state.lis.map((item, index) => {
                  return (
                    <li
                      onClick={() => this.tab(index)}
                      key={index}
                      className={this.state.acyive == index ? 'color' : ''}
                    >
                      <span>{item}</span>
                      {/* 三角形 */}
                      <div className="sanjiaoxing_big">
                        <div
                          onClick={(e) => this.tabqh(e, index)}
                          className={
                            this.state.active2 == index
                              ? this.state.show === 0
                                ? 'top s'
                                : 'top'
                              : 'top'
                          }
                        ></div>
                        <div
                          onClick={(e) => this.tabqh2(e, index)}
                          className={
                            this.state.active2 == index
                              ? this.state.show === 1
                                ? 'bottom y'
                                : 'bottom'
                              : 'bottom'
                          }
                        ></div>
                      </div>
                    </li>
                  )
                })}
              </ul>
            </div>
          </div>
          {/* 展示区域 */}
          <div className={this.state.acyive === 0 ? 'xianshi' : 'yincang'}>
            <div className={this.state.show === '' ? 'xianshi' : 'yincang'}>
              1
            </div>
            <div className={this.state.show === 0 ? 'xianshi' : 'yincang'}>
              1上
            </div>
            <div className={this.state.show === 1 ? 'xianshi' : 'yincang'}>
              1下
            </div>
          </div>
          <div className={this.state.acyive === 1 ? 'xianshi' : 'yincang'}>
            <div className={this.state.show === '' ? 'xianshi' : 'yincang'}>
              2
            </div>
            <div className={this.state.show === 0 ? 'xianshi' : 'yincang'}>
              2上
            </div>
            <div className={this.state.show === 1 ? 'xianshi' : 'yincang'}>
              2 下
            </div>
          </div>
          <div className={this.state.acyive === 2 ? 'xianshi' : 'yincang'}>
            <div className={this.state.show === '' ? 'xianshi' : 'yincang'}>
              3
            </div>
            <div className={this.state.show === 0 ? 'xianshi' : 'yincang'}>
              3 上
            </div>
            <div className={this.state.show === 1 ? 'xianshi' : 'yincang'}>
              3 下
            </div>
          </div>
          <div className={this.state.acyive === 3 ? 'xianshi' : 'yincang'}>
            <div className={this.state.show === '' ? 'xianshi' : 'yincang'}>
              4
            </div>
            <div className={this.state.show === 0 ? 'xianshi' : 'yincang'}>
              4 上
            </div>
            <div className={this.state.show === 1 ? 'xianshi' : 'yincang'}>
              4 下
            </div>
          </div>
          {/* 结束 */}
        </div>

        {/* 选项卡 */}
      </div>
    )
  }
}

export default serach
``
`.lxf_serach{`

`  ``// top条`

`  ``.lxf_serach_top{`

`    ``width: 100%;`

`    ``height: rm(133/3);`

`    ``background: #2ed8c4;`

`    ``.lxf_serach_top_centent{`

`      ``box-sizing: content-box;`

`    ``padding-left: rm(40/3);`

`    ``padding-right: rm(40/3);`

`    ``padding-top: rm(30/3);`

`    ``.lxf_serach_top_centent_nei{`

`      ``width: 100%;`

`      ``height: rm(80/3);`

`      ``display: flex;`

`      ``justify-content: space-between;`

`      ``align-items: center;`

`      ``.left{`

`        ``width: rm(80/3);`

`        ``height: 100%;`

`        ``display: flex;`

`        ``align-items: center;`

`      ``}`

`      ``.center{`

`        ``margin-left: rm(20/3);`

`        ``width: 100%;`

`        ``height: 100%;`

`        ``position: relative;`

`        ``img{`

`          ``position: absolute;`

`          ``width: rm(50/3);`

`          ``height: rm(50/3);`

`          ``top: rm(15/3);`

`          ``left: rm(15/3);`

`        ``}`

`        ``input{`

`          ``display: inline-block;`

`             ``width: 100%;`

`             ``height: 100%;`

`             ``border-radius: 20px;`

`             ``border: none;`

`             ``color: #333333;`

`        ``}`

`      ``}`

`      ``.right{`

`        ``margin-left: rm(20/3);`

`        ``width: rm(140/3);`

`        ``height: 100%;`

`        ``display: flex;`

`        ``align-items: center;`

`        ``span{`

`          ``width: rm(120/3);`

`          ``height: 100%;`

`          ``display: inline-block;`

`          ``border: 1px solid #ffffff;`

`          ``text-align: center;`

`          ``line-height: rm(80/3);`

`          ``border-radius: 30px;`

`          ``color: white;`

`          ``font-size: rm(36/3);`

`        ``}`

`      ``}`

`    ``}`

`    ``}`

`  ``}`

`  ``// 选项卡`

`  ``.lxf_serach_xxk{`

`    ``width: 100%;`

`    ``height: rm(95/3);`

`    ``box-shadow: 0px 1px 1px 1px #f5f5f5;`

`    ``.lxf_serach_xxk_centen{`

`      ``box-sizing: content-box;`

`      ``padding-left:rm(40/3) ;`

`      ``padding-right: rm(40/3);`

`      ``height: 100%;`

`      ``.lxf_serach_xxk_centen_qy{`

`        ``width: 100%;`

`        ``height: 100%;`

`        ``ul{`

`          ``width: 100%;`

`          ``height: 100%;`

`          ``display: flex;`

`          ``justify-content: space-around;`

`          ``list-style: none;`

`          ` 

`          ``li{`

`            ``width: 24%;`

`            ``height: 100%;`

`            ``display: flex;`

`            ``align-items: center;`

`            ``justify-content: center;`

`            ``font-size: rm(40/3);`

`            ``color: #cccccc;`

`           ``span{`

`               ``float``: left;`

`           ``}`

`          ``//  三角形`

`           ``.sanjiaoxing_big{`

`             ``height: 100%;`

`             ``width:  rm(30/3);`

.top{

margin-top: rm(15/3);

width: 0;

height: 0;

border-left: 3px solid transparent;

border-right: 3px solid transparent;

margin-left: rm(6/3);

border-bottom: 6px solid #f5f5f5;

}

.s{

border-bottom: 6px solid #28d2d1 ;

 
}



.bottom{

margin-top: rm(20/3);

width: 0;

height: 0;

border-left: 3px solid transparent;

border-right: 3px solid transparent;

border-top: 6px solid white;

margin-left: rm(6/3);

border-top: 6px solid #f5f5f5;

}

.y{

border-top: 6px solid #28d2d1;

}

}

}

.color{

color: #28d2d1 !important;

}

}

}

}

}

// 选项卡内容区

.xianshi{

width: 100%;

height: 200px;

background: red;

display: block;

}

.yincang{

width: 100%;

height: 200px;

background: red;

 display: none;

 }
``
//m是引入了移动端适配通过屏幕大小计算
`@charset ``"UTF-8"``;`

`$yh:``"Microsoft yahei"``;`

`@function rm($px, $``base``: 14.0625) {`

`  ``@``return` `($px / $``base``) * 1rem;`

`}`

`html {`

`   ``font-size: 62.5%; font-family:$yh;`

`}`

`body, textarea, input, ``select``, option {`

`  ``color: #333;`

`  ``font-family: ``"Hiragino Sans GB"``, ``"Microsoft Yahei"``, tahoma, arial, sans-serif;`

`  ``-webkit-font-smoothing: antialiased;`

`  ``-webkit-tap-highlight-color:transparent;`

`}`

`body,h1,h2,h3,h4,h5,h6,blockquote,ol,ul,dl,dd,p,textarea,input,``select``,option,form {`

`    ``margin:0; padding:0;`

`}`

 

`ol,ul,textarea,input,option,th,td {`

`    ``padding:0;`

`}`

`.page{`

`    ``min-width: 320px;max-width: 750px;margin: 0 auto;`

`}`

`h1,h2,h3,h4,h5,h6 {`

`    ``font-weight: normal;`

`    ``font-size:100%;`

`}`

`a,``select``,input,textarea{`

`    ``outline: none;`

`}`

`article, aside, details, figcaption, figure, footer, header, menu, nav, section {`

`    ``display: block;`

`}`

`table {`

`    ``border-collapse:collapse;border-spacing: 0;`

`}`

`ul,ol {`

`    ``list-style-type:none;`

`}`

`.hide {`

`    ``display: none;`

`}`

`.show {`

`    ``display: block;`

`}`

`.clearfix:after {`

`    ``content:``'.'``;display:block;height:0;clear:both;visibility:hidden;`

`}`

`//.clearfix {*zoom:1;}`

`.clear {`

`    ``clear:both;height:0;overflow:hidden;`

`}`

`/* ios默认文本框阴影 */`

`input[type=text],textarea{`

`    ``-webkit-appearance:none;`

`}`

`/* 低版本安卓文本框层级问题 */`

`input:focus{`

`    ``-webkit-user-modify:read-write-plaintext-only;`

`}`

`fieldset, img {`

`    ``border: 0;`

`}`

`a {`

`    ``text-decoration:none;`

`}`

`a,textarea,input{`

`    ``outline:none;`

`}`

`blockquote, q {`

`    ``quotes: none;`

`}`

`blockquote:before, blockquote:after, q:before, q:after {`

`  ``content: ``''``;`

`  ``content: none;`

`}`

`textarea {`

`    ``overflow:auto;resize:none;`

`}`

`// 以下是按照320下12像素字号走的,因为谷歌不识别小于12号字号`

`@media only screen and (min-width: 320px){`

`    ``html {`

`        ``font-size: 75%!important; ``/* 12÷16=75% */`

`    ``}`

`}`

`/**`

`    ``62.5%   10px;`

`    ``640 150%    24px;`

`    ``320除以标准比例 640  再乘以 640的基数24  再除以  HTML 根据基数16`

`    ``320/640  * 24 / 16 = 75%;`

`    ``375/640  * 24 / 16 = 87.89%;`

`    ``414/640  * 24 / 16 = 97.03%`

`*/`

`@media only screen and (min-width: 360px){`

`    ``html {`

`        ``font-size: 84.3%!important; ``/* 13.5÷16=84.3% */`

`    ``}`

`}`

`@media only screen and (min-width: 375px){`

`    ``html {`

`        ``font-size: 87.890625%!important; ``/* 14.0625÷16=87.890625% */`

`    ``}`

`}`

`@media only screen and (min-width: 384px){`

`    ``html {`

`        ``font-size: 90%!important; ``/* 14.4÷16=90% */`

`    ``}`

`}`

`@media only screen and (min-width: 390px){`

`    ``html {`

`        ``font-size: 91.4%!important; ``/* 14.625÷16=91.4% */`

`    ``}`

`}`

`@media only screen and (min-width: 412px){`

`    ``html {`

`        ``font-size: 96.56%!important; ``/* 15.45÷16=96.56% */`

`    ``}`

`}`

`@media only screen and (min-width: 414px){`

`    ``html {`

`        ``font-size: 97.03%!important; ``/* 15.525÷16=97.03% */`

`    ``}`

`}`

`@media only screen and (min-width: 480px){`

`    ``html {`

`        ``font-size: 112.5%!important; ``/* 18÷16=112.5% */`

`    ``}`

`}`

`@media only screen and (min-width: 560px){`

`    ``html {`

`        ``font-size: 131.25%!important;``/* 21÷16=131.25% */`

`    ``}`

`}`

`@media only screen and (min-width: 640px){`

`    ``html {`

`        ``font-size: 150%!important; ``/* 24÷16=150% */`

`    ``}`

`}`

`@media only screen and (min-width: 720px){`

`    ``html {`

`        ``font-size: 168.75%!important; ``/* 27÷16=168.75% */`

`    ``}`

`}`

`@media only screen and (min-width: 750px){`

`    ``html {`

`        ``font-size: 175.78125%!important; ``/* 28.125÷16=175.78125% */`

`    ``}`

`}`

`// @media only screen and (min-width: 800px){`

`//     html {`

`//         font-size: 187.5%!important; /* 30÷16=146.43% */`

`//     }`

`// }`

`// @media only screen and (min-width: 960px){`

`//     html {`

`//         font-size: 225%!important; /* 36÷16=146.43% */`

`//     }`

`// }`