首页 默认分类 正文
  • 本文约2764字,阅读需14分钟
  • 41
  • 0

vue加载进度组件函数式编写

摘要

一个用来显示下载文件进度的功能,如果使用普通的组件的话,一种是要在需要用的地方引入,另外一种是在最外层引入,通过vuex或eventbus传递参数调用。上面两种方法有一个弊端就是。这个组件在不使用的情况下如果不使用v-if判断都是渲染在页面的,如果使用v-if判断。又需要通过vuex eventbus等注册并监听事件

一个用来显示下载文件进度的功能,如果使用普通的组件的话,一种是要在需要用的地方引入,另外一种是在最外层引入,通过vuex或eventbus传递参数调用。上面两种方法有一个弊端就是。这个组件在不使用的情况下如果不使用v-if判断都是渲染在页面的,如果使用v-if判断。又需要通过vuex eventbus等注册并监听事件。
demo

1. 声明组件

./progress.jsx

import { createApp} from 'vue';
import styled from 'vue3-styled-component'; //样式化组件,可以在js中写传统的css
import { ThemeProvider } from 'vue3-styled-component'
import { ElProgress } from 'element-plus'
//最外层 
const modal = styled('div')`
      position: absolute;
      left:0;
      top:0;
      background: ${props => props.background};
      height: ${props => props.prentIsBody ? '100vh' : '100%'};
      width: ${props => props.prentIsBody ? '100vw' : '100%'};
      z-index: 99999;
      display: flex;
      align-items: center;
    justify-content: center;
`;
const progressInner = styled('div')`
      display: flex;
      width: ${(props) => (props.type=='line' ? "100%" : "unset")};
      flex-direction: column;
      align-items: center;
`;
const loadingText = styled('p')`
      color: var(--el-color-primary);
      margin: 3px 0;
      font-size: 14px;
    margin-top: 16px;
`;
// 进度组件
let progressComponent = {
    inheritAttrs:false,
    props: {
        parentIsBody: {
            typeof: Boolean,
            require: true,
            default: true
        },
        percentage: {
            type: [Number, String, Object],
            default: 0
        },
        bottomText: {
            type: [String, Object],
            default: '数据加载中!'
        },
        background:{
            type: String,
            default: 'rgba(0,0,0,.6)'
        }
    },
    render(ctx) {
        const { $props, $emit, $attrs, $slots } = ctx;
         let percentage = (typeof $props.percentage == 'object') ? $props.percentage.value : $props.percentage;
         let bottomText = (typeof $props.bottomText == 'object') ? $props.bottomText.value : $props.bottomText;
        //pug代码
        return <ThemeProvider class='theme-provider'>
            <modal class='qi-progress-modal' parentIsAppendBody={$props.parentIsAppendBody} background={$props.background}>
                <progressInner type={$attrs.type} class='qi-progress-inner'>
                    <ElProgress {...$attrs} percentage={percentage} style={{ width: (!$attrs.type || ['', 'line'].includes($attrs.type))?'95%':'unset'}}>
                        {$slots.default(percentage)}
                    </ElProgress>
                    <loadingText>{bottomText}</loadingText>
                </progressInner>
            </modal>
        </ThemeProvider>
    }
}

export const Qiprogress = (props = {}) => {
    let warpEl = document.createElement('div');
    warpEl.setAttribute('id','qi-progress-warp')
    if(props.el){
        if (props.el instanceof HTMLElement){
            props.el.appendChild(warpEl);
        }else{
            document.querySelector(props.el).appendChild(warpEl);
        }
    }else{
        document.body.appendChild(warpEl);
    }
    let parentIsBody = props.el?false:true;
    delete props.el;
    let background = props.background||null;
    delete props.background;
    let solts = ( props.content)||null;
    delete props.content;
    const app = createApp(<progressComponent>{solts}</progressComponent>,{
        ...props,
        parentIsBody,
        background
    });
    app.mount(warpEl);
    return{
        destoryed:()=>{
            app.unmount(warpEl);
            warpEl.remove();
        }
    }
}

2. 调用组件

./index.vue

import { ref } from 'vue';
import { Qiprogress } from './progress.jsx';

let progressInstance = null;
let progressOptions={
    type: "circle",
    percentage: ref(0),
    bottomText: ref('获取数据中....'),
    background:'rgba(0,0,0,.2)',
     content:(data)=>{
      return h('div', { class: 'tip-text' }, data+'%')
    }
}

progressInstance = Qiprogress(progressOptions)
setInterval(() => {
    progressOptions.percentage.value++;
    if (progressOptions.percentage.value>100){
        progressInstance.destoryed()
    }
}, 300);

3.属性说明

参数 默认值 类型 说明
percentage 0 [Number, String, Object] 进度,如果是动态变化的需要使用ref()创建对象
bottomText 数据加载中! [String, Object] 底部显示的提示文字,如果是动态变化的需要使用ref()创建对象
background rgba(0,0,0,.6) String 背景色
content [String, Number,Function] 中间显示文本,即的插槽 如果需要传入html,使用h函数,Function:(percentage)=>{}

其它参数: 参考 el-progress 如:
element-plus/el-progress/参数

4. 方法

方法名 说明 参数
destoryed 卸载组件
评论
友情链接