您好,登錄后才能下訂單哦!
本篇文章和大家了解一下vue3+ts+elementPLus實現v-preview指令的方法。有一定的參考價值,有需要的朋友可以參考一下,希望對大家有所幫助。
最近在用 vue3+ts 開發公司的后臺系統,因為后臺多處需要圖片放大預覽的功能,就想著封裝一個v-preview指令,這樣在需要預覽的圖片上加個 v-preview就可以預覽啦。
在這里就不列我的項目目錄啦,想嘗試的朋友可以這樣創建目錄
-- preview
---- previewImage.vue
---- preview.ts
普普通通vue3組件,記得全局注冊
<template> <div class="previewImg" @click="dialogVisible = true"> <slot> <img :src="props.src" alt="圖片加載失敗" /> </slot> </div> <el-dialog v-model="dialogVisible" title="查看圖片" @close="close"> <img :src="imgSrc" alt="Preview Image" /> </el-dialog> </template> <script setup lang="ts"> import { ref, getCurrentInstance, ComponentInternalInstance, onMounted } from 'vue' import { ElDialog } from 'element-plus' const props = defineProps({ src: String }) const dialogVisible = ref(false) const imgSrc = ref('') // 插槽形式 onMounted(() => { const { proxy } = getCurrentInstance() as ComponentInternalInstance let slot = proxy?.$slots?.default?.() if(slot){ // 獲取插槽內容設置imgSrc地址 imgSrc.value = slot?.[0]?.props?.src } }) const setSrc = (v: string) => { imgSrc.value = v } // 組件觸發 if (props.src) { setSrc(props.src) } // 指令觸發 const show = () => { dialogVisible.value = true } const close = () => { // 彈窗關閉移除dom if (document.getElementById('previewDom')) { document.body.removeChild(document.getElementById('previewDom') as HTMLElement) } } defineExpose({ show, setSrc }) </script>
對previewImage組件進行拓展,全局注冊preview指令(這個注冊代碼就不放了呦)
需要注意的是vue3拓展組件和vue2有所不同,vue2用Vue.extend就可以拿到組件構造器,vue3這邊則是使用createApp
import { Component, createApp } from 'vue' import PreviewImageVue from '@/components/PreviewImage.vue' function mountComponent(RootComponent: Component) { const app = createApp(RootComponent) const root = document.createElement('div') root.setAttribute('id', 'previewDom') document.body.appendChild(root) return { instance: app.mount(root), unmount() { // 這里unmout沒用到,因為組件中dialog的close事件這里監聽不到,我就在組件內進行卸載了 console.log('unmount') document.body.removeChild(root) } } } const preview = { mounted(el: any) { el.style.cursor = 'zoom-in' el.addEventListener('click', () => { let imgSrc = el.getAttribute('src') let { instance, unmount } = mountComponent(PreviewImageVue) ;(instance as any).setSrc(imgSrc) ;(instance as any).show() }) } } export default preview
本地資源測試
<div class="imgs"> <!-- 普通圖片 --> <img src="~@/assets/images/logo.png" alt=""> <!-- 組件形式使用預覽組件、需要注意路徑(使用絕對路徑) --> <PreviewImage src="/src/assets/images/logo.png"></PreviewImage> <!-- 組件插槽形式預覽組件、需要注意路徑(使用絕對路徑) --> <PreviewImage> <img src="/src/assets/images/logo.png" alt=""> </PreviewImage> <!-- 指令使用預覽組件 --> <img src="~@/assets/images/logo.png" alt="" v-preview> </div>
獲取proxy時使用getCurrentInstance時編輯器會報錯,斷言成ComponentInternalInstance就不報錯了。
獲取插槽內容時需要 proxy?.$slots?.default?.() 這樣判斷取值,不然編輯器也會報錯。
暴露給外部使用的方法/屬性需通過defineExpose暴露出去
注意拓展組件方式。vue2用Vue.extend,vue3用createApp
使用的時候注意路徑問題
之前都是用vue2開發項目,此次項目是vue3的第一次實踐,使用下來感覺ts寫起來比較冗余,很多編輯器報錯都需要時間去解決,可能不是開發組件庫都是業務需求,對類型接口的定義使用很少。個人不是很喜歡ts,還是js來的簡單粗暴。
以上就是vue3+ts+elementPLus實現v-preview指令的方法的簡略介紹,當然詳細使用上面的不同還得要大家自己使用過才領會。如果想了解更多,歡迎關注億速云行業資訊頻道哦!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。