美文网首页
React 点击删除列表中对应项

React 点击删除列表中对应项

作者: 谭瞎 | 来源:发表于2018-11-07 16:54 被阅读0次

    需求

    本周要实现一个上传图片的功能,简化应用场景:点击上传图片,增加一张图片,hover图片,出现删除按钮,点击删除按钮,删除该图片。

    效果

    delete.gif

    分析

    规划级别:图片+删除按钮作为一个子组件(此处是Image),整体作为一个父组件

    注意的点:生成的组件是一个数组,为了准确的删掉对应项,生成对应编号。点击删除按钮反馈当前编号,然后进行删除。由于子组件生成后,index属性是固定的,当删除元素的时候就不知道是哪个元素,所以可以通过自定义属性data-index来获取子组件的编号。

    具体逻辑:数据驱动,使用数据展示界面,在state里保存要展示的数据,在render里动态生成子组件,render里的子组件会根据数据的变化而刷新。

    实现

    子组件

    export default class Image extends Component {
    
      constructor(props) {
        super(props);
        this.state = {}
      }
    
      render() {
        let {
          index,
          deleteImage,
        } = this.props;
    
        return (
          <div
            className="upload-pic">
            <span className="upload-pic-left"/>
            <div className="upload-pic-right">
              <img
                className="upload-pic-thumbnail"
              />
              <span className="upload-pic-mask"
                    onClick={deleteImage}
                    data-index={index}
              />
            </div>
          </div>
        )
      }
    }
    

    渲染组件:

    render(){
        let {
          fileList
        } = this.state;
        
        return(
            {
              fileList.map((item, index) => {
                return (
                  (
                    <Image
                      key={index}
                      index={index}
                      src={item[0].thumb}
                      alt={item[0].name}
                      deleteImage={this.deleteImage}/>
                  )
                )
              })
            }
        )
    }
    

    添加图片:

      // 添加图片
      addImage(e) {
        
        let {
          fileList
        } = this.state;
    
        e.preventDefault();
    
        // 判断是否能上传
        this.getUpload(e);
    
        // 判断是否满足条件
        if (isUploadSize && isUploadLengthLimit) {
          fileList.push(globalFileObj);
          this.setState({
            fileList: fileList
          });
        } else {
          console.log('失败');
        }
      };
    

    鼠标事件

    父组件代码如下:

      // 鼠标移进
      handleMouseOver(e) {
        this.isShowMask(e,true);
      }
    
      // 鼠标移出
      handleMouseOut(e) {
        this.isShowMask(e,false);
      }
    
      // 是否显示遮罩层
      isShowMask(e,bool){
        e.preventDefault();
        let index = e.currentTarget.getAttribute("data-index");
        let {fileList} = this.state;
        fileList[index].isHover = bool;
        this.setState({
          fileList: fileList
        })
      }
      
      render(){
        let {
          fileList
        } = this.state;
        
        return(
            {
              fileList.map((item, index) => {
                return (
                  (
                    <Image
                      key={index}
                      index={index}
                      src={item[0].thumb}
                      alt={item[0].name}
                      isHover={item.isHover}
                      handleMouseOver={this.handleMouseOver}
                      handleMouseOut={this.handleMouseOut}
                      deleteImage={this.deleteImage}/>
                  )
                )
              })
            }
        )
    }
      
    

    e.target和e.currentTarget的区别

    此处需要注意一下e.target和e.currentTarget的区别,e.currentTarget指的是注册事件对象,e.target指的是实际触发事件对象,简单来说,当使用e.target的时候,虽然事件绑定在父级上,但是当经过子节点的时候,e.target指向子节点,而使用e.currentTarget,始终指向注册事件对象(此处为父节点)。

    如何区分悬浮在哪个子组件上

    当获取到每个子组件标示的data-index之后,利用fileList[index].isHover = false; 并将标识传给子组件(此处是isHover={item.isHover}),子组件再根据标识,做出一些特殊行为。

    子组件代码如下:

    export default class Image extends Component {
      
      render() {
        let {
          src,
          alt,
          index,
          deleteImage,
          handleMouseOver,
          handleMouseOut,
          isHover
        } = this.props;
    
        return (
          <div
            className={`upload-pic ${isHover ? 'upload--mask' : ''}`}>
            <span className="upload-pic-left"/>
            <div className="upload-pic-right"
                 onMouseOver={handleMouseOver}
                 onMouseOut={handleMouseOut}
                 data-index={index}
            >
              <img
                className="upload-pic-thumbnail"
                src={src}
                alt={alt}
              />
              <span className="upload-pic-mask"
                    onClick={deleteImage}
                    data-index={index}
              />
            </div>
          </div>
        )
      }
    }
    

    删除图片:

    使用splice(index,1)删除当前元素,改变原数组,且更新state

      // 删除图片
      deleteImage(e) {
        e.preventDefault();
        
        let {fileList} = this.state;
        
        let index = e.target.getAttribute("data-index");
        fileList.splice(index, 1);
    
        this.setState({
          fileList: fileList
        })
      }
    

    相关文章

      网友评论

          本文标题:React 点击删除列表中对应项

          本文链接:https://www.haomeiwen.com/subject/syivxqtx.html