Img 图片组件

ICE 图片组件,用来增强图片显示效果。

安装和升级

npm i @icedesign/img -S

参数(props)

参数名 说明 必填 类型 默认值 可选值 备注
type 图片显示模式 false string cover cover、contain
src 图片 url true string
shape 形状展现 false string sharp circle、sharp、rounded
title 图片的 title,hover 上去会显示出来 false string ''
alt 图片的 alt 通常用于屏幕阅读器(盲人)识别 false string ''
className 图片的 className false string ''
style 图片的 inline style false object {}
width 图片显示宽度 false number 计算图片必需,不传则表现形式等同于普通 img 标签。
height 图片显示高度 false number 计算图片必需,不传则表现形式等同于普通 img 标签。
errorImgSrc 图片加载失败的兜底图片 false string 如果图片加载失败,那么将用这张图来代替
onError 图片加载失败的回调方法 false function 如果图片加载失败,那么将执行这个 callback 让你添加一些容错逻辑
enableAliCDNSuffix 是否启用 Ali CDN 自动裁切参数 false false 如果在 cover 模式下,图片高度太高可能会拉伸的比较模糊

图片底部存在 3px 空隙的解决方法

如果你将当前组件用来展示图片放在其他组件内,或者使用当前组件时有外边线,细致的你会发现底部可能存在 3px 的间隙:

image

这是由于图片的 inline-block 渲染模式导致的,你无需理解背后的原理,如果你想去掉这个间隙,可以直接在当前组件加上一行 CSS 即可:

<Img
  style={{
    verticalAlign: 'middle',
  }}
  src="xxx"
/>

图片尺寸性能优化

图片原图可能会非常大,例如 https://img.alicdn.com/tps/TB1qfWuMVXXXXcEXpXXXXXXXXXX-434-254.png 会达到 200kb 但实际放在页面上,希望它只显示 200x100 这样的尺寸,此时性能就会很差。

如果你的图片使用 img.alicdn.com 这个 CDN 地址,那么可以传入 props enableAliCDNSuffix={true} 将自动开启 Ali CDN 裁切参数,会将图片 url 变成 https://img.alicdn.com/tps/TB1qfWuMVXXXXcEXpXXXXXXXXXX-434-254.png_400x200q90.jpg 进行压缩优化,压缩之后图片只有 116kb,加载性能会提升非常多,建议默认开启使用。

如果在 cover 模式下,如果图片尺寸跟配置的显示尺寸差距太大,可能会导致拉伸变模糊,如果绝大部分图片都是此类尺寸,可以设置 false 去掉这个功能。

DEMO 列表

简单的用法

本 Demo 演示最基础的用法。

import React, {Component} from 'react';
import ReactDOM from 'react-dom';
import {Button} from '@alifd/next';
import Img from '@icedesign/img';

class App extends Component {

  state = {
    url1: 'https://img.alicdn.com/tfs/TB1vyxuwHrpK1RjSZTEXXcWAVXa-1350-900.jpg',
    url2: 'https://img.alicdn.com/tfs/TB1A8NCLNYaK1RjSZFnXXa80pXa-2580-1032.jpg'
  };

  changeImgs = () => {
    this.setState({
      url1: getImgs(this.state.url1),
      url2: getImgs(this.state.url1)
    });
  };

  render() {
    return (
      <div>
        <h1>cover 模式强调填充铺平</h1>
        <Img
          enableAliCDNSuffix={true}
          width={400}
          height={200}
          src={this.state.url1}
          type="cover"
          style={{border: '1px solid #ccc', margin: '10px'}}
        />
        <Img
          enableAliCDNSuffix={false}
          width={400}
          height={200}
          src={this.state.url2}
          type="cover"
          style={{border: '1px solid #ccc', margin: '10px'}}
        />
        <h1>contain 模式强调信息全部展示</h1>
        <Img
          enableAliCDNSuffix={true}
          width={400}
          height={200}
          src={this.state.url1}
          type="contain"
          style={{border: '1px solid #ccc', margin: '10px'}}
        />
        <Img
          enableAliCDNSuffix={true}
          width={400}
          height={200}
          src={this.state.url2}
          type="contain"
          style={{border: '1px solid #ccc', margin: '10px'}}
        />
        <div>
          <Button type="primary" style={{marginTop: 20}} onClick={this.changeImgs}>切换新图片会重新计算尺寸</Button>
        </div>
      </div>
    );
  }
}

