原创

【vue3】 封装一个count-to计数器组件

本文目的:练习在vue中,基于第三方CountUp.js,封装一个计数器组件

countUp.js简介

countUp.js是一个由js实现的拥有渐变效果的计数器

countUp.js地址 http://inorganik.github.io/countUp.js/

countUp.js各参数含义如下:

属性含义参数类型
start初始值number
end结束值number
decimal places小数点后保留位数number
duration渐变时长number
use easing是否使用变速效果boolean
use grouping是否分组显示boolean
separator分组分分隔符string
decimal小数点符号string
prefix显示前缀string
suffix显示后缀string

组件化封装

好了开始封装,步骤如下:

第一步 引入依赖

引入countup.js

package-lock.json

    "countup": {
      "version": "1.8.2",
      "resolved": "https://registry.npmjs.org/countup/-/countup-1.8.2.tgz",
      "integrity": "sha1-AhzMam+WRUDGsn7WRoGvJ/tV8BA="
    }

package.json

  "dependencies": {
    "core-js": "^3.4.3",
    "countup": "^1.8.2",
    "element-ui": "^2.13.0",
    "vue": "^2.6.10",
    "vue-router": "^3.1.3",
    "vuex": "^3.1.2"
  }

第二步 组件封装

count-to.vue 封装组件文件

<template>
    <div>
        <slot name="left"></slot>
        <span ref="number" :id="countId" :class="getClass"></span>
        <slot name="right"></slot>
    </div>
</template>
<script>
    import CountUp from "countup";
    export default {
        name: "CountTo",
        computed: {
            countId() {
                return `count_up_${this.uid}`;
            },
            getClass() {
                return this.className
            }
        },
        data() {
            return {
                counter: {}
            };
        },
        props: {
            /**
             * @description 起始值
             */
            startVal: {
                type: Number,
                default: 0
            },
            /**
             * @description 起始值
             */
            endVal: {
                type: Number,
                required: true
            },
            /**
             * @description 小数点后保留位数
             */
            decimals: {
                type: Number,
                default: 0
            },
            /**
             * @description 动画延迟开始时间
             */
            delay: {
                type: Number,
                default: 0
            },
            /**
             * @description 渐变时长
             */
            duration: {
                type: Number,
                default: 1
            },
            /**
             * @description 是否使用变速效果
             */
            useEasing: {
                type: Boolean,
                default: false
            },
            /**
             * @description 是否分组显示
             */
            useGroup: {
                type: Boolean,
                default: true
            },
            /**
             * @description 分组显示的分隔符
             */
            separator: {
                type: String,
                default: ","
            },
            /**
             * @description 整数部分和小数的分隔符
             */
            decimal: {
                type: String,
                default: "."
            },
            className: {
                type: String,
                default: ''
            }
        },
        methods: {
            getCount() {
                return this.$refs.number.innerHTML
            }
        },
        watch: {
            /**
             * @description 监控endVal值变化,调用update方法
             */
            endVal(newVal, oldVal) {
                this.counter.update(newVal)
            }
        },
        mounted() {
            /**
             * @description 基于上述参数,初始化一个counter实例
             */
            this.$nextTick(() => {
                this.counter = new CountUp(this.countId, this.startVal, this.endVal, this.decimals, this
                    .duration, {
                        useEasing: this.useEasing,
                        useGroup: this.useGroup,
                        separator: this.separator,
                        decimal: this.decimal
                    })
                setTimeout(() => {
                    this.counter.start()

                }, this.delay)
            })
        }
    };
</script>

index.js

import CountTo from "./count-to.vue"
export default CountTo

第三步演示

新建countToDemo.vue用于演示,内容如下:

<template>
    <div class="count_class">
        <count-to ref="countTo" :end-val="endVal" :className="getClass">
            <span slot="left" class="prefix-style">总金额: </span>
            <span slot="right"> 元</span>
        </count-to>
        <br>
        <el-button type="primary" round @click="getNumber">获取数值</el-button>
        <el-button type="primary" round @click="updateVal">更新值</el-button>
    </div>
</template>
<script>
    import CountTo from '@/components/count-to'
    export default {
        name: "count_to",
        components: {
            CountTo
        },
        data() {
            return {
                endVal: 1000
            }
        },
        computed: {
            // 返回自定义样式
            getClass() {
                return ['count-to-number']
            }
        },
        methods: {
            getNumber() {
                let number = this.$refs.countTo.getCount();
                this.$message({
                    message: '当前数值为:' + number,
                    type: 'success'
                });
                console.log(number);
            },
            updateVal() {
                this.endVal += Math.random() * 100
            }

        }
    }
</script>
<style>
    .count_class {
        margin-top: 50px;
    }

    .count-to-number {
        font-size: 8em;
        color: #4d63bc;
        font-weight: 300;
    }

    .prefix-style {
        font-size: 2em;
    }
</style>

修改路由,添加如下内容

  {
    path: '/count',
    name: 'count',
    component: () => import('../views/countToDemo')
  }

demo目录如下:

npm run serve 启动项目

原创
vue

评论