小程序Progress组件介绍

官方文档

进度条。组件属性的长度单位默认为px,2.4.0起支持传入单位(rpx/px)。

属性

小程序所有可视的组件都可以绑定tap事件bindtap,即使没有在属性里面显示的标明。

小程序中Boolean属性如果为真则只需要写上属性名就好了,如果要设置成假,则需要写成属性名=“false”。

属性

类型

默认值

必填

说明

percent

number


百分比0~100

show-info

boolean

false


在进度条右侧显示百分比

border-radius

number/string

0


圆角大小

font-size

number/string

16


右侧百分比字体大小

stroke-width

number/string

6


进度条线的宽度(这是从进度条前进的方向上来看的,从表象上来看,其实就是组件的高度)

color

string

#09BB07


进度条颜色(请使用activeColor)

activeColor

string

#09BB07


已选择的进度条的颜色

backgroundColor

string

#EBEBEB


未选择的进度条的颜色

active

boolean

false


进度条从左往右的动画

active-mode

string

backwards


backwards: 动画从头播;forwards:动画从上次结束点接着播(实践中一般使用forwards)

duration

number

30


进度增加1%所需毫秒数

bindactiveend

eventhandle


动画完成事件

小程序颜色设计规范


小程序 progress固定显示的大小 微信小程序progress组件_进度条

  • #09BB07 是默认的activeColor颜色,是完成色。
  • #353535 也叫Semi,是大段说明文字且属于主要内容的,例如正文。
  • #888888 也叫Grey,用于次要内容。
  • #576b95 链接色。
  • #e64340 警告色。
  • 纯黑色Black一般用于主内容。
  • 浅黑色Light一般用于时间戳与表单缺省值。
  • backgroundColor默认的颜色值#EBEBEB。
  • 在Weui代码库中,默认按钮的底色是#F2F2F2。

常见问题

如何实现一个下载文件并显示动态进度条的功能?
  1. 启用Progress属性active和active-mode =“forwards”。
  2. 通过文件总大小和下载完成大小,可以实时计算出percent的数值。需要注意的是percent属性是动态绑定的,每次此数值变化后,我们需要显示使用setData触发视图更新。
Progress已产生的进度条如何设置圆角?
<progress border-radius="5" percent="20" show-info />

Progress组件的border-radius属性设置的是组件外部的圆角大小,它无法设置内部已经前进的进度条圆角。

直接改变小程序Progress组件的内部样式,进行覆盖。

当然此方法是野路子,如果有一天微信团队修改了此类名,也就不能用了。

.wx-progress-inner-bar {
    width:0;
    height: 100%;
}
.wx-progress-inner-bar {
    border-radius:5px;
}
已经加载完的进度条Progress,如何单击某个按钮让他重新加载呢?

有两种实现方法,但是原理都是延迟一部分操作到下一个时间片(渲染周期)再执行。

方法一,使用nextTick函数,或者在不支持nextTick的版本中使用setTimeout函数。

此处setTimeout时间设置为17ms,是由于一般手机屏幕的刷新频率是大于等于60赫兹,所以一秒60帧刷新能保证一个比较流畅的视觉效果,1000/60 = 16.6666 ms。

方法二,调用两次setData,因为每次setData在底层都需要调用evaluateJavascript这个底层函数,这个函数它用于小程序的逻辑层与视图层之间的通讯。他的执行本身就需要时间。

具体代码如下:

<view class="gap">已经加载完的进度条Progress,如何单击某个按钮让他重新加载呢?</view>
<button bindtap="resetProgress">重置</button>
<button bindtap="resetProgressYet">重置YET</button>
<progress border-radius="5" active-mode="forwards" active  show-info percent="{{percentValue}}"></progress>
Page({

    /**
     * 页面的初始数据
     */
    data: {
        percentValue: 20,
    },
    resetProgress() {
        this.setData({
            percentValue: 0
        });
        if (wx.canIUse('nextTick')) {
            wx.nextTick(() => {
                this.setData({
                    percentValue: 100
                });
            });
        } else {
            setTimeout(() => {
                this.setData({
                    percentValue: 0
                });
            }, 17)
        }
    },
    resetProgressYet(){
        this.setData({
            percentValue: 0
        });
        this.setData({
            percentValue: 100
        });
    },
})
能否设计一个环形进度条?

使用Canvas创建自定义组件:原理是这样的,用css设计两个圆,一个灰色的大部外圆,和一个白色的内部小圆,然后根据percent值的变化,控制canvas进行已完成进度的绘制。

  1. 在自定义组件中使用wx.createCanvasContent创建画布的上下文绘制对象时,需要在第二个参数处传递this对象。这样才是在组件中查找画布。不然就会变成了在引用它的页面中查找。
  2. 使用wx.createSelectorQuery创建对象的select方法,以ID查找组件对象时,如果在自定义组件中,必须在查找前先调用一下他的in方法,把this对象传递进去,不然组件是查找不到的。默认组件查询也只是在主页面查找,不会去查引用组件中的子组件。