function getImgs(url) {
  if (url === 'https://img.alicdn.com/imgextra/i3/2779138589/TB2_gtLlrBmpuFjSZFuXXaG_XXa_!!2779138589.jpg') {
    return 'https://img.alicdn.com/tfs/TB1vyxuwHrpK1RjSZTEXXcWAVXa-1350-900.jpg';
  }

  return 'https://img.alicdn.com/imgextra/i3/2779138589/TB2_gtLlrBmpuFjSZFuXXaG_XXa_!!2779138589.jpg';
}

ReactDOM.render((
  <App />
), mountNode);

用在表格中

本 Demo 演示在表格中使用图片。

import React, {Component} from 'react';
import ReactDOM from 'react-dom';
import {Table} from '@alifd/next';
import Img from '@icedesign/img';


class App extends Component {

  state = {

  }

  renderCover = (value, index, record) => {
    let type = 'cover';
    if (index % 3 === 0) {
      type = 'contain';
    }
    return (
      <div>
        <Img
          enableAliCDNSuffix={true}
          width={200}
          height={100}
          src={record.src}
          type={type}
        />
        当前图片模式:{type}
      </div>
    );
  };

  render() {
    return (
      <div>
        <Table
          dataSource={tableData}
        >
            <Table.Column title="封面图" cell={this.renderCover} />
            <Table.Column title="标题" dataIndex="title" />
        </Table>
      </div>
    );
  }
}

const tableData = [{
  src: 'https://img.alicdn.com/tfs/TB1vyxuwHrpK1RjSZTEXXcWAVXa-1350-900.jpg',
  title: '这是一张示例图片这是一张示例图片这是一张示例图片这是一张示例图片',
}, {
  src: 'https://img.alicdn.com/tfs/TB1A8NCLNYaK1RjSZFnXXa80pXa-2580-1032.jpg',
  title: '示例图片2号示例图片2号示例图片2号示例图片2号'
}, {
  src: 'https://img.alicdn.com/tfs/TB1vyxuwHrpK1RjSZTEXXcWAVXa-1350-900.jpg',
  title: '这是一张示例图片这是一张示例图片这是一张示例图片这是一张示例图片',
}, {
  src: 'https://img.alicdn.com/tfs/TB1A8NCLNYaK1RjSZFnXXa80pXa-2580-1032.jpg',
  title: '示例图片2号示例图片2号示例图片2号示例图片2号'
}, {
  src: 'https://img.alicdn.com/tfs/TB1vyxuwHrpK1RjSZTEXXcWAVXa-1350-900.jpg',
  title: '这是一张示例图片这是一张示例图片这是一张示例图片这是一张示例图片',
}, {
  src: 'https://img.alicdn.com/tfs/TB1A8NCLNYaK1RjSZFnXXa80pXa-2580-1032.jpg',
  title: '示例图片2号示例图片2号示例图片2号示例图片2号'
}, {
  src: 'https://img.alicdn.com/tfs/TB1vyxuwHrpK1RjSZTEXXcWAVXa-1350-900.jpg',
  title: '这是一张示例图片这是一张示例图片这是一张示例图片这是一张示例图片',
}, {
  src: 'https://img.alicdn.com/tfs/TB1A8NCLNYaK1RjSZFnXXa80pXa-2580-1032.jpg',
  title: '示例图片2号示例图片2号示例图片2号示例图片2号'
}];

ReactDOM.render((
  <App />
), mountNode);

图片加载失败

图片加载失败的处理方法。

import React, {Component} from 'react'
import ReactDOM from 'react-dom';

