Vue自定义组件之图片缩放

    点击缩略图放大,查看原比例高清大图,是我们做完图片上传功能后经常需要遇到面对的问题,比如图片预览。虽然这个问题zoom.js这个现成插件可以帮我们解决,美中不足的是,zoom.js放大后的图片会受原img本身外层高宽限制,恰恰我们做缩略图往往会限制外层宽高以便多图呈现,并希望放大后的图片不受原img影响,基于这个问题,下面借助layer.js简单封装了一个Vue图片缩放组件。

目录

1.demo页面

2.组件核心:JS/CSS/辅助页面

3.demo演示

4.实现原理简述


1.demo页面

kt-zoom-demo.html
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
    <link rel="stylesheet" href="kt-zoom.css">
    <style>
        .wrap {
            border: 1px solid;
            /* 自身水平垂直居中 */
            width: 300px;
            height: 300px;
            position: absolute;
            top: 0;
            bottom: 0;
            left: 0;
            right: 0;
            margin: auto;
            /* 内部元素水平垂直居中 */
            display: flex;
            justify-content: center;
            align-items: center;
        }

        .wrap img {
            max-width: calc(100% - 12px);
            max-height: calc(100% - 12px);
        }

        .el-card__body {
            position: relative;
            height: calc(100vh - 100px);
        }

        .el-icon-view:hover{
            color: #f56c6c;
        }
    </style>
    <title>Document</title>
</head>
<body>
<div id="app">
    <el-card style="padding: 20px;" v-cloak>
        <div slot="header">
            KT-ZOOM-DEMO
            <kt-zoom custom :src="src">
                <el-button style="font-size: 16px;" type="text" size="mini">
                    <i class="el-icon-view"></i>
                </el-button>
            </kt-zoom>
        </div>

        <div class="wrap">
            <kt-zoom class="real-img" :src="src"></kt-zoom>
        </div>
    </el-card>
</div>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<script src="kt-zoom.js"></script>
<script>
    const APP = new Vue({
        el: '#app',
        data() {
            return {
                src: 'images/tongliya.jpg'
            }
        }
    });
</script>
</body>
</html>

2.组件核心:JS/CSS/辅助页面

kt-zoom.js
document.write("<script src='layer/layer.js'></script>");

Vue.component("kt-zoom", {
    template: `
      <span v-if="custom" @click="clickMe" v-cloak><slot></slot></span>
      <img v-else class="zoom-in" :src="src || 'images/zhanwutupian.png'" alt="This is an image" @click="clickMe" v-cloak>
    `,
    props: {
        src: String,
        custom: {
            type: Boolean,
            default: false
        }
    },
    methods: {
        clickMe() {
            // const $ev = ev || event;
            // let src = $ev.target.getAttribute('src');
            let src = this.src || 'images/zhanwutupian.png';
            if (src.indexOf('=') !== -1) src = src.replace(/=/g, "%3D");
            layer.open({
                type: 2,
                title: false,
                closeBtn: 0,
                area: ['60%', '80%'],
                skin: 'layui-layer-nobg', //没有背景色
                shadeClose: true,
                content: `!!kt-zoom-img!!.html?src=${src}`
            });
        }
    }
});
kt-zoom.css
[v-cloak] {
    display: none !important;
}

.zoom-in {
    transition: width 1s, height 1s;
}

.zoom-in:hover {
    cursor: url("images/zoomin.ico"), auto;
}

.zoom-out {
    transition: width 1s, height 1s;
}

.zoom-out:hover {
    cursor: url("images/zoomout.ico"), auto;
}

.kt-zoom_wrap {
    /* 自身水平垂直居中 */
    width: 100%;
    height: 100%;
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    margin: auto;
    /* 内部元素水平垂直居中 */
    display: flex;
    justify-content: center;
    align-items: center;
}

.kt-zoom_wrap img {
    max-width: calc(100% - 12px);
    max-height: calc(100% - 12px);
}
!!kt-zoom-img!!.html
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
    <link rel="stylesheet" href="kt-zoom.css">
    <style>
        html, body {
            width: 100%;
            height: 100%;
        }
    </style>
    <title>Document</title>
</head>
<body>
<div id="app">
    <div class="kt-zoom_wrap" v-cloak>
        <img class="zoom-out" :src="src" alt="Here is an img" @click="clickMe">
    </div>
</div>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<script>
    const APP = new Vue({
        el: '#app',
        data() {
            return {
                src: void 0,
            }
        },
        methods: {
            clickMe() {
                // 当你在iframe页面关闭自身时
                let index = parent.layer.getFrameIndex(window.name); // 先得到当前iframe层的索引
                parent.layer.close(index); // 再执行关闭
            },
            // 获取父页面url传参
            getParams(){
                const url = location.search;
                let params = {};
                if (url.indexOf("?") !== -1) {
                    let str = url.substr(1);
                    let strs = str.split("&");
                    for (let i = 0; i < strs.length; i++) {
                        params[strs[i].split("=")[0]] = unescape(strs[i].split("=")[1]);
                    }
                }
                return params;
            }
        },
        created() {
            this.src = encodeURI(this.getParams().src) || 'images/zhanwutupian.png';
        }
    });
</script>
</body>
</html>

3.demo演示

4.实现原理简述

1.通过layer弹出框插件,点击缩略图时,弹出辅助页面并传入src路径。
2.辅助页面放置img原图,设置max-width、max-height百分百并且水平垂直居中即可。
PS:完整demo以图包方式存放,右键 演示demo.gif 存储=》重命名xxx.rar=>解压即可。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhengvipin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值