# uni.previewImage(options)

预览图片

# previewImage 兼容性

Web 微信小程序 Android iOS HarmonyOS HarmonyOS(Vapor)
4.0 4.41 3.9 4.11 4.61 5.0

# 参数

名称 类型 必填 默认值 兼容性 描述
options PreviewImageOptions -
-
名称 类型 必备 默认值 兼容性 描述
current any -
current 为当前显示图片的链接/索引值,不填或填写的值无效则为 urls 的第一张。APP平台仅支持索引值。
urls Array<string.ImageURIString> -
需要预览的图片链接列表
showmenu boolean -
是否显示长按菜单
indicator "default" | "number" | "none" -
图片指示器样式
loop boolean -
是否可循环预览
longPressActions LongPressActionsOptions -
长按图片显示操作菜单。
名称 类型 必备 默认值 兼容性 描述
itemList Array<string> -
-
按钮的文字数组
itemColor string -
-
按钮的文字颜色,字符串格式,默认为"#000000"
success (result: LongPressActionsSuccessResult) => void -
-
接口调用成功的回调函数
fail (result: LongPressActionsFailResult) => void -
-
接口调用失败的回调函数
complete (result: any) => void -
-
接口调用结束的回调函数(调用成功、失败都会执行)
success (callback: PreviewImageSuccess) => void -
接口调用成功的回调函数
fail (callback: PreviewImageFail) => void -
接口调用失败的回调函数
complete (callback: any) => void -
接口调用结束的回调函数(调用成功、失败都会执行)
referrerPolicy string -
需要基础库: 2.13.0

origin: 发送完整的referrer; no-referrer: 不发送。格式固定为 https://servicewechat.com/{appid}/{version}/page-frame.html,其中 {appid} 为小程序的 appid,{version} 为小程序的版本号,版本号为 0 表示为开发版、体验版以及审核版本,版本号为 devtools 表示为开发者工具,其余为正式版本;
# LongPressActionsSuccessResult 的属性值
名称 类型 必备 默认值 兼容性 描述
tapIndex number -
-
接口调用失败的回调函数
index number -
-
接口调用结束的回调函数(调用成功、失败都会执行)
# LongPressActionsFailResult 的属性值
名称 类型 必备 默认值 兼容性 描述
errCode number -
-
错误码
合法值 兼容性 描述
1001
-
urls至少包含一张图片地址
1101001
-
用户取消
1101003
-
文件不存在
1101004
-
图片加载失败
1101005
-
未获取权限
1101010
-
其他错误
errSubject string -
-
统一错误主题(模块)名称
data any -
-
错误信息中包含的数据
cause Error -
-
源错误信息,可以包含多个错误,详见SourceError
errMsg string -
-

# PreviewImageSuccess 的属性值

名称 类型 必备 默认值 兼容性 描述
errSubject string -
调用API的名称
errMsg string -
描述信息

# PreviewImageFail 的属性值

名称 类型 必备 默认值 兼容性 描述
errCode number -
-
错误码
合法值 兼容性 描述
1001
-
urls至少包含一张图片地址
1101001
-
用户取消
1101003
-
文件不存在
1101004
-
图片加载失败
1101005
-
未获取权限
1101010
-
其他错误
errSubject string -
-
统一错误主题(模块)名称
data any -
-
错误信息中包含的数据
cause Error -
-
源错误信息,可以包含多个错误,详见SourceError
errMsg string -
-

# 示例

示例为hello uni-app x alpha分支,与最新HBuilderX Alpha版同步。与最新正式版同步的master分支示例另见

扫码体验(手机浏览器跳转到App直达页)

示例