import Img from '@icedesign/img';

class App extends Component {

  state = {
    imgSrc: 'https://im---g.alicdn.com/tps/TB1qfWuMVXXXXcEXpXXXXXXXXXX-434-254.png'
  }

  handleImgError = () => {
    // 你可以额外添加一些容错处理业务逻辑
    // console.log('图片报错啦!日志记录下');
    this.setState({
      imgSrc: 'https://img.alicdn.com/tps/TB11W.WOXXXXXcbaXXXXXXXXXXX-496-310.png'
    });
  };

  render() {
    return (
      <div>
        <h1>图片加载失败可以监听 onError 事件,并改变 State 实现</h1>
        <p>用于对图片加载失败做更多业务逻辑处理</p>
        <Img
          enableAliCDNSuffix={true}
          width={400}
          height={200}
          onError={this.handleImgError}
          src={this.state.imgSrc}
          type="cover"
          style={{border: '1px solid #ccc', margin: '10px'}}
        />
        <h1>或者通过设置 errorImgSrc props 会自动在出错的时候替换掉</h1>
        <Img
          enableAliCDNSuffix={true}
          width={400}
          height={200}
          errorImgSrc="https://img.alicdn.com/tps/TB11W.WOXXXXXcbaXXXXXXXXXXX-496-310.png"
          src="https://im---g.alicdn.com/tps/TB1qfWuMVXXXXcEXpXXXXXXXXXX-434-254.png"
          type="cover"
          style={{border: '1px solid #ccc', margin: '10px'}}
        />
      </div>
    );
  }
}

ReactDOM.render((
  <App />
), mountNode);

shape 形状用法

本 Demo 演示 shape 形状的用法。

shape 默认为 rounded sharp 无圆角 circle 圆形

import React, {Component} from 'react';
import ReactDOM from 'react-dom';
import Img from '@icedesign/img';


class App extends Component {

  state = {

  }

  render() {
    return (
      <div>
        <h1>cover 模式下展示</h1>
        <Img
          enableAliCDNSuffix={true}
          width={200}
          height={200}
          src="//img.alicdn.com/tfs/TB1K..3PpXXXXa4XFXXXXXXXXXX-311-199.png"
          type="cover"
          shape="circle"
          style={{border: '1px solid #ccc', margin: '10px'}}
        />
        <Img
          enableAliCDNSuffix={true}
          width={300}
          height={200}
          src="//img.alicdn.com/tfs/TB1oPNcPFXXXXXQXpXXXXXXXXXX-341-202.png"
          type="cover"
          shape="sharp"
          style={{border: '1px solid #ccc', margin: '10px'}}
        />
        <Img
          enableAliCDNSuffix={true}
          width={300}
          height={200}
          src="//img.alicdn.com/tfs/TB1oPNcPFXXXXXQXpXXXXXXXXXX-341-202.png"
          type="cover"
          style={{border: '1px solid #ccc', margin: '10px'}}
        />

        <h1>contain 模式下展示</h1>

        <Img
          enableAliCDNSuffix={true}
          width={300}
          height={200}
          src="//img.alicdn.com/tfs/TB1A2c4PpXXXXaiXFXXXXXXXXXX-274-201.png"
          type="contain"
          style={{border: '1px solid #ccc', margin: '10px'}}
        />
        <Img
          enableAliCDNSuffix={true}
          width={350}
          height={200}
          src="//img.alicdn.com/tfs/TB17wwYPpXXXXXHXVXXXXXXXXXX-297-199.png"
          type="contain"
          shape="sharp"
          style={{border: '1px solid #ccc', margin: '10px'}}
        />
        <Img
          enableAliCDNSuffix={true}
          width={200}
          height={200}
          src="//img.alicdn.com/tfs/TB17wwYPpXXXXXHXVXXXXXXXXXX-297-199.png"
          type="contain"
          shape="circle"
          style={{border: '1px solid #ccc', margin: '10px'}}
        />
      </div>
    );
  }
}

ReactDOM.render((
  <App />
), mountNode);