最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

vue3中使用medium-zoom方法實(shí)例代碼

 更新時(shí)間:2026年03月12日 09:31:58   作者:在掘金80110  
這篇文章主要介紹了vue3中使用medium-zoom方法的相關(guān)資料,Medium Zoom是一個(gè)輕量級(jí)的JavaScript庫,用于實(shí)現(xiàn)類似Medium網(wǎng)站的圖片點(diǎn)擊放大縮放效果,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下

簡介

Medium Zoom 是一個(gè)輕量級(jí) JavaScript 庫,用于實(shí)現(xiàn)類似 Medium 網(wǎng)站的圖片點(diǎn)擊放大縮放效果。本文檔專注于在 Vue3 項(xiàng)目中的集成和使用。

核心特性

  • ?? 響應(yīng)式設(shè)計(jì) - 完美適配移動(dòng)端和桌面端
  • ?? 高性能 - 優(yōu)化至 60fps 流暢動(dòng)畫
  • ?? 高清圖支持 - 通過 data-zoom-src 屬性加載高清大圖
  • ?? 可定制化 - 支持自定義邊距、背景、滾動(dòng)偏移等
  • ?? 事件系統(tǒng) - 完整的生命周期事件監(jiān)聽
  • ?? 零依賴 - 無任何運(yùn)行時(shí)依賴
  • ?? 框架友好 - 完美支持 Vue3 組合式 API

安裝

使用 npm

npm install medium-zoom

使用 yarn

yarn add medium-zoom

使用 pnpm

pnpm add medium-zoom

Vue3 快速開始

方法一:封裝組件(推薦)

創(chuàng)建一個(gè)可復(fù)用的 ImageZoom.vue 組件:

<script setup lang="ts">
import { watch, type ImgHTMLAttributes, type ComponentPublicInstance } from 'vue'
import mediumZoom, { type Zoom, type ZoomOptions } from 'medium-zoom'

interface Props extends ImgHTMLAttributes {
  options?: ZoomOptions
}

const props = defineProps<Props>()

let zoom: Zoom | null = null

function getZoom() {
  if (zoom === null) {
    zoom = mediumZoom(props.options)
  }
  return zoom
}

function attachZoom(ref: Element | ComponentPublicInstance | null) {
  const image = ref as HTMLImageElement | null
  const zoom = getZoom()

  if (image) {
    zoom.attach(image)
  } else {
    zoom.detach()
  }
}

watch(() => props.options, (options) => {
  const zoom = getZoom()
  zoom.update(options || {})
})
</script>

<template>
  <img :ref="attachZoom" v-bind="$attrs" />
</template>

使用封裝的組件

<script setup lang="ts">
import ImageZoom from './components/ImageZoom.vue'
</script>

<template>
  <article>
    <h1>我的圖片畫廊</h1>

    <!-- 基礎(chǔ)使用 -->
    <ImageZoom src="/images/photo-1.jpg" alt="照片1" />

    <!-- 自定義背景色 -->
    <ImageZoom 
      src="/images/photo-2.jpg" 
      alt="照片2"
      :options="{ background: '#000000' }" 
    />

    <!-- 自定義邊距 -->
    <ImageZoom 
      src="/images/photo-3.jpg" 
      alt="照片3"
      :options="{ margin: 48, background: 'rgba(0,0,0,0.9)' }" 
    />

    <!-- 高清圖支持 -->
    <ImageZoom 
      src="/images/thumbnail.jpg" 
      data-zoom-src="/images/hd-image.jpg"
      alt="高清圖片"
    />
  </article>
</template>

方法二:在 Composable 中使用

創(chuàng)建 useImageZoom.ts

import { onMounted, onUnmounted, ref, type Ref } from 'vue'
import mediumZoom, { type Zoom, type ZoomOptions } from 'medium-zoom'

export function useImageZoom(
  selector?: string | HTMLElement,
  options?: ZoomOptions
) {
  const zoom: Ref<Zoom | null> = ref(null)

  onMounted(() => {
    zoom.value = mediumZoom(selector, options)
  })

  onUnmounted(() => {
    zoom.value?.detach()
  })

  return {
    zoom,
    open: () => zoom.value?.open(),
    close: () => zoom.value?.close(),
    toggle: () => zoom.value?.toggle(),
  }
}

使用 Composable:

<script setup lang="ts">
import { onMounted } from 'vue'
import { useImageZoom } from './composables/useImageZoom'

