IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 手把手实现图片预览插件(三) -> 正文阅读

[JavaScript知识库]手把手实现图片预览插件(三)

因为项目需要,之前封装了一个图片点击预览的全局组件。这次我们尝试将它封装成一个插件。通过命令式的方式来达到点击预览的效果。

在封装插件之前。我们要对vue的插件机制有个基本了解。vue的插件的核心是use方法。

其实就是在Vue类上添加一个use方法,这个方法看传入第一个参数是否是函数,如果是函数则直接执行,如果是对象,就看是否有install方法,然后执行install方法,执行的时候把Vue类传入,同时把用户传入的option也传入

Vue.use = function (plugin) {   
    // 忽略已注册插件
    if (plugin.installed) {
      return
    }
    
    // 集合转数组,并去除第一个参数
    var args = toArray(arguments, 1);
    
    // 把this(即Vue)添加到数组的第一个参数中
    args.unshift(this);
    
    // 调用install方法
    if (typeof plugin.install === 'function') {
      plugin.install.apply(plugin, args);
    } else if (typeof plugin === 'function') {
      plugin.apply(null, args);
    }
    
    // 注册成功
    plugin.installed = true;
    return this;
  };

而在install方法里。vue给我们提供了几种插件注册的方式

(1) 全局minx混入? (2)全局组件注册 (3)给vue对象的原型添加该插件

也就是说。插件调用的方式我们可以选择在全局组件的方式调用,也可以选择在vue原型上调用或者在minx混入里的某个时机去调用。

说了那么多,我们开始自己的图片预览组件的开发

(1) 我们在src下新建一个plugins文件夹。新建两个文件:

prevImg.vue和index.js

<template>
    <div class="prewImg-wrap" v-show="show">
        <div class="mask"></div>       
            <div class="action">
                <i class="el-icon-minus ic"></i>
                <i class=" ic el-icon-plus"></i>
                <i class=" ic el-icon-refresh-right"></i>
                <i class=" ic el-icon-close" @click="close"></i>
            </div>
            <div class="img-wrap">
                <span v-if="loading" style="color:#fff">加载中...</span>
                <img v-else ref="img" :src="url" alt="" class="pic" 
                    @load="handleImgLoad"
                    @error="handleImgError">
            </div>   
    </div>
</template>

<script>
    export default {
        data(){
            return {
                show: false,
                loading:false,
                url:"https://s1.chu0.com/src/img/gif/30/30e530c90d674d26aa5afb35ab7eda84.gif"
            }
        },
        mounted(){
            this.loadImg()
        },
        watch:{
           url(val) {
            this.$nextTick(_ => {
                const $img = this.$refs.img;
                if (!$img.complete) {
                this.loading = true;
                }
            });
            }
        },
        methods:{
            close(){
                this.show=false
            },
            handleImgLoad(){
                this.loading=false
            },
            handleImgError(e){
                console.log("e-rror--",e)
                this.loading=false
            }
        }

    }
</script>
<style scoped>
    
.prewImg-wrap{
    position:fixed;
    left:0;
    top:0;
    width: 100%;
    height: 100%;;
   overflow: hidden;
   z-index:1;
}
.action{
    width: 200px;
    padding: 20px;
    position: absolute;
    right:10px;
    top:20px;
    color:#fff;
    z-index: 30;
    display: flex;
    justify-content: flex-end;
}
.ic{
    display: inline-block;
    margin-right: 10px;
}
.mask{
    background: rgba(0,0,0,0.6);
    position: absolute;
    top:0;
    left:0;
    z-index: 10;
    width: 100%;
    height: 100%;
}
.img-wrap{
   position: absolute;
    top:0;
    left:0;
    width: 100%;
    height: 100%;
    z-index:20;
    display: flex;
    justify-content: center;
    align-items: center;
}
.pic{
    max-height: 100%;
    max-width: 100%;
}

</style>

prevImg/index.js

import PrevView from "./prewImg.vue"
export default {

    install(Vue,options){
        let PrevVueConstructor= Vue.extend(PrevView)
        let instance= new PrevVueConstructor()
        document.body.appendChild(instance.$mount().$el);

        let prevObj={
            show(opts={text:"",url:""}){
                console.log("instance:",instance)
                instance.show=true
                instance.text=opts.text||""
                instance.url=opts.url||""
            },
            hide(){
                instance.show=false
                instance=null
            }
        }
        if(!Vue.$prevObj){
            Vue.$prevObj=prevObj
        }
        Vue.prototype.$prevImg = prevObj
    }

}

这个文件使我们这个插件的核心。首先我们通过vue.extend构造一个基于vue的构造函数,它类似于vue的实例。具备vue实例的所有属性和方法,和根vue实例不同的是,通过extend构造的子类只其data只能是一个函数。我们创建Vue实例时,都会有一个el选项,来指定实例的根节点,如果不写el选项,那组件就处于未挂载状态。Vue.extend?的作用,就是基于 Vue 构造器,创建一个‘ 子类 ',再配合$mount,就可以渲染组件,并且挂载到任意指定的节点上,比如body(这是单文件组件做不到的)

在show方法中,console.log("instance:",instance)能看到它的具体结构。也正是因为它。所以我们可以直接访问到我们prewImg组件中data定义的数据。比如show,我们就可以通过操作show变量来控制open和hide方法直接让prevImg组件展示或隐藏。

最后我们把这个prevImg对象挂载到vue的原型上。

(2)main.js中引入 prevImg文件夹下的index.js

import Vue from 'vue'
import App from './App.vue'
import "./directives/composImg"
Vue.config.productionTip = false
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import prewImg from "./plugins/prewImg"

Vue.use(ElementUI);

Vue.use(prewImg)
new Vue({
  render: h => h(App),
}).$mount('#app')

(3)具体使用

    <el-button @click="openPrev">打开预览</el-button>
    <el-button @click="closePrve">关闭预览</el-button>
<script>
export default{

   data(){
    return{
        restaurants: [],
        state1: '',
        url:"https://baj-dabanjiz-conf.oss-cn-hangzhou.aliyuncs.com/intelligent-design/image/20210730/middle/9bbeb6570f7b416b1bcbcc59a1b38635.jpg",
        url2:"https://fuss10.elemecdn.com/8/27/f01c15bb73e1ef3793e64e6b7bbccjpeg.jpeg"
        
    }
  },
}
    methods:{
        
        openPrev(){
          this.$prevImg.show({url:this.url2})
        },  
        closePrve(){
            this.$prevImg.hide()
        },          
    }

</script>

  
   

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-08-06 10:34:49  更:2022-08-06 10:39:53 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 9:50:40-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码