1. 程式人生 > >vue專案中編寫一個圖片預覽的公用元件

vue專案中編寫一個圖片預覽的公用元件

今天產品提出了一個檢視影像的功能需求。 在檢視單據的列表中,有一列是影像欄位,一開始根據單據號呼叫介面檢視是否有圖片附件,如果有則彈出一個全屏的彈出層,如果沒有給出提示。而且,從列表進入詳情之後,附件那邊也會有一個檢視影像的按鈕。 所以,根據需求,多個元件需要用到檢視影像的功能,所以考慮做一個公用元件,通過元件傳值的方法將檢視影像檔案的入參傳過去。 後來,產品要求圖片可以旋轉縮放。

廢話不多說,貼上程式碼:

<template>
    <div class="filePreview">
        <el-dialog 
        class="imgList" 
        title="預覽圖片列表" 
        :visible.sync="imgListShow"
        @close="$emit('remove')" 
        fullscreen>
            <div class="allImg">
                <div style="width:200px;height:100%;margin-top:50px;overflow-y: auto;margin: 0 auto;">
                    <img v-for="(item,index) in imgList" :key="item.fileid" :src='item.furl' :class="{ changeColor:changeColor == index}" @click="handlerImg(item,index)">
                </div>
            </div>
            <div style="width:70%;float:left">
            <el-pagination
                style="margin-bottom:20px;"
                background
                @size-change="handleSizeChange"
                @current-change="handleCurrentChange1"
                :current-page.sync="currentImg"
                :page-size="1"
                layout="prev, pager, next, jumper"
                :total="num">
            </el-pagination>
            <div style="width:50%;text-align:center;margin:20px 0">
                <button  @click="rotateL" icon="el-icon-arrow-left">
                    <i class="el-icon-arrow-left"></i>左旋轉
                </button>
                <button  @click="rotateR">右旋轉
                    <i class="el-icon-arrow-right"></i>
                </button>

                <button  @click="scale">
                    <i class="el-icon-zoom-out"></i>縮小
                </button>
                <button  @click="scale1">放大
                    <i class="el-icon-zoom-in"></i>
                </button>
                
            </div>
            <div id="test_3" @mousemove="move" @mouseup="stop">
                <p  @mousedown="start" >
                    <img :src="furl" ref="singleImg" class="originStyle">
                </p>
            </div>
            </div>
        </el-dialog>
    </div>
</template>