// 初始化 zoom
const { zoom, open, close } = useImageZoom('[data-zoomable]', {
  margin: 24,
  background: '#BADA55',
})

// 也可以在掛載后動(dòng)態(tài)附加圖片
onMounted(() => {
  zoom.value?.attach('.gallery-image')
})
</script>

<template>
  <div>
    <img src="/image-1.jpg" data-zoomable alt="圖片1" />
    <img src="/image-2.jpg" data-zoomable alt="圖片2" />
    <img src="/image-3.jpg" class="gallery-image" alt="圖片3" />
    
    <!-- 手動(dòng)控制按鈕 -->
    <button @click="open">放大第一張圖片</button>
    <button @click="close">關(guān)閉縮放</button>
  </div>
</template>

方法三:直接在組件中使用

<script setup lang="ts">
import { onMounted, onUnmounted, ref } from 'vue'
import mediumZoom from 'medium-zoom'

const zoomRef = ref(null)

onMounted(() => {
  zoomRef.value = mediumZoom('.zoomable', {
    margin: 24,
    background: '#fff',
    scrollOffset: 40,
  })
})

onUnmounted(() => {
  zoomRef.value?.detach()
})
</script>

<template>
  <div>
    <img src="/image.jpg" class="zoomable" alt="可縮放圖片" />
  </div>
</template>

配置選項(xiàng) (ZoomOptions)

屬性類型默認(rèn)值說明
marginnumber0縮放圖片外的空白邊距(像素)
backgroundstring"#fff"遮罩層背景色,支持任何 CSS 顏色值
scrollOffsetnumber40滾動(dòng)多少像素后自動(dòng)關(guān)閉縮放
containerstring | HTMLElement | objectnull指定縮放渲染的容器視口
templatestring | HTMLTemplateElementnull自定義模板元素

配置示例

const options: ZoomOptions = {
  margin: 48,                    // 48px 邊距
  background: 'rgba(0,0,0,0.9)', // 半透明黑色背景
  scrollOffset: 100,             // 滾動(dòng) 100px 后關(guān)閉
  container: '#zoom-container',  // 在指定容器內(nèi)縮放
}

API 方法

open(options?: { target?: HTMLElement }): Promise<Zoom>

打開縮放,返回 Promise。

zoom.value?.open()
// 或指定目標(biāo)圖片
zoom.value?.open({ target: imgElement })

close(): Promise<Zoom>

關(guān)閉縮放,返回 Promise。

zoom.value?.close()

toggle(options?: { target?: HTMLElement }): Promise<Zoom>

切換縮放狀態(tài)(打開/關(guān)閉)。

zoom.value?.toggle()

attach(...selectors): Zoom

附加圖片到縮放實(shí)例。

zoom.value?.attach('#image-1', '#image-2')
zoom.value?.attach(document.querySelector('#image-3'))

detach(...selectors): Zoom

從縮放實(shí)例中移除圖片。

zoom.value?.detach('#image-1')
zoom.value?.detach() // 移除所有圖片

update(options: ZoomOptions): Zoom

更新配置選項(xiàng)。

zoom.value?.update({ 
  background: '#000',
  margin: 50 
})

clone(options?: ZoomOptions): Zoom

克隆一個(gè)新的縮放實(shí)例,合并新配置。

const newZoom = zoom.value?.clone({ margin: 100 })

on(type: string, listener: Function, options?): Zoom

注冊(cè)事件監(jiān)聽器。

zoom.value?.on('open', (event) => {
  console.log('圖片已打開', event.detail.zoom)
})

off(type: string, listener: Function, options?): Zoom

移除事件監(jiān)聽器。

const handler = (event) => { /* ... */ }
zoom.value?.on('open', handler)
zoom.value?.off('open', handler)

getOptions(): ZoomOptions

獲取當(dāng)前配置選項(xiàng)。

const currentOptions = zoom.value?.getOptions()

getImages(): HTMLElement[]

獲取所有已附加的圖片元素。

const images = zoom.value?.getImages()

getZoomedImage(): HTMLElement | null

獲取當(dāng)前正在縮放的圖片元素。

const currentImage = zoom.value?.getZoomedImage()

事件系統(tǒng)

可用事件

