Vue3+ElementPlus封裝圖片空間組件的門面實(shí)例
什么是圖片空間?
圖片空間就是專門管理我們上傳圖片的地方。
就好比用戶管理一樣,我們對要上傳的圖片進(jìn)行管理。
這樣做的好處有哪些?
我們把可能需要的圖片都上傳到圖片管理中。在其他需要圖片的地方(如:商品圖片等)可以直接調(diào)用圖片空間組件,從圖片空間中進(jìn)行選擇。
圖片空間的樣式多種多樣,但是它們的入口都是一樣的,所以這里封裝了圖片空間的門面。
1.PictureSpaceFacade.vue 組件
<script setup>
const props=defineProps({
// 圖片數(shù)組或字符串(http://a.com/1.jpg,http://a.com/2.jpg 用逗號隔開)
modelValue: {
type: [Array,String,Object],
},
// 圖片寬度
pictureWidth: {
type:String,
default: '100px'
},
// 圖片高度
pictureHeight:{
type:String,
default: '100px'
}
})
const emits=defineEmits(['update:modelValue'])
import {ref, watch} from "vue";
// 圖片數(shù)組
const pictureList = ref([])
// 監(jiān)聽props.modelValue變化
watch(() => props.modelValue, (newValue) => {
if (newValue){
pictureList.value=Array.isArray(newValue) ? newValue : props.modelValue.split(",");
}else{
pictureList.value = []
}
},{deep:true,immediate:true})
// 預(yù)覽圖片開關(guān)
const previewVisible = ref(false)
// 預(yù)覽圖片url
const previewImageUrl = ref('')
// 點(diǎn)擊預(yù)覽圖片按鈕回調(diào)
function previewPicture(url) {
previewVisible.value = true
previewImageUrl.value = url
}
// 點(diǎn)擊刪除圖片按鈕回調(diào)
function deletePicture(url) {
pictureList.value = pictureList.value.filter(item => url !== item)
emits('update:modelValue', pictureList.value)
}
</script>
<template>
<div id="app">
<div class="container">
<div class="container-item" :style="{width:pictureWidth ,height:pictureHeight}" v-for="item in pictureList" :key="item">
<img class="img-item" :src="item" alt=""/>
<div class="overlay">
<span class="opt" @click="previewPicture(item)">預(yù)覽</span>
<span class="opt" @click="deletePicture(item)">刪除</span>
</div>
</div>
<div class="container-item add-container" :style="{width:pictureWidth ,height:pictureHeight}">
<slot>+</slot>
</div>
</div>
<!-- 圖片預(yù)覽-->
<el-dialog v-model="previewVisible" style="overflow: auto">
<div style="height: 100%; width: 100%; display: flex; justify-content: center; align-items: center;">
<img style="object-fit: cover; height: 100%; width: 100%;" :src="previewImageUrl" alt="Preview Image"/>
</div>
</el-dialog>
</div>
</template><style scoped lang="scss">
.container {
display: flex;
flex-wrap: wrap;
width: 100%;
}
.container-item {
height: 150px;
width: 150px;
margin: 3px;
border: 1px solid #cecaca;
border-radius: 5px;
overflow: hidden;
position: relative;
&:hover .overlay {
opacity: 1;
}
.img-item {
height: 100%;
width: 100%;
}
.overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
color: #fff;
font-size: 14px;
opacity: 0;
transition: opacity .5s;
.opt {
cursor: pointer;
margin: 8px;
}
}
}
.add-container {
border: 1px dashed #cecaca;
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
&:hover {
border: 1px dashed blue;
}
}
</style>2.PictureSpaceFacade 組件使用
<script setup>
import {ref} from "vue";
import PictureSpaceFacade from "./components/PictureSpaceFacade.vue";
// 獲取隨機(jī)圖片
async function getPicture() {
const response = await fetch('https://dog.ceo/api/breeds/image/random')
const res = await response.json()
return res.message
}
// 圖片數(shù)組
const pictureList = ref([])
// 初始化圖片數(shù)組(準(zhǔn)備測試數(shù)據(jù))
async function initPicture() {
for (let i = 0; i < 3; i++) {
pictureList.value.push(await getPicture())
}
}
// 圖片空間開關(guān)
const pictureSpaceVisible = ref(false)
// 打開圖片空間
function openPictureSpace() {
pictureSpaceVisible.value = true
}
// 關(guān)閉圖片空間(從圖片空間選擇圖片后對 pictureList進(jìn)行填充)
async function closePictureSpace() {
for (let i = 0; i < 2; i++) {
pictureList.value.push(await getPicture())
}
pictureSpaceVisible.value = false
}
initPicture()
</script><template>
<el-row>
<el-col :span="8">
<PictureSpaceFacade v-model="pictureList" width="220px" picture-width="100px" picture-height="100px">
<div style="height: 100%;width: 100%;display: flex;justify-content: center;align-items: center;"
@click="openPictureSpace">+
</div>
</PictureSpaceFacade>
</el-col>
</el-row>
<!-- 圖片空間彈出框-->
<el-dialog v-model="pictureSpaceVisible" title="圖片空間" @close="closePictureSpace">
</el-dialog>
</template>
<style scoped lang="scss">
</style>
圖片寬度和高度就是圖片自身。
鼠標(biāo)懸浮會出現(xiàn)操作按鈕(這里的文字可以自行修改為icon圖標(biāo))。

點(diǎn)擊圖片添加框,會彈出圖片空間組件供我們選擇。
我們通過選項(xiàng)綁定將pcitureList存入圖片空間,這樣在圖片空間中就能夠修改我們的圖片數(shù)組。

總結(jié)
以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。
- Vue3+Vite+ElementPlus構(gòu)建學(xué)習(xí)筆記
- Vue3通過JSON渲染ElementPlus表單的流程步驟
- vue3+js+elementPlus使用富文本編輯器@vueup/vue-quill詳細(xì)教程
- vue3基于elementplus 簡單實(shí)現(xiàn)表格二次封裝過程
- vue3+elementplus 樹節(jié)點(diǎn)過濾功能實(shí)現(xiàn)
- 如何在Vue3中正確使用ElementPlus,親測有效,避坑
- vue3+elementplus前端生成圖片驗(yàn)證碼完整代碼舉例
- Vue3 + ElementPlus動態(tài)合并數(shù)據(jù)相同的單元格的完整代碼
相關(guān)文章
vue router 通過路由來實(shí)現(xiàn)切換頭部標(biāo)題功能
在做單頁面應(yīng)用程序時,一般頁面布局頭尾兩塊都是固定在布局頁面,中間為是路由入口。這篇文章主要介紹了vue-router 通過路由來實(shí)現(xiàn)切換頭部標(biāo)題 ,需要的朋友可以參考下2019-04-04
vue-cli如何修改打包項(xiàng)目結(jié)構(gòu)及前綴
這篇文章主要介紹了vue-cli如何修改打包項(xiàng)目結(jié)構(gòu)及前綴問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-07-07
Vue Axios異步與數(shù)據(jù)類型轉(zhuǎn)換問題淺析
總的來說這并不是一道難題,那為什么要拿出這道題介紹?拿出這道題真正想要傳達(dá)的是解題的思路,以及不斷優(yōu)化探尋最優(yōu)解的過程。希望通過這道題能給你帶來一種解題優(yōu)化的思路,Axios是一個開源的可以用在瀏覽器端和Node JS的異步通信框架,主要作用就是實(shí)現(xiàn)AJAX異步通信2023-01-01

