进度通过VUEX全局控制,就算切换页面你的下载进度也不会丢失并且在其他页面也能通过btn按钮看到下载进度
<template>
<div :class="percentageVerify?'button-succeed':'button'"
:style="{height:strokeWidth/2+'px',
borderRadius:strokeWidth/2+'px'}"
@click="onclick"
ref="dow">
<span>{{text}}</span>
</div>
</template>
<script>
import {mapGetters} from "vuex";
/**
* carryOut下载完成时回调方法
* */
export default {
name: "DownLoadButton",
props: {
/**
* 按钮宽度
*/
strokeWidth: {
type: Number,
default: 56
},
/**
* 完成文案
*/
succeedText: {//
type: String,
default: "完成"
},
/**
* 初始化文案
*/
initText: {//
type: String,
default: "下载"
},
/**
* 暂停时文案
*/
suspendText: {//
type: String,
default: "继续"
},
/**
* vuex plan 中的对象名
*/
vuexName:{
type: String,
},
/**
* 按钮浅色
*/
lightColor:{
type:String,
default:"#2BA3FF"
},
/**
* 按钮深色
*/
darkColor:{
type:String,
default:"#017BFF"
},
/**
* 按钮边框 单位PX
*/
borderpx:{
type:String,
default:"1px"
}
},
computed: {
...mapGetters({plan:'getPlan'}),
percentage() {
let p = 0
if(this.plan[this.vuexName]){
let item = this.plan[this.vuexName]
p = Number(item.haveDownloaded / item.filelength * 100)
}
return p.toFixed(2);
},
percentageVerify(){
return this.percentage==100 || this.percentage==0;
},
text(){
if(this.percentage==0){
return this.initText
}else if(this.percentage==100){
return this.succeedText
}else if(!this.plan[this.vuexName].state){
return this.suspendText
}
return this.percentage+'%'
}
},
watch: {
percentage(val) {
this.$refs.dow.style.setProperty('--position', val + '%');
if(this.percentageVerify){
this.$refs.dow.style.setProperty('--borderpx', 0 );
if(val==100 && this._events.carryOut){//下载完成时回调
this.$emit('carryOut')
}
}else{
this.$refs.dow.style.setProperty('--borderpx', this.borderpx );
}
}
},
mounted() {
this.$refs.dow.style.setProperty('--position', this.percentage + '%');
if(this.percentageVerify){
this.$refs.dow.style.setProperty('--borderpx', 0 );
}else{
this.$refs.dow.style.setProperty('--borderpx', this.borderpx );
}
this.$refs.dow.style.setProperty('--lightColor', this.lightColor );
this.$refs.dow.style.setProperty('--darkColor', this.darkColor );
},
methods:{
onclick(){
this.$emit("click");
}
}
}
</script>
<style scoped lang="scss">
@mixin span-font {
font-size: 32px;
font-weight: bold;
text-align: center;
width: 100%;
}
@mixin button {
width: 100%;
display: flex;
align-items: center;
}
.button {
@include button;
border: 2px solid #E5E4E9;
--color: #afdbff;
--position: 0%;
background-repeat: no-repeat;
background-size: 100%, var(--position);
background-image: radial-gradient(closest-side circle at 0, var(--color), var(--color) 100%, transparent),
linear-gradient(var(--color), var(--color));
span {
@include span-font;
color: $color-text;
}
}
.button-succeed {
--lightColor:#2BA3FF;
--darkColor:#017BFF;
--borderpx:1px;
@include button;
border: var(--borderpx) solid #E5E4E9;
background: linear-gradient(90deg, var(--lightColor), var(--darkColor));
span {
@include span-font;
color: $font-color-dark;
}
}
</style>
调用方式
<down-load-button @click="btnClick"
@carryOut="carryOut"
:vuexName="apkName"
:light-color="lightColor"
:dark-color="darkColor"
:init-text="btntext"
:succeed-text="btnsucceedtext"/>
vuex
state:{
plan: {},
},
getters:{
/**
* 下载进度
* @param state
*/
getPlan: state => {
return state.plan
},
},
mutations:{
setPlan(state, plan) {
state.plan = JSON.parse(plan);
},
/**
* 停止进度条
* @param state
*/
stopPlan(state) {
window.clearInterval(intervalID)
intervalID = undefined
},
},
actions:{
/* 开始获取进度
* @param commit
*/
actionPlan({
state,
commit
}) {
if (!intervalID) {
intervalID = setInterval(function () {
AppTool.getPlan().then(res => {
console.log("定时器")
commit("setPlan", res)
// console.log(state.plan)
})
}, 500)
}
},
}
最终实现效果:
宽高适应,不同状态时文字变化,按钮颜色外部传入,按钮渐变色,下载完成时会有回调
网友评论