事件名觸發(fā)時(shí)機(jī)說明
open調(diào)用 open() 方法時(shí)立即觸發(fā)縮放動(dòng)畫開始前
opened縮放動(dòng)畫完成后圖片已完全放大
close調(diào)用 close() 方法時(shí)立即觸發(fā)關(guān)閉動(dòng)畫開始前
closed關(guān)閉動(dòng)畫完成后圖片已完全縮小
detach調(diào)用 detach() 方法時(shí)圖片從實(shí)例中移除
update調(diào)用 update() 方法時(shí)配置選項(xiàng)已更新

Vue3 中使用事件

<script setup lang="ts">
import { onMounted, ref } from 'vue'
import mediumZoom from 'medium-zoom'

const zoom = ref(null)
const zoomCount = ref(0)

onMounted(() => {
  zoom.value = mediumZoom('[data-zoomable]')
  
  // 監(jiān)聽打開事件
  zoom.value.on('open', (event) => {
    console.log('開始縮放:', event.target.alt)
  })
  
  // 監(jiān)聽打開完成事件
  zoom.value.on('opened', (event) => {
    zoomCount.value++
    console.log(`已縮放 ${zoomCount.value} 次`)
  })
  
  // 監(jiān)聽關(guān)閉事件
  zoom.value.on('close', () => {
    console.log('開始關(guān)閉縮放')
  })
  
  // 監(jiān)聽關(guān)閉完成事件
  zoom.value.on('closed', () => {
    console.log('縮放已關(guān)閉')
  })
  
  // 單次事件監(jiān)聽
  zoom.value.on('open', (event) => {
    console.log('這個(gè)只觸發(fā)一次')
  }, { once: true })
})
</script>

<template>
  <div>
    <img src="/image.jpg" data-zoomable alt="圖片" />
    <p>已縮放次數(shù): {{ zoomCount }}</p>
  </div>
</template>

高級(jí)用法

1. 高清圖加載

使用 data-zoom-src 屬性指定高清大圖:

<template>
  <ImageZoom 
    src="/thumbnails/small.jpg" 
    data-zoom-src="/images/large-hd.jpg"
    alt="高清圖片"
  />
</template>

2. 在 Markdown 渲染中使用

適用于博客、文檔等場景:

<script setup lang="ts">
import { onMounted, ref, nextTick } from 'vue'
import mediumZoom from 'medium-zoom'
import MarkdownIt from 'markdown-it'

const md = new MarkdownIt()
const content = ref('')
const zoom = ref(null)

const markdown = `
# 我的文章
![圖片1](/image-1.jpg)
![圖片2](/image-2.jpg)
`

onMounted(async () => {
  content.value = md.render(markdown)
  
  await nextTick()
  
  // 為所有 markdown 渲染的圖片添加縮放
  zoom.value = mediumZoom('.markdown-body img', {
    background: 'rgba(255,255,255,0.95)',
    margin: 24
  })
})
</script>

<template>
  <div class="markdown-body" v-html="content"></div>
</template>

3. 自定義容器

在指定容器內(nèi)縮放:

<script setup lang="ts">
import { onMounted } from 'vue'
import mediumZoom from 'medium-zoom'

onMounted(() => {
  mediumZoom('[data-zoomable]', {
    container: '#custom-container',
    background: 'transparent'
  })
})
</script>

<template>
  <div id="custom-container" style="position: relative; height: 500px;">
    <img src="/image.jpg" data-zoomable alt="圖片" />
  </div>
</template>

4. 動(dòng)態(tài)添加/移除圖片

<script setup lang="ts">
import { ref, onMounted } from 'vue'
import mediumZoom from 'medium-zoom'

const images = ref(['/img1.jpg', '/img2.jpg'])
const zoom = ref(null)

onMounted(() => {
  zoom.value = mediumZoom('.gallery img')
})

function addImage() {
  const newImg = `/img${images.value.length + 1}.jpg`
  images.value.push(newImg)
  
  // 下一幀后附加新圖片
  nextTick(() => {
    const newElement = document.querySelector(`.img-${images.value.length - 1}`)
    zoom.value?.attach(newElement)
  })
}

function removeImage(index: number) {
  const imgElement = document.querySelector(`.img-${index}`)
  zoom.value?.detach(imgElement)
  images.value.splice(index, 1)
}
</script>

<template>
  <div class="gallery">
    <img 
      v-for="(src, index) in images" 
      :key="index"
      :src="src" 
      :class="`img-${index}`"
      alt="圖片" 
    />
    <button @click="addImage">添加圖片</button>
  </div>
</template>

5. 從外部按鈕觸發(fā)縮放

<script setup lang="ts">
import { ref, onMounted } from 'vue'
import mediumZoom from 'medium-zoom'