<template>
  <!-- #ifdef APP -->
  <scroll-view style="flex: 1">
  <!-- #endif -->
    <view style="padding-left: 8px; padding-right: 8px">
      <view>
        <text class="text-desc">图片指示器样式</text>
        <radio-group class="cell-ct" style="background-color: white" @change="onIndicatorChanged">
          <view class="indicator-it" v-for="(item, index) in indicator" :key="item.value">
            <radio :disabled="isWeb" :checked="index == 0" :value="item.value">{{
              item.name
            }}</radio>
          </view>
        </radio-group>
      </view>
      <view>
        <checkbox-group @change="onCheckboxChange" style="margin-top: 16px; margin-left: 8px">
          <checkbox :disabled="isWeb" :checked="isLoop" style="margin-right: 15px">循环播放</checkbox>
        </checkbox-group>
      </view>
      <view>
        <text class="text-desc">长按行为</text>
        <radio-group class="cell-ct" style="background-color: white; margin-bottom: 16px;" @change="onLongPressCheckboxChange">
          <view class="indicator-it" v-for="(item, index) in longPressAction" :key="item.value">
            <radio :disabled="isWeb" :checked="index == 1" :value="item.value">{{
              item.name
            }}</radio>
          </view>
        </radio-group>
      </view>
      <view style="background-color: white">
        <text class="text-desc">点击图片开始预览</text>
        <view class="cell-ct" style="margin: 8px;">
          <view class="cell cell-choose-image" v-for="(image, index) in imageList" :key="index">
            <text style="width: 100px; height: 100px;background-color: lightgray; color: red; text-align: center; line-height: 100px;font-size: 14px;" v-if="image.error"
              @click="previewImage(index)">图片路径非法</text>
            <image style="width: 100px; height: 100px;background-color: white;" mode="aspectFit" :src="image.src"
              v-if="!image.error" @click="previewImage(index)"
              @error="onImageLoadError(index,$event as ImageErrorEvent)">
            </image>
          </view>
          <image class="cell cell-choose-image" src="/static/plus.png" @click="chooseImage">
          </image>
        </view>
      </view>
      <view style="margin:8px;">
        <text style="color: black;font-size: 18px;margin-bottom: 4px;">注意事项:</text>
        <text style="font-size: 17px;margin-left: 4px;color: darkgray;">1、indicator属性仅App平台支持。</text>
        <text style="font-size: 17px;margin-left: 4px;color: darkgray;">2、Web平台不支持loop属性。</text>
      </view>
    </view>
  <!-- #ifdef APP -->
  </scroll-view>
  <!-- #endif -->
</template>

<script setup lang="uts">
  type Indicator = "number" | "default" | "none"
  type ItemType = {
    value : Indicator,
    name : string
  }

  type ImageType = {
    src : string,
    error : boolean
  }

  type LongPressType = {
    value : string,
    name : string
  }

  const imageList = ref([
    { src: "https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/uni@2x.png", error: false },
    { src: "/static/test-image/logo.png", error: false },
    { src: "/static/test-image/logo.svg", error: false },
    // #ifdef APP
    { src: "/static/uni2.png", error: false },
    // #endif
  ] as ImageType[])

  const indicator = ref([{
    value: "default",
    name: "圆点"
  }, {
    value: "number",
    name: "数字"
  }, {
    value: "none",
    name: "不显示"
  }] as ItemType[])

  const longPressAction = ref([{
    value: "0",
    name: "默认长按行为"
  }, {
    value: "1",
    name: "自定义长按行为"
  }] as LongPressType[])

  const currentIndicator = ref("default"  as Indicator)

  // #ifdef WEB
  const isWeb = ref(true)
  // #endif
  // #ifndef WEB
  const isWeb = ref(false)
  // #endif

  // #ifdef APP-IOS
  const isIOS = ref(true)
  // #endif
  // #ifndef APP-IOS
  const isIOS = ref(false)
  // #endif

  const isLongPress = ref(true)
  const isLoop = ref(true)

  const previewImage = (index : number) => {
    let list = [] as Array<string>
    imageList.value.forEach((item : ImageType) => {
      list.push(item.src)
    })
    uni.previewImage({
      urls: list,
      current: index,
      indicator: currentIndicator.value,
      loop: isLoop.value,
      longPressActions: (isLongPress.value ? ({
        itemList: ["按钮1", "按钮2", "按钮3"],
        itemColor: "#ccc",
        success: (e : LongPressActionsSuccessResult) => {
          uni.showToast({
            title: "用户选中了第" + (e.index + 1) + "张图片,并选中了第" + (e.tapIndex + 1) + "个选项",
            position: "bottom"
          })
        },
        fail: (e : LongPressActionsFailResult) => {
          uni.showToast({
            title: "用户关闭了action sheet",
            position: "bottom"
          })
        }
      } as LongPressActionsOptions) : null)
    })
  }

  const chooseImage = () => {
    uni.chooseImage({
      sourceType: ['album'],
      count: 1,
      success: (e) => {
        imageList.value = imageList.value.concat({ src: e.tempFilePaths[0], error: false } as ImageType)
        // imageList.value = imageList.value.concat(e.tempFilePaths)
      },
      fail(_) {
      }
    })
  }

  const onIndicatorChanged = (e : UniRadioGroupChangeEvent) => {
    currentIndicator.value = e.detail.value as Indicator
  }

  const onCheckboxChange = (_ : UniCheckboxGroupChangeEvent) => {
    isLoop.value = !isLoop.value
  }

  const onLongPressCheckboxChange = (e: UniRadioGroupChangeEvent) => {
    isLongPress.value = (e.detail.value == "1")
  }

  const onImageLoadError = (index : number, error : UniImageErrorEvent) => {
    imageList.value[index].error = true
  }

  const closePreviewImage = ()=>{
    uni.closePreviewImage({})
  }

  const testSetCurrentIndicator = (value:string) =>{
    currentIndicator.value = value as Indicator
  }

  defineExpose({
  	testSetCurrentIndicator,
    previewImage,
    closePreviewImage
  })
</script>

<style>
  .text-desc {
    margin-top: 16px;
    margin-left: 8px;
    margin-bottom: 16px;
    font-weight: bold;
  }

  .cell-ct {
    display: flex;
    flex-wrap: wrap;
    flex-direction: row;
  }

  .cell {
    margin-left: 3px;
    margin-right: 3px;
    width: 100px;
    height: 100px;
  }

  .cell-choose-image {
    border-width: 1px;
    border-style: solid;
    border-color: lightgray;
  }

  .indicator-it {
    margin: 8px;
  }
  .cell-pd {
    padding: 11px 0px;
  }
</style>

# 参见

# 开源自定义

内置的previewImage弹出的界面,无法充分自定义。所以uni-app x提供了开源的previewImage页面,开发者可以自己定义UI。

开源插件地址:https://ext.dcloud.net.cn/plugin?id=21314

这个插件是ext api,下载到项目下会覆盖uni.previewImage的实现。

单独下载开源插件后,调用uni.previewImage,会在栈顶页面打开一个dialogPage,在父页面的getDialogPages中可以看到。使用内置的uni.previewImage看不到。

该开源插件目前仅支持Android。后续会补充其他平台。

# uni.closePreviewImage(options)

关闭图片预览

# closePreviewImage 兼容性

Web 微信小程序 Android iOS HarmonyOS HarmonyOS(Vapor)
4.0 x 3.9 4.11 4.61 5.0

# 参数

名称 类型 必填 默认值 兼容性 描述
options ClosePreviewImageOptions -
名称 类型 必备 默认值 兼容性 描述
success (callback: ClosePreviewImageSuccess) => void -
接口调用成功的回调函数
fail (callback: ClosePreviewImageFail) => void -
接口调用失败的回调函数
complete (callback: any) => void -
接口调用结束的回调函数(调用成功、失败都会执行)

# ClosePreviewImageSuccess 的属性值

名称 类型 必备 默认值 兼容性 描述
errMsg string -
错误信息

# ClosePreviewImageFail 的属性值

名称 类型 必备 默认值 兼容性 描述
errCode number -
错误码
合法值 兼容性 描述
1001
urls至少包含一张图片地址
1101001
用户取消
1101003
文件不存在
1101004
图片加载失败
1101005
未获取权限
1101010
其他错误
errSubject string -
统一错误主题(模块)名称
data any -
错误信息中包含的数据
cause Error -
源错误信息,可以包含多个错误,详见SourceError
errMsg string -

# 参见

# 通用类型

# GeneralCallbackResult

名称 类型 必备 默认值 兼容性 描述
errMsg string -
错误信息