在components文件中新建一个子组件,文件的所有代码如下:
<template>
<div v-if="type == 'image'">
<!--图片列表,value是完整url数组-->
<ul class="el-upload-list el-upload-list--picture-card" v-for="(item,index) in value" :key="index">
<li tabindex="0" class="el-upload-list__item is-ready" :style="'width: '+width+'px;height: '+height+'px'">
<div>
<img :src="item" alt="" class="el-upload-list__item-thumbnail">
<span class="el-upload-list__item-actions">
<!--向左排序-->
<span class="el-upload-list__item-preview" v-if="index != 0" @click="moveMaterial(index,'up')">
<i class="el-icon-back"></i>
</span>
<!--查看大图-->
<span class="el-upload-list__item-preview" @click="zoomMaterial(index)">
<i class="el-icon-view"></i>
</span>
<!--删除-->
<span class="el-upload-list__item-delete" @click="deleteMaterial(index)">
<i class="el-icon-delete"></i>
</span>
<!--向后排序-->
<span class="el-upload-list__item-preview" v-if="index != value.length-1" @click="moveMaterial(index,'down')">
<i class="el-icon-right"></i>
</span>
</span>
</div>
</li>
</ul>
<!--上传图片的+按钮显示与否,数量够即不显示-->
<div tabindex="0" v-if="num > value.length" @click="toSeleteMaterial" class="el-upload el-upload--picture-card" :style="'width: '+width+'px;height: '+height+'px;'+'line-height:'+height+'px;'">
<i class="el-icon-plus"></i>
</div>
<!--点击查看大图的弹窗-->
<el-dialog append-to-body :visible.sync="dialogVisible" width="35%">
<img :src="url" alt="" style="width: 100%">
</el-dialog>
<!--图片素材库弹窗-->
<el-dialog :title="$t('rf_material.picLibrary')" append-to-body :visible.sync="listDialogVisible" width="70%">
<el-container>
<!--左侧分组-->
<el-aside width="unset">
<!--添加分组-->
<div style="margin-bottom: 10px">
<el-button class="el-icon-plus" size="small" @click="materialgroupAdd()">{{$t('rf_material.addGroup')}}</el-button>
</div>
<!--标签页-->
<el-tabs tab-position="left" v-model="materialgroupObjId" v-loading="materialgroupLoading" @tab-click="tabClick">
<el-tab-pane v-for="(item,index) in materialgroupList" :key="index" :name="item.id">
<span slot="label"> {{item.name}}</span>
</el-tab-pane>
</el-tabs>
</el-aside>
<!--右侧卡片-->
<el-main>
<el-card>
<!--卡片标题-->
<div slot="header">
<el-row>
<el-col :span="12">
<span>{{materialgroupObj.name}}</span>
<!--id=-1即全部分组,不是全部分组方显示重命名和删除按钮-->
<span v-if="materialgroupObj.id != '-1'">
<el-button size="small" type="text" @click="materialgroupEdit(materialgroupObj)" class="el-icon-edit" style="margin-left: 10px;">{{$t('rfbutton.rename')}}</el-button>
<el-button size="small" type="text" @click="materialgroupDelete(materialgroupObj)" class="el-icon-delete" style="margin-left: 10px;color: red">{{$t('rfbutton.delete')}}</el-button>
</span>
</el-col>
<el-col :span="12" v-if="materialgroupObj.id != '-1'" style="text-align: right;">
<el-upload
:headers="headers"
action="/admin/sys-file/upload"
:file-list="[]"
:on-progress="handleProgress"
:before-upload="beforeUpload"
:on-success="handleSuccess">
<el-button size="small" type="primary">{{$t('rfbutton.uploadImg')}}</el-button>
</el-upload>
</el-col>
</el-row>
</div>
<!--卡片内容-->
<div v-loading="tableLoading">
<el-alert v-if="tableData.length <= 0" title="暂无数据" type="info" :closable="false" center show-icon></el-alert>
<el-row :gutter="5"><!--gutter:栅格间隔-->
<el-checkbox-group v-model="urls" :max="num - value.length">
<el-col :span="4" v-for="(item,index) in tableData" :key="index">
<el-card :body-style="{ padding: '5px' }">
<!--fit:确定图片如何适应容器框fill / contain / cover / none / scale-down;preview-src-list:开启图片预览功能-->
<el-image :src="item.url" fit="contain" :preview-src-list="[item.url]" style="width: 100%;height: 100px"></el-image>
<div>
<el-checkbox class="material-name" :label="item.url">{{$t('radio.choose')}}</el-checkbox>
<el-row>
<el-col :span="24" class="col-do">
<el-button type="text" size="medium" @click="materialDel(item)">{{$t('rfbutton.delete')}}</el-button>
</el-col>
</el-row>
</div>
</el-card>
</el-col>
</el-checkbox-group>
</el-row>
<el-pagination
@size-change="sizeChange"
@current-change="pageChange"
:current-page.sync="page.currentPage"
:page-sizes="[12, 24]"
:page-size="page.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="page.total"
class="pagination">
</el-pagination>
</div>
</el-card>
</el-main>
</el-container>
<span slot="footer" class="dialog-footer">
<el-button @click="listDialogVisible = false">{{$t("cancelText")}}</el-button>
<el-button type="primary" @click="submitUrls">{{$t("submitText")}}</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import { getFileService,getGrouplist,addGroupObj,putGroupObj,delGroupObj,getPicLibraryList,addPicLibraryObj,delPicLibraryObj } from '@/util/util'
import store from '@/store'
import { mapGetters } from 'vuex'
export default {
name: "materialList",
props: {
//素材数据
value:{
type: Array,
default() {
return []
},
},
//素材类型
type:{
type: String,
},
//素材限制数量,默认5个
num:{
type: Number,
default() {
return 5
},
},
//宽度
width: {
type: Number,
default() {
return 150
}
},
//高度
height: {
type: Number,
default() {
return 150
}
}
},
data() {
return {
headers: {
Authorization: 'Bearer ' + store.getters.access_token
},
dialogVisible: false,
url: '',
listDialogVisible: false,
materialgroupList: [],
materialgroupObjId: '',
materialgroupObj: {},
materialgroupLoading: false,
tableData: [],
page: {
total: 0, // 总页数
currentPage: 1, // 当前页数
pageSize: 12, // 每页显示多少条
ascs: [],//升序字段
descs: 'create_time'//降序字段
},
tableLoading: false,
groupId: null,
urls: [],
baseImgUrl: '',
}
},
computed: {
...mapGetters(['permissions','languageID','language'])
},
created:function () {
//在页面创建时需处理内容,在此添加,比如给下拉框绑定change事件等
this.baseImgUrl=getFileService()
},
methods:{
//向左右排序
moveMaterial(index,type){
if(type == 'up'){//向左
let tempOption = this.value[index - 1]
this.$set(this.value, index - 1, this.value[index])
this.$set(this.value, index, tempOption)
}
if(type == 'down'){//向右
let tempOption = this.value[index + 1]
this.$set(this.value, index + 1, this.value[index])
this.$set(this.value, index, tempOption)
}
},
//查看大图
zoomMaterial(index){
this.dialogVisible = true
this.url = this.value[index]
},
//删除图片
deleteMaterial(index){
let that = this
this.$confirm('是否确认删除?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(function() {
that.value.splice(index,1)
that.urls = []
})
},
//打开素材库
toSeleteMaterial(){
this.listDialogVisible = true
if(this.tableData.length <= 0){
this.materialgroupPage()
}
},
//分组数据
materialgroupPage(){
this.materialgroupLoading = true
getGrouplist(this.languageID).then(res => {
this.materialgroupLoading = false
this.materialgroupList=res.data.data
this.materialgroupList.unshift({
id: '-1',
name: '全部分组'
})
this.tabClick({
index: 0
})
});
},
//删除分组
materialgroupDelete(materialgroupObj){
let that = this
this.$confirm('是否确认删除该分组?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(function() {
delGroupObj(materialgroupObj.id)
.then(function() {
that.$delete(that.materialgroupList, materialgroupObj.index)
that.getPage(that.page)
})
})
},
//重命名分组
materialgroupEdit(materialgroupObj){
let that = this
this.$prompt('请输入分组名', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
inputValue: materialgroupObj.name,
}).then(({ value }) => {
materialgroupObj.name=value
putGroupObj(materialgroupObj).then(function() {
materialgroupObj.name = value
that.$set(that.materialgroupList, materialgroupObj.index, materialgroupObj)
})
})
},
//添加分组
materialgroupAdd(){
let that = this
//element的MessageBox消息弹窗
this.$prompt('请输入分组名', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
}).then(({ value }) => {
addGroupObj({
name: value,
languageId:this.languageID
}).then(function() {
that.materialgroupPage()//刷新分组数据
})
})
},
//点击标签页事件
tabClick(tab,event){
console.log(tab, event);
this.urls = []
let index = Number(tab.index)
let materialgroupObj = this.materialgroupList[index]
materialgroupObj.index = index
this.materialgroupObj = materialgroupObj
this.materialgroupObjId = materialgroupObj.id
this.page.currentPage = 1
this.page.total = 0
if(materialgroupObj.id != '-1'){
this.groupId = materialgroupObj.id
}else{
this.groupId = null
}
this.getPage(this.page)
},
getPage(page, params) {
this.tableLoading = true
getPicLibraryList(Object.assign({
current: this.page.currentPage,
size: this.page.pageSize,
groupId: this.groupId,
languageId: this.languageID
})).then(res=>{
this.tableLoading = false
this.tableData = res.data.data.records
this.page.total = res.data.data.total
this.page.currentPage = res.data.data.current
this.page.pageSize = res.data.data.size
}).catch(() => {
this.tableLoading=false
})
},
//当前每页总数改变时触发的函数
sizeChange(val) {
console.log(val)
this.page.currentPage = 1
this.page.pageSize = val
this.getPage(this.page)
},
//当前页码改变时触发的函数,即你点击 1 , 2 , 3 ,它就跳到相应的数据页
pageChange(val) {
console.log(val)
this.page.currentPage = val
//this.page.pageSize = val
this.getPage(this.page)
},
//删除图片
materialDel(item){
let that = this
this.$confirm('是否确认删除该素材?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(function() {
delPicLibraryObj(item.id)
.then(function() {
that.$message.success(that.$t("rfbutton.delete")+' '+that.$t("successText"))
that.getPage(that.page)
})
})
},
handleProgress(event, file, fileList){
// let uploadProgress = file.percentage.toFixed(0)
// this.uploadProgress = uploadProgress
},
//上传图片格式和大小校验
beforeUpload(file){
const isPic =
file.type === "image/jpeg" ||
file.type === "image/png" ||
file.type === "image/gif" ||
file.type === "image/jpg"
const isLt2M = file.size / 1024 / 1024 < 2
if (!isPic) {
this.$message.error("上传图片只能是 JPG、JPEG、PNG、GIF 格式!")
return false
}
if (!isLt2M) {
this.$message.error('上传图片大小不能超过 2MB!')
}
return isPic && isLt2M
},
//上传图片成功
handleSuccess(res, file, fileList){
// this.uploadProgress = 0
console.log(res, file, fileList)
let that = this
addPicLibraryObj({
type: 1,//1图片,2视频
groupId: this.groupId != '-1' ? this.groupId : null,
languageId: this.languageID,
name: file.name,
url: this.baseImgUrl+ res.data.bucketName + '/' + res.data.fileName
// url: res.link
}).then(function() {
that.$message.success(that.$t("rfbutton.uploadImg")+' '+that.$t("successText"))
that.getPage(that.page)
})
},
//提交选取的图片
submitUrls(){
this.urls.forEach(item => {
this.$set(this.value,this.value.length, item)
})
this.listDialogVisible=false
},
materialRename(item){
let that = this
this.$prompt('请输入素材名', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
inputValue: item.name,
}).then(({ value }) => {
putObj({
id: item.id,
name: value
}).then(function() {
that.getPage(that.page)
})
}).catch(() => {
})
},
materialUrl(item){
let that = this
this.$prompt('素材链接', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
inputValue: item.url,
}).then(({ value }) => {
}).catch(() => {
})
},
handleCommand(command) {
let that = this
let s = command.split('-')
putObj({
id: s[0],
groupId: s[1]
}).then(function() {
that.getPage(that.page)
})
}
}
};
</script>
<style lang="scss" scoped>
.material-name{
padding: 8px 0px;
}
.col-do{
text-align: center;
}
.button-do{
padding: unset!important;
font-size: 12px;
}
</style>
文件中涉及的接口需换成自己后台的接口,即可直接使用。
<MaterialList v-model="imageArr" :value="imageArr" style="width: 500px" type="image" :num=1 :width=150 :height=150></MaterialList>
import MaterialList from '@/components/material'
components: {
MaterialList
},
效果如链接中管理闪屏商品-新增-商品图片
添加链接描述