const zoom = ref(null)
const imageRef = ref(null)

onMounted(() => {
  zoom.value = mediumZoom(imageRef.value)
})

function handleZoom() {
  zoom.value?.toggle({ target: imageRef.value })
}
</script>

<template>
  <div>
    <img ref="imageRef" src="/image.jpg" alt="圖片" />
    <button @click="handleZoom">點(diǎn)擊縮放圖片</button>
  </div>
</template>

6. 圖片畫廊示例

<script setup lang="ts">
import { ref, onMounted } from 'vue'
import mediumZoom from 'medium-zoom'

const zoom = ref(null)

const gallery = [
  { id: 1, src: '/gallery/img1.jpg', thumb: '/gallery/thumb1.jpg', alt: '風(fēng)景1' },
  { id: 2, src: '/gallery/img2.jpg', thumb: '/gallery/thumb2.jpg', alt: '風(fēng)景2' },
  { id: 3, src: '/gallery/img3.jpg', thumb: '/gallery/thumb3.jpg', alt: '風(fēng)景3' },
]

onMounted(() => {
  zoom.value = mediumZoom('.gallery-image', {
    margin: 48,
    background: '#000',
  })
  
  zoom.value.on('opened', (event) => {
    console.log(`正在查看: ${event.target.alt}`)
  })
})
</script>

<template>
  <div class="gallery-grid">
    <div v-for="item in gallery" :key="item.id" class="gallery-item">
      <img 
        :src="item.thumb" 
        :data-zoom-src="item.src"
        :alt="item.alt"
        class="gallery-image"
      />
      <p>{{ item.alt }}</p>
    </div>
  </div>
</template>

<style scoped>
.gallery-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 16px;
}

.gallery-image {
  width: 100%;
  cursor: zoom-in;
  transition: opacity 0.3s;
}

.gallery-image:hover {
  opacity: 0.8;
}
</style>

樣式定制

如果需要自定義 z-index(避免與其他 UI 框架沖突):

/* 在全局樣式中添加 */
.medium-zoom-overlay,
.medium-zoom-image--opened {
  z-index: 9999;
}

自定義動(dòng)畫時(shí)長:

.medium-zoom-image--opened {
  transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1);
}

TypeScript 支持

完整的 TypeScript 類型定義:

import mediumZoom, { 
  type Zoom, 
  type ZoomOptions, 
  type ZoomSelector,
  type ZoomOpenOptions 
} from 'medium-zoom'

// Zoom 實(shí)例類型
const zoom: Zoom = mediumZoom()

// 配置選項(xiàng)類型
const options: ZoomOptions = {
  margin: 24,
  background: '#fff',
  scrollOffset: 40,
}

// 選擇器類型
const selector: ZoomSelector = '.image' // string | HTMLElement | HTMLElement[] | NodeList

常見問題

Q: 縮放的圖片看不見?

A: 某些 UI 框架可能設(shè)置了較高的 z-index,需要手動(dòng)設(shè)置:

.medium-zoom-overlay,
.medium-zoom-image--opened {
  z-index: 9999;
}

Q: 在 v-for 中使用無效?

A: 確保在 DOM 更新后再附加圖片:

<script setup>
import { nextTick } from 'vue'

async function addImages() {
  images.value.push(newImage)
  await nextTick()
  zoom.value?.attach('.new-image')
}
</script>

Q: 如何在路由切換時(shí)清理?

A: 使用 onUnmounted 鉤子:

<script setup>
import { onUnmounted } from 'vue'

onUnmounted(() => {
  zoom.value?.detach()
})
</script>

瀏覽器支持

  • Chrome 36+
  • Firefox 34+
  • Safari 9+
  • Edge 12+
  • IE 10+ (需要 template polyfill)

參考資源

提示: 本文檔基于 medium-zoom 庫分析生成,適用于 Vue 3.x 版本項(xiàng)目。

