vue.extends编写全局弹框组件

540 阅读1分钟

场景

场景一:类似于alert的提示,并且带有各种操作。比如:文件上传,耗时比较久,需要全局弹出页面展示文件上传进度,同时页面可以进行其余操作(比如上传进度,再比上传失败重新上传等等)。弹框支持最小化和关闭。

场景二:在vue项目中需要根据返回的code不同去展示不同的提示,并且提示中带有跳转、留言等功能。(当然这个操作可以在vue组件中完成,但是如果代码非常“优美”,以至于你不敢动原来的代码,而原来的代码又是在js文件中统一处理的,那么这个时候可以用extend)

其实简单来说就是使用vue实现类似于alert的功能。

代码

组件文件

components/uploadModal/src/main.vue

<template>
    <div class="fixed font" v-if="visible">
        <header class="flexRowBetween">
            <span style="color: #100DB1;">上传数据</span>
            <span>
                <i style="font-size:18px" v-if="isOpen" class="el-icon-arrow-down" @click="()=>isOpen = !isOpen"></i>
                <i style="font-size:18px" v-if="!isOpen" class="el-icon-arrow-up" @click="()=>isOpen = !isOpen"></i>
                <i style="font-size:18px" @click="()=>visible=false" class="el-icon-close"></i>
            </span>
        </header>
        <div style="margin-top:10px">
            <span>
                <span style="color:#50E39D">已成功1/1</span> |
                <span>1234KB</span> |
                <span style="color:red">已失败0</span> |
                <span>传输用时 00:00:00</span>
            </span>
        </div>
        <div>
            <div v-for="item in fileList" :key="item.name">
                <div class="fileListItem">
                    <span class="fileTitle">{{item.name}}</span>
                    <span>
                        <span style="color:#100DB1">重新上传</span>
                        <i style="color:red" class="el-icon-error"></i>
                    </span>
                    <i style="color:#50E39D" class="el-icon-success"></i>
                </div>
            </div>
        </div>
    </div>
</template>
<script>
export default {
    data() {
        return {
            isOpen: true,
            fileList: [],
            visible: false
        }
    },
    methods: {
        show(fileList) {
            this.fileList = fileList
            this.visible = true
        }
    }
}
</script>
<style lang="scss" scoped>
.fixed {
    position: fixed;
    right: 19px;
    bottom: 16px;
    z-index: 100;
    width: 550px;
    height: 368px;
    background: #FFFFFF;
    box-shadow: 5px 4px 22px 1px rgba(33, 64, 100, 0.12);
    border-radius: 4px;
    border: 1px solid #DBDDE6;
    padding: 19px
}

.flexRowBetween {
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.font {
    font-size: 12px;
    font-family: PingFangSC-Regular, PingFang SC;
    font-weight: 400;
    color: #484D6A;
    line-height: 17px;
}

.fileListItem {
    display: flex;
    justify-content: space-between;
    align-items: center;
    height: 27px;
    background: rgba(213, 213, 245, 0.31);
    border-radius: 5px;
    padding: 10px;
}

.fileTitle {
    font-size: 10px;
    font-family: PingFangSC-Medium, PingFang SC;
    font-weight: 500;
    color: #7876C6;
    line-height: 14px;
    display: inline-block;
}
</style>

导出实例

components/uploadModal/src/index.js

import Vue from "vue";
import main from "./main";
let uploadGlobal = Vue.extend(main);
let res = new uploadGlobal().$mount('#upLoadGlobal') //在index.html中声明id为upLoadGlobal的容器
export default res;

准备use方法

components/uploadModal/index.js

import uploadGlobal from './src'
export default function (Vue) {
  Vue.prototype.$uploadGlobal = uploadGlobal
}

main.js挂载

import uploadModal from './components/uploadModal/index.js'
Vue.use(uploadModal)

使用

this.$uploadGlobal.show(this.fileList)