一、描述

rax-picture 是 rax 内置的数据展示组件,主要用来展示大图,与 rax-image 组件相比,可以根据原始图片大小自动计算高度等。而且使用阿里的 cdn 有部分的优化策略。

由于 weex 的策略是图片的处理依赖于客户端使用的 adapter 或者是 handler,所以 gif 图也是依赖客户端的

文档地址:

关于支持的 props 不单独重复了,可以具体去查看文档。

二、源码分析之 picture.weex.js

由于 rax-picture 的源码太多了,而且分为了 web 容器和 weex 容器明显的不同的处理策略,因此单独拿出来分析。

rax-picture 的 index.js 中直接就是判断 isWeex 还是 isWeb,然后直接加载不同的组件源码,分别是 index.weex.jsindex.web.js,除此之外,还包括 webp.js 对 webp 格式文件进行单独处理。

1、props

weex 容器支持的 props 相比于 web 容器少了很多,主要包含以下:

props类型说明
styleObject样式对象,style.width 是必须的
sourceobject{{uri:'xxx'}}
resizeModeStringcontain,cover,stretch
widthString原始宽度
heightString原始高度
defaultHeightString默认图片高度
forceUpdateBoolean是否忽略 shouldComponentUpdate

其中,默认 props 只写了一个 defaultHeight:750

2、组件更新策略

rax-picture 默认的策略是,只有当组件的 props.source.uri 发生变化时才会更新组件,rax-picture 是一个 PureComponent。

其中,只有当配置了 forceUpdate = true 之后,才会忽略默认的配置。

shouldComponentUpdate(nextProps) {
  if (this.props.forceUpdate || this.props.children) {
    return true;
  }

  return this.props.source.uri !== nextProps.source.uri;
}

3、渲染

weex 容器环境中最终还是渲染的 rax-image,只不过在 render 中进行了一系列的处理。

其中,根据图片的原始宽高计算高度在 render 中完成(其实明明可以拿出去的,没必要放在 render 中,不过因为 rax-picture 是一个 PureComponent,所以放在 render 中也无所谓了)

通过原始宽高计算高度的前提必须是设置了 props.style.width,才能计算 height,计算方法很简单,无非就是个比例的问题。

// according to the original height and width of the picture
if (!styleHeight && styleWidth && width && height) {
  const pScaling = width / parseInt(styleWidth, 10);
  styleHeight = parseInt(height / pScaling, 10);
}

因为 rax-image 本身就支持 resizeMode 属性,因此直接将 resizeMode 挂到 image 组件上就行了,这个过程没什么特殊处理的。

同样的,因为 rax-image 本身就支持子组件,所以 props.children 也是直接挂到了 image 组件内部。

三、实践

在 weex 容器环境中示例:

import {createElement, Component} from 'rax';
import View from 'rax-view';
import Text from 'rax-text';
import Picture from 'rax-picture';
import styles from './App.css';

const img = 'https://camo.githubusercontent.com/27b9253de7b03a5e69a7c07b0bc1950c4976a5c2/68747470733a2f2f67772e616c6963646e2e636f6d2f4c312f3436312f312f343031333762363461623733613132336537386438323436636438316338333739333538633939395f343030783430302e6a7067';

class App extends Component {
  render() {
    return (
      <View style={styles.app}>
          <Picture 
             source={{uri: img}}
            style={{width:400,height:300}}
            resizeMode="cover" 
          ></Picture> 
      </View>
    );
  }
}

export default App;

效果:

微信图片_20180903004126.jpg

恕咱直言,在 weex 环境,除了计算动态计算高度外,没有发现其他相比于 rax-image 组件优势的地方

当然动态计算高度在某些应用场景下是必须的,最近我的一个项目就需要动态计算高度,如果自己写的话,还需要单独封装,rax-picture 就很方便

rax-picture 在 web 容器环境下,做的工作更多,另一篇 picture.web.js 的源码分析文章地址: