Image 图片
图片容器,在保留原生 img 的特性下,支持懒加载,自定义占位、加载失败等
TIP
若在 Image 上启用 preview 功能,或单独使用 ea-image-preview 组件,请在等待 ea-image-preview 组件定义完成之后再进行 js 操作。(特别在 Vue 环境中)
await customElements.whenDefined("ea-image-preview");引入
<script type="module">
import "./node_modules/easy-component-ui/dist/components/ea-image.js";
</script>import "easy-component-ui/ea-image";自定义样式
移步到 CSS Part。
基础用法
可通过
fit确定图片如何适应到容器框,同原生object-fit。
查看代码
<div class="demo">
<ea-image
fit="fill"
width="100px"
height="100px"
src="https://tse2-mm.cn.bing.net/th/id/OIP-C.mH9YLFEL5YdVxJM82mjVJQAAAA?rs=1&pid=ImgDetMain"
></ea-image>
<ea-image
width="100px"
height="100px"
fit="contain"
src="https://tse2-mm.cn.bing.net/th/id/OIP-C.mH9YLFEL5YdVxJM82mjVJQAAAA?rs=1&pid=ImgDetMain"
></ea-image>
<ea-image
width="100px"
height="100px"
fit="cover"
src="https://tse2-mm.cn.bing.net/th/id/OIP-C.mH9YLFEL5YdVxJM82mjVJQAAAA?rs=1&pid=ImgDetMain"
></ea-image>
<ea-image
width="100px"
height="100px"
fit="none"
src="https://tse2-mm.cn.bing.net/th/id/OIP-C.mH9YLFEL5YdVxJM82mjVJQAAAA?rs=1&pid=ImgDetMain"
></ea-image>
<ea-image
width="100px"
height="100px"
fit="scale-down"
src="https://tse2-mm.cn.bing.net/th/id/OIP-C.mH9YLFEL5YdVxJM82mjVJQAAAA?rs=1&pid=ImgDetMain"
></ea-image>
</div>占位内容
在 slot="placeholder" 插槽中自定义占位内容。点击 Reload 按钮可重新加载图片,观察占位内容到加载完成的过渡效果。
查看代码
<div class="demo">
<ea-image
id="placeholderImage"
class="image"
width="200px"
height="150px"
fit="cover"
src=""
>
<div class="image-slot" slot="placeholder">
Loading<span class="dot">...</span>
</div>
</ea-image>
<ea-button id="reloadButton">Reload</ea-button>
</div>.image-slot {
margin: auto;
}const placeholderExample = {
image: document.querySelector("#placeholderImage"),
button: document.querySelector("#reloadButton"),
async init() {
await customElements.whenDefined("ea-image");
this.button.addEventListener("click", () => {
this.image.setAttribute("src", "");
setTimeout(() => {
this.image.setAttribute(
"src",
"https://tse2-mm.cn.bing.net/th/id/OIP-C.mH9YLFEL5YdVxJM82mjVJQAAAA?rs=1&pid=ImgDetMain"
);
}, 500);
});
},
};
placeholderExample.init();加载失败
查看代码
<div class="demo error">
<ea-image></ea-image>
<ea-image>
<ea-icon slot="error" name="image" size="30"></ea-icon>
</ea-image>
</div>.error ea-image {
width: 150px;
height: 200px;
}懒加载
TIP
您可以使用 loading="lazy" 替换之前的lazy = true。
如果当前浏览器支持原生图片延迟加载,则先使用原生能力,否则将使用滚动监听实现相同效果。
可通过lazy开启懒加载功能, 当图片滚动到可视范围内才会加载。 可通过 scroll-container 来设置滚动容器, 若未定义,则为最近一个 overflow 值为 auto 或 scroll 的父元素。
单项
查看代码
<div class="demo">
<ea-image
src="https://tse2-mm.cn.bing.net/th/id/OIP-C.mH9YLFEL5YdVxJM82mjVJQAAAA?rs=1&pid=ImgDetMain"
lazy
></ea-image>
</div>多项
查看代码
<div class="demo lazy">
<ea-image
src="https://tse2-mm.cn.bing.net/th/id/OIP-C.mH9YLFEL5YdVxJM82mjVJQAAAA?rs=1&pid=ImgDetMain"
lazy
></ea-image>
<ea-image
src="https://th.bing.com/th/id/R.d88442788ee5a458d50e40f0a8cb1e05?rik=EoPp8GhejYeQfw&riu=http%3a%2f%2fimg.pconline.com.cn%2fimages%2fupload%2fupc%2ftx%2fwallpaper%2f1307%2f10%2fc2%2f23151595_1373424485102.jpg&ehk=J7xq%2f50bCmdD4jUXfnTlau2s5WiVsBxQArAjvJzqIo4%3d&risl=&pid=ImgRaw&r=0"
lazy
></ea-image>
<ea-image
src="https://www.keaitupian.cn/cjpic/frombd/0/253/4061721412/2857814056.jpg"
lazy
></ea-image>
<ea-image
src="https://www.keaitupian.cn/cjpic/frombd/2/253/2107631312/3178897554.jpg"
lazy
></ea-image>
<ea-image
src="https://tse3.mm.bing.net/th/id/OIP.sPgwHtYKbg6cTN5LBYF_nQHaEK?cb=12&rs=1&pid=ImgDetMain&o=7&rm=3"
lazy
></ea-image>
<ea-image
src="https://tse1.mm.bing.net/th/id/OIP.VS7qtQiQgNuBk2SVdwvxagHaEk?rs=1&pid=ImgDetMain&o=7&rm=3"
lazy
></ea-image>
<ea-image
src="https://www.keaitupian.cn/cjpic/frombd/1/253/2032688566/3458490751.jpg"
lazy
></ea-image>
</div>.lazy {
height: 200px;
width: 500px;
overflow: auto;
}
.lazy ea-image {
height: 200px;
width: 100%;
}图片预览
可通过 previewSrcList 开启预览大图的功能。 你可以通过 initial-index 初始化第一张预览图片的位置。 默认初始位置为 0。
查看代码
<div class="demo">
<ea-image
id="previewImage"
style="width: 100px; height: 100px"
class="viewer"
src="https://tse1.mm.bing.net/th/id/OIP.rTMre-V-rMq3T1EP9W7vlAHaEK?cb=12&rs=1&pid=ImgDetMain&o=7&rm=3"
preview
zoom-rate="1.2"
max-scale="7"
min-scale="0.2"
initial-index="4"
fit="cover"
show-progress
>
</ea-image>
</div>const previewExample = {
image: document.querySelector("#previewImage"),
list: [
"https://tse2-mm.cn.bing.net/th/id/OIP-C.mH9YLFEL5YdVxJM82mjVJQAAAA?rs=1&pid=ImgDetMain",
"https://th.bing.com/th/id/R.d88442788ee5a458d50e40f0a8cb1e05?rik=EoPp8GhejYeQfw&riu=http%3a%2f%2fimg.pconline.com.cn%2fimages%2fupload%2fupc%2ftx%2fwallpaper%2f1307%2f10%2fc2%2f23151595_1373424485102.jpg&ehk=J7xq%2f50bCmdD4jUXfnTlau2s5WiVsBxQArAjvJzqIo4%3d&risl=&pid=ImgRaw&r=0",
"https://www.keaitupian.cn/cjpic/frombd/0/253/4061721412/2857814056.jpg",
"https://www.keaitupian.cn/cjpic/frombd/2/253/2107631312/3178897554.jpg",
"https://tse3.mm.bing.net/th/id/OIP.sPgwHtYKbg6cTN5LBYF_nQHaEK?cb=12&rs=1&pid=ImgDetMain&o=7&rm=3",
"https://tse1.mm.bing.net/th/id/OIP.VS7qtQiQgNuBk2SVdwvxagHaEk?rs=1&pid=ImgDetMain&o=7&rm=3",
"https://www.keaitupian.cn/cjpic/frombd/1/253/2032688566/3458490751.jpg",
],
async init() {
await customElements.whenDefined("ea-image");
this.image.previewSrcList = this.list;
},
};
previewExample.init();手动打开预览
查看代码
<div class="demo">
<ea-button id="showPreviewButton">
openPreview with showPreview method
</ea-button>
<ea-button id="previewControlledButton"> preview controlled </ea-button>
<section>
<ea-image
id="showPreviewImage"
style="width: 100px; height: 100px"
class="viewer"
src="https://tse1.mm.bing.net/th/id/OIP.rTMre-V-rMq3T1EP9W7vlAHaEK?cb=12&rs=1&pid=ImgDetMain&o=7&rm=3"
preview
zoom-rate="1.2"
max-scale="7"
min-scale="0.2"
initial-index="4"
fit="cover"
show-progress
>
</ea-image>
</section>
<section>
<ea-image-preview id="previewControlledImage" show-progress>
<section class="viewer-error" slot="viewer-error">viewer-error</section>
<section slot="toolbar">toolbar</section>
<section slot="progress">
<span data-active></span> //
<span data-total></span>
</section>
</ea-image-preview>
</section>
</div>const imageHandlerExample = {
showPreviewButton: document.querySelector("#showPreviewButton"),
previewControlledButton: document.querySelector("#previewControlledButton"),
showPreviewImage: document.querySelector("#showPreviewImage"),
previewControlledImage: document.querySelector("#previewControlledImage"),
list: [
"https://tse2-mm.cn.bing.net/th/id/OIP-C.mH9YLFEL5YdVxJM82mjVJQAAAA?rs=1&pid=ImgDetMain",
"https://th.bing.com/th/id/R.d88442788ee5a458d50e40f0a8cb1e05?rik=EoPp8GhejYeQfw&riu=http%3a%2f%2fimg.pconline.com.cn%2fimages%2fupload%2fupc%2ftx%2fwallpaper%2f1307%2f10%2fc2%2f23151595_1373424485102.jpg&ehk=J7xq%2f50bCmdD4jUXfnTlau2s5WiVsBxQArAjvJzqIo4%3d&risl=&pid=ImgRaw&r=0",
"https://www.keaitupian.cn/cjpic/frombd/0/253/4061721412/2857814056.jpg",
"https://www.keaitupian.cn/cjpic/frombd/2/253/2107631312/3178897554.jpg",
"https://tse3.mm.bing.net/th/id/OIP.sPgwHtYKbg6cTN5LBYF_nQHaEK?cb=12&rs=1&pid=ImgDetMain&o=7&rm=3",
"https://tse1.mm.bing.net/th/id/OIP.VS7qtQiQgNuBk2SVdwvxagHaEk?rs=1&pid=ImgDetMain&o=7&rm=3",
"https://www.keaitupian.cn/cjpic/frombd/1/253/2032688566/3458490751.jpg",
],
async init() {
await customElements.whenDefined("ea-image-preview");
this.showPreviewImage.previewSrcList = this.list;
this.previewControlledImage.urlList = this.list;
this.showPreviewButton.addEventListener("click", () => {
this.showPreviewImage.showPreview();
});
this.previewControlledButton.addEventListener("click", () => {
this.previewControlledImage.visible = true;
});
},
};
imageHandlerExample.init();自定义工具栏
可通过 toolbar 插槽自定义工具栏内容。工具栏中的元素支持 data-action 事件委托,可用的 action 值包括:switch-prev、switch-next、zoom-in、zoom-out、rotate-anticlockwise、rotate-clockwise。对于自定义操作(如跳转到首张/末张、重置),可通过组件的 setActiveItem 和 reset 方法实现。
查看代码
<div class="demo">
<ea-image
id="customToolbarImage"
style="width: 100px; height: 100px"
class="viewer"
src="https://tse1.mm.bing.net/th/id/OIP.rTMre-V-rMq3T1EP9W7vlAHaEK?cb=12&rs=1&pid=ImgDetMain&o=7&rm=3"
preview
zoom-rate="1.2"
max-scale="7"
min-scale="0.2"
initial-index="4"
fit="cover"
show-progress
>
<section slot="toolbar">
<ea-icon id="switchFirst" name="backward-fast"></ea-icon>
<ea-icon name="angle-left" data-action="switch-prev"></ea-icon>
<ea-icon name="angle-right" data-action="switch-next"></ea-icon>
<ea-icon id="switchLast" name="forward-fast"></ea-icon>
|
<ea-icon name="magnifying-glass-plus" data-action="zoom-in"></ea-icon>
<ea-icon name="magnifying-glass-minus" data-action="zoom-out"></ea-icon>
|
<ea-icon name="rotate-left" data-action="rotate-anticlockwise"></ea-icon>
<ea-icon name="rotate-right" data-action="rotate-clockwise"></ea-icon>
|
<ea-icon id="reset" name="recycle"></ea-icon>
</section>
</ea-image>
</div>const customToolbarImage = {
image: document.querySelector("#customToolbarImage"),
switchFirst: document.querySelector("#switchFirst"),
switchLast: document.querySelector("#switchLast"),
reset: document.querySelector("#reset"),
list: [
"https://tse2-mm.cn.bing.net/th/id/OIP-C.mH9YLFEL5YdVxJM82mjVJQAAAA?rs=1&pid=ImgDetMain",
"https://th.bing.com/th/id/R.d88442788ee5a458d50e40f0a8cb1e05?rik=EoPp8GhejYeQfw&riu=http%3a%2f%2fimg.pconline.com.cn%2fimages%2fupload%2fupc%2ftx%2fwallpaper%2f1307%2f10%2fc2%2f23151595_1373424485102.jpg&ehk=J7xq%2f50bCmdD4jUXfnTlau2s5WiVsBxQArAjvJzqIo4%3d&risl=&pid=ImgRaw&r=0",
"https://www.keaitupian.cn/cjpic/frombd/0/253/4061721412/2857814056.jpg",
"https://www.keaitupian.cn/cjpic/frombd/2/253/2107631312/3178897554.jpg",
"https://tse3.mm.bing.net/th/id/OIP.sPgwHtYKbg6cTN5LBYF_nQHaEK?cb=12&rs=1&pid=ImgDetMain&o=7&rm=3",
"https://tse1.mm.bing.net/th/id/OIP.VS7qtQiQgNuBk2SVdwvxagHaEk?rs=1&pid=ImgDetMain&o=7&rm=3",
"https://www.keaitupian.cn/cjpic/frombd/1/253/2032688566/3458490751.jpg",
],
async init() {
await customElements.whenDefined("ea-image-preview");
this.image.previewSrcList = this.list;
this.switchFirst.addEventListener("click", () => {
this.image.setActiveItem(0);
});
this.switchLast.addEventListener("click", () => {
this.image.setActiveItem(6);
});
this.reset.addEventListener("click", () => {
this.image.reset();
});
},
};
customToolbarImage.init();自定义进度条
可通过 show-progress 控制是否在预览图片时显示进度条。 进度条会在使用 progress 插槽时显示。
查看代码
<div class="demo">
<ea-image
id="customProgressImage"
style="width: 100px; height: 100px"
class="viewer"
src="https://tse1.mm.bing.net/th/id/OIP.rTMre-V-rMq3T1EP9W7vlAHaEK?cb=12&rs=1&pid=ImgDetMain&o=7&rm=3"
preview
zoom-rate="1.2"
max-scale="7"
min-scale="0.2"
initial-index="4"
fit="cover"
show-progress
>
<section slot="progress">
<span data-active></span> //
<span data-total></span>
</section>
</ea-image>
</div>const customProgressExample = {
image: document.querySelector("#customProgressImage"),
list: [
"https://tse2-mm.cn.bing.net/th/id/OIP-C.mH9YLFEL5YdVxJM82mjVJQAAAA?rs=1&pid=ImgDetMain",
"https://th.bing.com/th/id/R.d88442788ee5a458d50e40f0a8cb1e05?rik=EoPp8GhejYeQfw&riu=http%3a%2f%2fimg.pconline.com.cn%2fimages%2fupload%2fupc%2ftx%2fwallpaper%2f1307%2f10%2fc2%2f23151595_1373424485102.jpg&ehk=J7xq%2f50bCmdD4jUXfnTlau2s5WiVsBxQArAjvJzqIo4%3d&risl=&pid=ImgRaw&r=0",
"https://www.keaitupian.cn/cjpic/frombd/0/253/4061721412/2857814056.jpg",
"https://www.keaitupian.cn/cjpic/frombd/2/253/2107631312/3178897554.jpg",
"https://tse3.mm.bing.net/th/id/OIP.sPgwHtYKbg6cTN5LBYF_nQHaEK?cb=12&rs=1&pid=ImgDetMain&o=7&rm=3",
"https://tse1.mm.bing.net/th/id/OIP.VS7qtQiQgNuBk2SVdwvxagHaEk?rs=1&pid=ImgDetMain&o=7&rm=3",
"https://www.keaitupian.cn/cjpic/frombd/1/253/2032688566/3458490751.jpg",
],
async init() {
await customElements.whenDefined("ea-image-preview");
this.image.previewSrcList = this.list;
},
};
customProgressExample.init();Image API
Image Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---|---|---|---|---|
| src | 图片地址 | String | — | — |
| fit | 确定图片如何适应容器框,同原生 object-fit | String | fill / contain / cover / none / scale-down | — |
| alt | 原生 img 的 alt 属性 | String | — | — |
| width | 图片宽度 | String | — | — |
| height | 图片高度 | String | — | — |
| loading | 原生图片加载策略 | String | lazy / eager | eager |
| lazy | 兼容性懒加载开关(布尔),当浏览器不支持原生 lazy 时会使用 IntersectionObserver | Boolean | — | false |
| referrerpolicy | 原生 img 的 referrerpolicy 属性 | String | — | — |
| crossorigin | 原生 img 的 crossorigin 属性 | String | — | — |
| preview | 是否启用预览功能(会按需动态 import ea-image-preview) | Boolean | — | false |
| previewSrcList | 预览图片地址列表 | Array | — | [] |
| hide-on-click-modal | 预览时点击遮罩是否隐藏(透传到 preview 组件) | Boolean | — | false |
| z-index | 预览遮罩的 z-index(透传到 preview 组件) | Number | — | 2000 |
| initial-index | 预览初始索引(透传到 preview 组件) | Number | — | 0 |
| close-on-press-escape | 是否允许按 Escape 关闭预览(透传到 preview 组件) | Boolean | — | true |
| infinite | 预览是否无限循环(透传到 preview 组件) | Boolean | — | true |
| zoom-rate | 预览缩放倍率(透传到 preview 组件) | Number | — | 1.2 |
| scale | 预览时初始缩放比例(透传到 preview 组件) | Number | — | 1 |
| min-scale | 预览最小缩放比例(透传到 preview 组件) | Number | — | 0.2 |
| max-scale | 预览最大缩放比例(透传到 preview 组件) | Number | — | 7 |
| show-progress | 在预览时是否显示进度(透传到 preview 组件) | Boolean | — | false |
Image CSS Part
用法可参考 MDN ::part()伪类
| 名称 | 说明 |
|---|---|
| container | 外层容器 |
| image | 图片内容 |
| error | 图片加载失败时显示的图片 |
| placeholder | 图片加载前的占位内容 |
| preview | 预览图片容器 |
Image Methods
| 方法名 | 说明 | 参数 |
|---|---|---|
| setActiveItem | 切换预览图片 | (index: number) |
| reset | 重置图片预览状态 | — |
| showPreview | 显示图片预览 | — |
Image Events
| 事件名称 | 说明 | 回调参数 |
|---|---|---|
| load | 图片加载成功时触发 | (e: Event) |
| error | 图片加载失败时触发 | (e: Event) |
Image Slots
| 名称 | 说明 |
|---|---|
| error | 图片加载失败时显示的图片(slot="error") |
| placeholder | 图片未加载时的占位内容(slot="placeholder") |
| progress | 图片加载过程中的进度(slot="progress") |
| toolbar | 图片预览工具栏(slot="toolbar") |
ImagePreview API
ImagePreview Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---|---|---|---|---|
| visible | 是否可见(控制遮罩显示/隐藏) | Boolean | — | false |
| modal | 是否显示遮罩层(继承自 ea-overlay) | Boolean | — | true |
| urlList | 图片地址列表 | Array | — | [] |
| initial-index | 初始索引,用于初始化 index | Number | — | 0 |
| index | 当前预览的图片索引(可读写,会触发切换逻辑) | Number | — | initial-index |
| infinite | 是否在首尾继续循环 | Boolean | — | true |
| zoom-rate | 缩放步长(每次缩放的倍率因子) | Number | — | 1.2 |
| zoom | 缩放倍数 | Number | — | 1 |
| scale | 当前缩放比例(可读写,受 min-scale/max-scale 限制) | Number | — | 1 |
| min-scale | 最小缩放比例 | Number | — | 0.2 |
| max-scale | 最大缩放比例 | Number | — | 7 |
| close-on-press-escape | 是否支持按 Escape 关闭 | Boolean | — | true |
| close-on-click-modal | 点击遮罩是否关闭(继承自 ea-overlay) | Boolean | — | true |
| show-progress | 是否显示进度(progress 区域会渲染 slot 或文本) | Boolean | — | false |
| append-to-body | 是否插入到 body(继承自 ea-overlay) | Boolean | — | false |
| append-to | 组件追加的目标容器选择器(继承自 ea-overlay) | String | — | body |
| z-index | 遮罩层的 z-index(继承自 ea-overlay) | String | — | — |
| beforeClose | 关闭前的回调函数(继承自 ea-overlay),done() 确认关闭,done(true) 取消关闭 | Function | — | null |
ImagePreview Scopes
| 名称 | 说明 |
|---|---|
| data-active | 当前预览图片的索引值 |
| data-total | 预览图片的总数 |
ImagePreview CSS Part
用法可参考 MDN ::part()伪类
| 名称 | 说明 |
|---|---|
| container | 预览遮罩的根元素(基于 ea-overlay) |
| mask | 遮罩层(继承自 ea-overlay) |
| content | 内容容器(继承自 ea-overlay) |
| header | 头部区域(包含关闭按钮) |
| main | 主体区域(包含图片与左右切换) |
| footer | 底部区域(包含工具栏与进度) |
| toolbar | 自定义工具栏 slot |
| progress | 进度显示区域 |
| icon | 图标元素(所有图标共有的 part) |
| icon & close-icon | 关闭按钮 |
| icon & prev-icon | 左切换按钮 |
| icon & next-icon | 右切换按钮 |
| icon & zoom-in-icon | 缩放按钮(放大) |
| icon & zoom-out-icon | 缩放按钮(缩小) |
| icon & rotate-left-icon | 旋转按钮(向左旋转) |
| icon & rotate-right-icon | 旋转按钮(向右旋转) |
ImagePreview Methods
| 方法名 | 说明 | 参数 |
|---|---|---|
| setActiveItem | 切换预览图片 | (index: number) |
| reset | 重置预览状态(index、scale、rotate、position) | — |
ImagePreview Events
| 事件名称 | 说明 | 回调参数 |
|---|---|---|
| ea-switch | 切换图片时触发 | { index, url, imgTarget } |
| ea-preview-error | 图片加载失败时触发 | — |
| ea-rotate | 旋转图片时触发 | { oldVal, rotate } |
| ea-open | 遮罩打开时触发(继承自 ea-overlay) | — |
| ea-opened | 遮罩打开动画结束后触发(继承自 ea-overlay) | — |
| ea-close | 遮罩关闭时触发(继承自 ea-overlay) | — |
| ea-closed | 遮罩关闭动画结束后触发(继承自 ea-overlay) | — |
ImagePreview Slots
| 名称 | 说明 |
|---|---|
| viewer-error | 预览图片加载错误时用于替换错误展示 |
| toolbar | 自定义工具栏内容(支持 data-action 事件委托) |
| progress | 自定义进度显示内容(支持 data-active / data-total) |