<script>
    import {isgetFilePath}from 'api/public_api.js'

    export default {
        data() {
            return {
                imgList:[],
                imgListShow:false,
                num:0,
                furl:'',
                currentImg:1,
                changeColor:-1,
                currentRotate: 0 ,
                currentScale:1,
                canDrag: false,
                offset_x:0,
                offset_y:0,
                mouse_x:0,
                mouse_y:0,
            }
        },
        props:['filePreviewShow','FDJH'],
        created() {
            this.imgListShow = this.filePreviewShow
            this.preview()
        },
        methods: {
            //點選圖片顯示
            handlerImg(obj,index){
                this.currentRotate = 0
                this.currentScale = 1
                this.rotateScale()
                this.$refs.singleImg.style.left = 0
                this.$refs.singleImg.style.top = 0
                this.furl = obj.furl
                this.changeColor = index
                this.currentImg = index+1
            },
            //影像
            preview(){
                let data = {
                    // FDJH:'000002'
                    FDJH:this.FDJH
                }
                isgetFilePath(data).then(res=>{
                    // console.log(res)
                    if(res.TYPE == "S"){
                        this.imgList = JSON.parse(res.MESSAGE)
                        this.num = this.imgList.length
                        if(this.imgList.length > 0){
                            this.furl = this.imgList[0].furl
                            this.changeColor = 0
                        }else{
                            this.$message.warning('影像檔案為空')
                        } 
                    }else{
                        this.$message.warning(res.MESSAGE)
                    }
                    
                    
                })
            },
            handleSizeChange(val) {
                console.log(`每頁 ${val} 條`);
            },
            handleCurrentChange1(val) {
                this.currentRotate = 0
                this.currentScale = 1
                this.rotateScale()
                this.$refs.singleImg.style.left = 0
                this.$refs.singleImg.style.top = 0
                this.furl = this.imgList[val-1].furl
                this.changeColor = val-1
            },
            start(e){
                //滑鼠左鍵點選
                e.preventDefault && e.preventDefault(); //去掉圖片拖動響應
                if(e.button==0){
                    this.canDrag=true;
                    //獲取需要拖動節點的座標
                    this.offset_x = document.getElementsByClassName('originStyle')[0].offsetLeft;//x座標
                    this.offset_y = document.getElementsByClassName('originStyle')[0].offsetTop;//y座標
                    //獲取當前滑鼠的座標
                    this.mouse_x = e.pageX;
                    this.mouse_y = e.pageY;
                }
            },
            move(e){
                e.preventDefault && e.preventDefault()
                if(this.canDrag==true){
                    let _x = e.pageX - this.mouse_x;
                    let _y = e.pageY - this.mouse_y;
                    //設定移動後的元素座標
                    let now_x = (this.offset_x + _x ) + "px";
                    let now_y = (this.offset_y + _y ) + "px";
                    
                    document.getElementsByClassName('originStyle')[0].style.top = now_y
                    document.getElementsByClassName('originStyle')[0].style.left = now_x
                }
            },
            stop(e){
                this.canDrag = false;
            },
            
            //旋轉放大
            rotateScale(){
                this.$refs.singleImg.style.OTransform = 'rotate('+this.currentRotate+'deg)'+'scale('+this.currentScale+')'
                this.$refs.singleImg.style.webkitTransform = 'rotate('+this.currentRotate+'deg)'+'scale('+this.currentScale+')'
                this.$refs.singleImg.style.MozTransform = 'rotate('+this.currentRotate+'deg)'+'scale('+this.currentScale+')'
                this.$refs.singleImg.style.msTransform = 'rotate('+this.currentRotate+'deg)'+'scale('+this.currentScale+')'
                this.$refs.singleImg.style.transform = 'rotate('+this.currentRotate+'deg)'+'scale('+this.currentScale+')'
            },
            //旋轉
            rotateL(){
                this.currentRotate += 15
                this.rotateScale()
            },
            rotateR(){
                this.currentRotate -= 15
                this.rotateScale()
            },
            //縮放
            scale(){
                this.currentScale -= 0.1
                if(this.currentScale <= 0.1){
                    this.currentScale = 0.1
                    this.rotateScale()
                }else{
                    this.rotateScale()
                }
            },
            scale1(){
                this.currentScale += 0.1
                this.rotateScale()
            },
        }
    }
</script>

<style rel="stylesheet/scss" lang="scss" slot-scope="scope">
    .filePreview{
        .imgList{
            .el-dialog__headerbtn{
                font-size:26px;
            }
            .el-dialog__body{
                .allImg{
                    width:30%;
                    float:left;
                    height:600px;
                    img{
                        width: 150px;
                        height: 150px;
                        margin: 5px;
                        cursor: pointer;
                    }
                    .changeColor{
                        border:4px solid #409eff;
                    }
                }
            }
        }
        .originStyle{
            position:absolute;
            left:0;top:0;
            cursor: pointer;
            // transform-origin: 50% 50%;
        }
        #test_3{
            position: relative;
            width: 600px;
            height: 400px;
            overflow: hidden;
            // overflow: scroll;
            & > p{
                position: absolute;
                cursor: move;
                transform-origin: center;
                width: 100%;
                height: 100%;
                padding: 0;
                -webkit-margin-before: 0;
                -webkit-margin-after: 0;
                left: 0;
                top: 0;
                & > img{
                    display: inline-block;
                    vertical-align: middle;
                }
            }
        }
    }
    
    
</style>

後來出現一個問題,有一類的單據的圖片儲存在資料庫中,之前的圖片都是儲存在伺服器中,只需要傳入單據號查詢返回給我圖片路徑即可。

而儲存在資料庫當中不一樣,需要拼接路徑,一下是解決方法:

preview(){

        if(this.imgList.length > 0){
            this.imgList.map(item=>{
                item.furl = process.env.APP_EXCEL_PATH+'portal/gys/querydownloadPurchaFile?fileid='+ item.FILEID +'&gysdh='+item.CREATENAME //介面加入參
            })
        }
        this.num = this.imgList.length
        this.furl = this.imgList[0].furl
        this.changeColor = 0
},

一般情況下,圖片的預覽,圖片儲存在伺服器中,資料庫中一般只儲存路徑。 我們後端我也是醉了,盡給我找事情,說起來都是淚。