antdPopover的动态变色和动态visable


目的: 使用Popover制作动态的变色和控制Visable

引入相关文件

import React, { useState } from 'react';
import cxs from 'classnames'
import { Popover } from 'antd';
import '../../iconfont/iconfont.css'
import "./popovers.css";
function Popovers() {
  const [chooseIndex, setChooseIndex] = useState(undefined)
  const list = [
    { "name": "Rose", "age": 22 },
    { "name": "Eric", "age": 18 },
    { "name": "Mary", "age": 25 },
    { "name": "Lucy", "age": 28 },
    { "name": "Alice", "age": 21 },
    { "name": "Jack", "age": 29 },
    { "name": "Bruce", "age": 27 },
    { "name": "Tian", "age": 25 },
    { "name": "JuDiao", "age": 24 },
    { "name": "Niuheng", "age": 31 },
    { "name": "KaiDi", "age": 26 },
    { "name": "Haohao", "age": 26 },
    { "name": "Wind", "age": 23 }
  ]

  const closeList = (index) => {
    console.log('close')
    setChooseIndex()  // 每次关闭也会重新return? 渲染的是全部视图还是局部视图
    // stopPropagation 阻止事件冒泡
  }
  const renderContent = (item, index) => {  // 函数组件的函数,还必须const
    console.log(item)
    return <div className={cxs('content-wrap')}>
      <div className={cxs("content-top")}>
        <div className={cxs('content-top-left')}><h1>Name:</h1><p>{item.name}</p></div>
        <div 
        onClick={(e) => {
          e.stopPropagation()   // 此处必须阻止冒泡事件,否则会触发父元素的点击事件,导致子元素的点击事件点击了但是没效果
          closeList(index)      // ***这是因为事件冒泡触发父元素点击对值重新赋值了***
        }}
        className={cxs('content-top-right')}>
          <i className="icon iconfont">&#xe607;</i>
        </div>
      </div>
      <div className={cxs("content-bottom")}>
        <h2>Have a good nice Day !</h2>
      </div>
    </div>
  }
  const changeColorAndIndex = (item, index) => {
    // console.log(item, index)
    // console.log('changeIndex')
    setChooseIndex(index)   // 中间值与下标相等了 ,完成了两件事,被点击元素变色,被点击元素的pop显示,其他不显示!
  }
 
  return (
    <div className={cxs('wrap')}>
      <header>点名</header>
      {list.map( (item, index) => {
        return <div 
        key={index}
        id='item-info'    
        className={cxs({"activeIndex": chooseIndex === index})}  //1. 若类名与中间值相等,就出现变化的背景色
        onClick={() => {changeColorAndIndex(item, index)}}    //3.  使中间值和下标相等的事件。触发器
        >
        <Popover
          content={renderContent(item, index)}
          trigger="click"
          getPopupContainer={() => document.getElementById("item-info")}  // 绑定渲染父级
          visible={chooseIndex === index}     //2. 同理,若下标和中间值相同就显示
        >
          <div className={cxs("item-onfo1")}>
            <div className={cxs('item-info-left')}>{item.name}</div>
            <div className={cxs('item-info-right')}>{item.age}</div>
          </div>
        </Popover>
      </div>
      })}
    </div>
  )
}

export default Popovers
关于为什么popover要绑定父级
// popover的默认渲染父级是body ,这在有些时候会出问题,例如元素错位(当然在目前看来是没有问题的,为了严谨)
getPopupContainer={() => document.getElementById("item-info")}
css:
// 给父级元素相对定位,高度
// 给子元素向左的距离
.ant-popover {
    left: 415px  !important;
    top: 0 !important;
}
.ant-popover-arrow{
    display: none  !important;
}

.ant-popover-inner-content{
    padding: 0  !important;
    width: 400px;
    height: 270px;
}
完整css


.wrap{
    width: 400px;
    height: 900px;
    margin-top: 40px;
    margin-left: 50px;
    background: rgba(0, 0, 0, .6);
}

header{
    height: 50px;
    margin-bottom: 15px;
    /* text-align: center; */
    line-height: 50px;
    font-size: 18px;
    color: seagreen;
    padding-left: 16px;
    font-weight: 700;
}
#item-info{
    height: 40px;
    padding: 0 16px;
    position: relative;
}

.activeIndex{
    background: #cccccc;
}

.item-onfo1{
    height: 100%;
    display: flex;
    font-size: 14px;
    padding: 11px 0;
    justify-content: space-between;
    border-bottom: 1px solid #cccccc;
}

.item-info-left{
    color: blueviolet;
}
.item-info-right{
    color: brown;
}

.ant-popover {
    left: 415px  !important;
    top: 0 !important;
}
.ant-popover-arrow{
    display: none  !important;
}

.ant-popover-inner-content{
    padding: 0  !important;
    width: 400px;
    height: 270px;
}


/* content */
.content-wrap{
    padding: 14px 16px;
    height: 100%;
}
.content-top{
    height: 50px;
    display: flex;
    justify-content: space-between;
}

.content-bottom{
    /* less 预编译  要  calc(~"100% - 50px") */
    height: calc(100% - 50px);  
}

.content-top-left{
    display: flex;
}
.content-top-left p{
    margin-left: 20px;
    line-height: 50px;
}
.content-top-left h1{
    color: crimson;
}
.content-top-right {
    line-height: 50px;
}

.content-top-right i {
    color: lightseagreen;
    font-weight: 800;
}
.content-bottom h2{
    color: dodgerblue;
}


文章作者: KarlFranz
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 reprint policy. If reproduced, please indicate source KarlFranz !
评论
  目录