vue 封装滚动数字组件

7 篇文章 0 订阅
2 篇文章 0 订阅

该组件包含正整数及浮点型小数

父组件引用

<roll-number :font-size="16" :num="num"></roll-number>
<script>
 setInterval(() => {
    this.num = Math.random() * (10000 + 1);
 }, 3000);
</script>

rollNumber.vue 数字滚动组件

html

<template>
    <div class="container" :style="parentStyle">
        <span
            v-for="(item, index) in numAry"
            :key="index"
            class="container-number-roll"
            :data-content="getBeforeContent(item).content"
            :style="styles[index]"
            ref="num"
            >0</span
        >
    </div>
</template>

js

<script>
export default {
    name: "rollNumber",
    props: {
        fontSize: {
            type: Number,
            default: 18
        },
        color: {
            type: String,
            default: "#333"
        },
        num: {
            type: [Number, String],
            default: 0
        }
    },
    data() {
        return {
            styles: {}
        };
    },
    watch: {
        num() {
            this.numChange();
        },
        color() {
            this.extraStyles({
                "--color": this.color
            });
        }
    },
    computed: {
        numAry() {
            return this.num.toString().split("");
        },
        parentStyle() {
            return {
                fontSize: this.fontSize + "px",
                height: this.fontSize + "px"
            };
        }
    },
    mounted() {
        this.numChange();

        this.color != "#333" &&
            this.extraStyles({
                "--color": this.color
            });
    },
    methods: {
        getBeforeContent(item) {
            let res = isNaN(parseInt(item)) ? "." : "0123456789";
            return {
                isNaN: isNaN(parseInt(item)),
                content: res
            };
        },
        extraStyles(obj = {}) {
            this.numAry.map((item, index) => {
                Object.assign(this.styles[index], obj);
            });
            this.$forceUpdate();
        },
        setStyles(obj = {}) {
            let defaultStyle = {
                fontSize: this.fontSize + "px",
                height: this.fontSize + "px",
                width: 0.7 * this.fontSize + "px"
            };
            Object.assign(defaultStyle, obj);
            return defaultStyle;
        },
        numChange() {
            this.numAry.map((item, index) => {
                let top = 0,
                    style = {};
                if (this.getBeforeContent(item).isNaN) {
                    top = this.fontSize * 0.2;
                    style.width = 0.2 * this.fontSize + "px";
                } else {
                    top = -parseInt(item) * this.fontSize;
                }
                Object.assign(style, {
                    "--local": `translate(0, ${top}px)`
                });
                this.styles[index] = this.setStyles(style);
            });
            this.$forceUpdate();
        }
    }
};
</script>

css

<style lang="scss" scoped>
.container {
    overflow: hidden !important;
}
.container-number-roll {
    --local: translate(0, -0px);
    --color: #333;
    position: relative;
    /* 文字竖显示 */
    writing-mode: vertical-rl;
    text-orientation: upright;
    color: rgba(255, 255, 255, 0);
    &::before {
        width: 100%;
        content: attr(data-content);
        position: absolute;
        color: var(--color);
        font-weight: bold;
        /* 文字竖显示 */
        writing-mode: vertical-rl;
        text-orientation: upright;
        // animation: loca1 1s ease-in-out forwards;
        transform: var(--local);
        transition: transform 1s ease-in-out;
        display: flex;
        justify-content: center;
        align-items: center;
    }
}
</style>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,下面是一个基本的弹窗组件封装代码。代码中使用的是Element UI库中的Dialog组件,你可以根据自己的需求进行修改和定制。 ``` <template> <el-dialog :title="title" :visible.sync="visible" :modal="modal" :width="width" :fullscreen="fullscreen" :lock-scroll="lockScroll" :custom-class="customClass" :show-close="showClose" :before-close="beforeClose" > <slot></slot> </el-dialog> </template> <script> export default { name: 'MyDialog', props: { title: { // 弹窗标题 type: String, default: '' }, visible: { // 是否显示弹窗 type: Boolean, default: false }, modal: { // 是否为模态弹窗 type: Boolean, default: true }, width: { // 弹窗宽度 type: String, default: '50%' }, fullscreen: { // 是否全屏显示 type: Boolean, default: false }, lockScroll: { // 是否锁定滚动条 type: Boolean, default: true }, customClass: { // 自定义类名 type: String, default: '' }, showClose: { // 是否显示关闭按钮 type: Boolean, default: true }, beforeClose: { // 关闭前的回调函数 type: Function, default: () => {} } } } </script> ``` 这是一个非常基础的弹窗组件,你可以根据自己的需求进行扩展和修改。在使用时,你需要在父组件中引入该组件,并使用v-model绑定visible属性来控制弹窗的显示和隐藏状态。 ``` <template> <div> <el-button @click="visible = true">打开弹窗</el-button> <my-dialog v-model="visible" title="弹窗标题"> <p>这是弹窗内容</p> </my-dialog> </div> </template> <script> import MyDialog from './MyDialog.vue' export default { components: { MyDialog }, data() { return { visible: false } } } </script> ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yww_yang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值