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

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

countUp.js简介

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

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

image

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目录如下:

image
image

npm run serve 启动项目

image

!

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容