mirror of
https://gitee.com/element-plus/element-plus.git
synced 2024-12-05 12:48:04 +08:00
feat(components): [image-viewer] add setActiveItem
method (#9389)
* fix(components): [image-viewer] initialIndex lost reactivity * feat(components): [image-viewer] add `setActiveItem` method * feat: expose instance type * chore: add test case * chore: update docs
This commit is contained in:
parent
e16cb4f97e
commit
e33a279556
@ -111,3 +111,9 @@ image/image-preview
|
||||
| ---------- | ------------------------------------------------------------------------------------------------- | ------------------------- |
|
||||
| `close` | trigger when clicking on close button or when `hide-on-click-modal` enabled clicking on backdrop. | `() => void` |
|
||||
| `switch` | trigger when switching images. | `(index: number) => void` |
|
||||
|
||||
## Image Viewer Methods
|
||||
|
||||
| Method | Description | Parameters |
|
||||
| ------------- | --------------------- | ----------------------------------------------------- |
|
||||
| setActiveItem | manually switch image | index of the image to be switched to, starting from 0 |
|
||||
|
@ -44,4 +44,26 @@ describe('<image-viewer />', () => {
|
||||
expect(wrapper.emitted('close')).toBeDefined()
|
||||
wrapper.unmount()
|
||||
})
|
||||
|
||||
test('manually switch image', async () => {
|
||||
const wrapper = mount({
|
||||
props: {
|
||||
urlList: [IMAGE_SUCCESS, IMAGE_SUCCESS],
|
||||
},
|
||||
})
|
||||
|
||||
await doubleWait()
|
||||
const viewer = wrapper.find('.el-image-viewer__wrapper')
|
||||
expect(viewer.exists()).toBe(true)
|
||||
|
||||
const imgList = wrapper.findAll('.el-image-viewer__img')
|
||||
expect(imgList[0].attributes('style')).not.contains('display: none;')
|
||||
expect(imgList[1].attributes('style')).contains('display: none;')
|
||||
|
||||
wrapper.vm.setActiveItem(1)
|
||||
await doubleWait()
|
||||
expect(imgList[0].attributes('style')).contains('display: none;')
|
||||
expect(imgList[1].attributes('style')).not.contains('display: none;')
|
||||
wrapper.unmount()
|
||||
})
|
||||
})
|
||||
|
@ -4,7 +4,9 @@ import {
|
||||
isNumber,
|
||||
mutable,
|
||||
} from '@element-plus/utils'
|
||||
|
||||
import type { Component, ExtractPropTypes } from 'vue'
|
||||
import type ImageViewer from './image-viewer.vue'
|
||||
|
||||
export type ImageViewerAction =
|
||||
| 'zoomIn'
|
||||
@ -53,3 +55,5 @@ export interface ImageViewerMode {
|
||||
name: string
|
||||
icon: Component
|
||||
}
|
||||
|
||||
export type ImageViewerInstance = InstanceType<typeof ImageViewer>
|
||||
|
@ -63,7 +63,7 @@
|
||||
<div :class="ns.e('canvas')">
|
||||
<img
|
||||
v-for="(url, i) in urlList"
|
||||
v-show="i === index"
|
||||
v-show="i === activeIndex"
|
||||
:ref="(el) => (imgRefs[i] = el as HTMLImageElement)"
|
||||
:key="url"
|
||||
:src="url"
|
||||
@ -142,7 +142,7 @@ const imgRefs = ref<HTMLImageElement[]>([])
|
||||
const scopeEventListener = effectScope()
|
||||
|
||||
const loading = ref(true)
|
||||
const index = ref(props.initialIndex)
|
||||
const activeIndex = ref(props.initialIndex)
|
||||
const mode = shallowRef<ImageViewerMode>(modes.CONTAIN)
|
||||
const transform = ref({
|
||||
scale: 1,
|
||||
@ -158,15 +158,15 @@ const isSingle = computed(() => {
|
||||
})
|
||||
|
||||
const isFirst = computed(() => {
|
||||
return index.value === 0
|
||||
return activeIndex.value === 0
|
||||
})
|
||||
|
||||
const isLast = computed(() => {
|
||||
return index.value === props.urlList.length - 1
|
||||
return activeIndex.value === props.urlList.length - 1
|
||||
})
|
||||
|
||||
const currentImg = computed(() => {
|
||||
return props.urlList[index.value]
|
||||
return props.urlList[activeIndex.value]
|
||||
})
|
||||
|
||||
const imgStyle = computed(() => {
|
||||
@ -318,16 +318,19 @@ function toggleMode() {
|
||||
reset()
|
||||
}
|
||||
|
||||
function setActiveItem(index: number) {
|
||||
const len = props.urlList.length
|
||||
activeIndex.value = (index + len) % len
|
||||
}
|
||||
|
||||
function prev() {
|
||||
if (isFirst.value && !props.infinite) return
|
||||
const len = props.urlList.length
|
||||
index.value = (index.value - 1 + len) % len
|
||||
setActiveItem(activeIndex.value - 1)
|
||||
}
|
||||
|
||||
function next() {
|
||||
if (isLast.value && !props.infinite) return
|
||||
const len = props.urlList.length
|
||||
index.value = (index.value + 1) % len
|
||||
setActiveItem(activeIndex.value + 1)
|
||||
}
|
||||
|
||||
function handleActions(action: ImageViewerAction, options = {}) {
|
||||
@ -372,7 +375,7 @@ watch(currentImg, () => {
|
||||
})
|
||||
})
|
||||
|
||||
watch(index, (val) => {
|
||||
watch(activeIndex, (val) => {
|
||||
reset()
|
||||
emit('switch', val)
|
||||
})
|
||||
@ -383,4 +386,9 @@ onMounted(() => {
|
||||
// focus wrapper so arrow key can't cause inner scroll behavior underneath
|
||||
wrapper.value?.focus?.()
|
||||
})
|
||||
|
||||
defineExpose({
|
||||
/** @description manually switch image */
|
||||
setActiveItem,
|
||||
})
|
||||
</script>
|
||||
|
Loading…
Reference in New Issue
Block a user