具体代码如下:

  1. 组件代码
// progress/circle-progress/index.js
Component({
    runTimeid: 0,
    behaviors: [],
    /**
     * 组件的属性列表
     */
    properties: {
        percent: {
            type: Number,
            value: 50,
            observer: function (newVal, oldVal) {
                this.draw(newVal);
            }
        }
    },

    /**
     * 组件的初始数据,属于私有数据,可用于模板渲染
     */
    data: {
        //百分比
        percentage: '',
        //动画执行时间
        animTime: ''
    },
    ready() {
        if (this.data.percent) this.draw(this.data.percent);
    },
    /**
     * 组件的方法列表
     */
    methods: {
        // 绘制圆形进度条方法
        run(c,w,h){
            let that = this;
            var num = (2 * Math.PI / 100 * c) - 0.5 * Math.PI;
            that.ctx2.arc(w, h, w - 8, -0.5 * Math.PI, num);
            that.ctx2.setStrokeStyle('#09bb07');//绿色
            that.ctx2.setLineWidth('16');
            that.ctx2.setLineCap('butt');
            that.ctx2.stroke();

            that.ctx2.beginPath();
            that.ctx2.setFontSize(40);//设置字体大小,不能加引号
            that.ctx2.setFillStyle('#b2b2b2');//灰色字体
            that.ctx2.setTextAlign('center');
            that.ctx2.setTextBaseline('middle');
            that.ctx2.fillText(c+' %',w,h);
            that.ctx2.draw();
        },
        // 实现动画效果
        canvasTap(start,end,time,w,h){
            let that = this;
            start++;
            if(start>end){
                return false;
            }
            that.run(start,w,h);
            that.runTimerid=setTimeout(function(){
                that.canvasTap(start,end,time,w,h);
            },time);
        },
        draw(percent) {
           const id = 'runCanvas';
           const animTime = 500;
           if(percent>100)return
           if(!this.ctx2){
               const ctx2=wx.createCanvasContext(id, this)
               this.ctx2 = ctx2
           }
           let oldPercentValue = this.data.percentage;
           this.setData({
               percentage:percent,
               animTime:animTime
           });
           var time = this.data.animTime/(this.data.percentage-oldPercentValue);
           const query = wx.createSelectorQuery().in(this)
           query.select('#'+id).boundingClientRect((res)=>{
               var w = parseInt(res.width/2);
               var h = parseInt(res.height/2);
               if(this.runTimeid) clearTimeout(this.runTimeid)
               this.canvasTap(oldPercentValue,percent,time,w,h)
           }).exec()
        }
    }
})
<!--  progress/circle-progress/index.wxml -->
<view class="canvasBox">
    <!-- 外部灰色的圆  -->
    <view class="bigCircle"></view>
    <!-- 内部白色的圆 -->
    <view class="littleCircle"></view>
    <canvas canvas-id="runCanvas" id="runCanvas" class="canvas"></canvas>
</view>
/* progress/circle-progress/index.wxss */
.canvasBox {
    height: 500rpx;
    position: relative;
    background-color: white;
}

.bigCircle {
    width: 420rpx;
    height: 420rpx;
    border-radius: 50%;
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    margin: auto auto;
    background-color: #f2f2f2;
}

.littleCircle {
    width: 350rpx;
    height: 350rpx;
    border-radius: 50%;
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    margin: auto auto;
    background-color: white;
}

.canvas {
    width: 420rpx;
    height: 420rpx;
    border-radius: 50%;
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    margin: auto auto;
    z-index: 99;
}
  1. 页面使用代码

引用组件申明

{
  "usingComponents": {
    "circle-progress": "./circle-progres/index"
  }
}

具体使用

<view class="gap">能否设计一个环形进度条?</view>
<circle-progress id="progress1" percent="{{percentValue}}" />
<button bindtap="drawProgress">绘制</button>
// progress/progress.js
Page({

    /**
     * 页面的初始数据
     */
    data: {
        percentValue: 20,
    },
    drawProgress(){
        if(this.data.percentValue>=100){
            this.setData({percentValue:0})
        }
        this.setData({percentValue:this.data.percentValue+10})
    }
})
Progress组件进度的百分比数字怎么设置?

有两种方法:

第一种,直接覆盖组件内部的样式,这属于全局改变。

<view class="gap">Progress组件进度的百分比数字怎么设置?</view>
<progress percent="40" stroke-width="5" show-info />
.wx-progress-info{
    color:red;
}

第二种,使用内联样式。

<view class="gap">Progress组件进度的百分比数字怎么设置?</view>
<progress percent="40" stroke-width="5" show-info style="color:red"/>
Progress组件右侧的百分比文字,与左边离得太近了,可否增加一个边距?

直接覆盖组件内部的样式。

<view class="gap">Progress组件右侧的百分比文字,与左边离得太近了,可否增加一个边距?</view>
<progress percent="40" stroke-width="5" show-info />
.wx-progress-info{
    margin-left: 5px;
}