到此這篇關(guān)于vue3中使用medium-zoom方法的文章就介紹到這了,更多相關(guān)vue3使用medium-zoom內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • vue實(shí)現(xiàn)app頁面切換動(dòng)畫效果實(shí)例

    vue實(shí)現(xiàn)app頁面切換動(dòng)畫效果實(shí)例

    本篇文章主要介紹了vue實(shí)現(xiàn)app頁面切換動(dòng)畫效果實(shí)例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • vue實(shí)現(xiàn)動(dòng)態(tài)路由的方法及路由原理解析

    vue實(shí)現(xiàn)動(dòng)態(tài)路由的方法及路由原理解析

    這篇文章主要介紹了路由原理及vue實(shí)現(xiàn)動(dòng)態(tài)路由,Vue Router 提供了豐富的 API,可以輕松地實(shí)現(xiàn)路由功能,并支持路由參數(shù)、查詢參數(shù)、命名路由、嵌套路由等功能,可以滿足不同應(yīng)用程序的需求,需要的朋友可以參考下
    2023-06-06
  • vue3學(xué)習(xí)筆記簡單封裝axios示例實(shí)現(xiàn)

    vue3學(xué)習(xí)筆記簡單封裝axios示例實(shí)現(xiàn)

    這篇文章主要為大家介紹了vue3學(xué)習(xí)筆記簡單封裝axios示例實(shí)現(xiàn),
    2022-06-06
  • 在uni-app中使用vant組件的方法

    在uni-app中使用vant組件的方法

    最近在做uni-app的時(shí)候需要用到vant組件,在網(wǎng)上看到了很多的使用vant組件的方法,但是講解的大多繁瑣,或者無法使用,現(xiàn)把最新,最實(shí)用的vant組件的使用方法分享給大家,需要的朋友可以參考下
    2023-02-02
  • Vue中使用ECharts與v-if的問題和解決方案

    Vue中使用ECharts與v-if的問題和解決方案

    在Vue項(xiàng)目中使用v-if指令控制ECharts圖表顯示時(shí),可能會(huì)遇到圖表無法正常渲染或顯示錯(cuò)誤的問題,下面這篇文章主要介紹了Vue中使用ECharts與v-if的問題和解決方案,需要的朋友可以參考下
    2024-10-10
  • 使用 vue 實(shí)現(xiàn)滅霸打響指英雄消失的效果附demo

    使用 vue 實(shí)現(xiàn)滅霸打響指英雄消失的效果附demo

    這篇文章主要介紹了使用 vue 實(shí)現(xiàn)滅霸打響指英雄消失的效果 demo,需要的朋友可以參考下
    2019-05-05
  • 使用Axios攔截器中止Vue請(qǐng)求的步驟詳解

    使用Axios攔截器中止Vue請(qǐng)求的步驟詳解

    假設(shè)?App?的用戶可以在短時(shí)間內(nèi)進(jìn)行多個(gè)?API?調(diào)用,但您只想顯示上次調(diào)用的結(jié)果,之前正在進(jìn)行的請(qǐng)求變得無關(guān)緊要,在這種情況下,您可以利用?Axios?攔截器,本文給大家介紹了如何使用Axios攔截器中止Vue請(qǐng)求,需要的朋友可以參考下
    2023-11-11
  • easycom模式開發(fā)UNI-APP組件調(diào)用必須掌握的實(shí)用技巧

    easycom模式開發(fā)UNI-APP組件調(diào)用必須掌握的實(shí)用技巧

    uni-app基于VUE開發(fā),通常組件的使用都是先安裝,然后全局或者局部引入,注冊(cè),今天通過本文給大家分享easycom模式開發(fā)UNI-APP組件調(diào)用必須掌握的實(shí)用技巧,需要的朋友一起看看吧
    2021-08-08
  • vue中formdata傳值給后臺(tái)時(shí)參數(shù)為空的問題

    vue中formdata傳值給后臺(tái)時(shí)參數(shù)為空的問題

    這篇文章主要介紹了vue中formdata傳值給后臺(tái)時(shí)參數(shù)為空的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • vue項(xiàng)目實(shí)現(xiàn)分頁效果

    vue項(xiàng)目實(shí)現(xiàn)分頁效果

    這篇文章主要為大家詳細(xì)介紹了vue項(xiàng)目實(shí)現(xiàn)分頁效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-03-03

最新評(píng)論

乌审旗| 区。| 瑞金市| 宜丰县| 宾川县| 红桥区| 临颍县| 修水县| 射洪县| 普兰店市| 临清市| 柘城县| 柯坪县| 滁州市| 益阳市| 科技| 灵山县| 莱西市| 平乐县| 黔西| 北川| 辽宁省| 巴林左旗| 翼城县| 驻马店市| 邵东县| 密山市| 扎囊县| 中卫市| 衡阳县| 永吉县| 榆林市| 阳谷县| 龙胜| 乌鲁木齐县| 宿松县| 阿尔山市| 西青区| 蓬莱市| 时尚| 浪卡子县|