美文网首页
手写一个NoticeBar 通知栏组件

手写一个NoticeBar 通知栏组件

作者: 德日班勒 | 来源:发表于2019-12-02 10:06 被阅读0次

我们无论是移动端还是PC端都会遇到像滚动新闻的展示方式


演示.gif

自己做了一个组件,方便以后调用
下面是组件内部代码:

<template>
  <transition name="fade">
    <!--主要内容-->
    <div class="noticebar" :style="{backgroundColor:data.backround}">
      <div style="margin-left:5px"></div>
      <img v-if="data.icon" :style="{height:data.iconSize?data.iconSize:'16px',width:data.iconSize?data.iconSize:'16px'}" :src=data.icon alt="">
      <div style="margin-right:5px"></div>
      <div ref="back" class="back">
        <span ref="text" :style="{fontSize:data.size?data.size:'16px',color:data.color?data.color:'#f60'}" class="text">{{ data.text?data.text:'通知内容' }}</span>
      </div>
    </div>
  </transition>
</template>
<script>
export default {
    props: {
        options: {
            type: Object,
            default() {
                return {
                    text: '默认'
                };
            }
        }
    },
    data() {
        return {
            speed: this.options.speed, // 速度(单位px/s)
            backWidth: '', // 父级宽度
            backHeight: '', // 父级高度
            wordLength: '', // 文本长度
            state: 1,
            firstAnimationTime: '', // 状态一动画效果
            secondAnimationTime: '', // 状态二动画效果
            data: this.options
        };
    },
    methods: {
        // 获取数据
        getData() {
            let style = document.styleSheets[0];
            let text = this.$refs.text;
            let back = this.$refs.back;
            this.backWidth = back.offsetWidth;
            this.backHeight = back.offsetHeight;
            text.style.lineHeight = this.backHeight + 'px';
            this.wordLength = text.offsetWidth;
            this.ComputationTime(); // 计算时间
            style.insertRule(
                `@keyframes firstAnimation {0%   {left:0px;}100%  {left:-${this.wordLength}px;}}`
            );
            style.insertRule(
                `@keyframes secondAnimation {0%   {left:${this.backWidth}px;}100%  {left:-${this.wordLength}px;}}`
            );
            setTimeout(res => {
                this.changeState();
            }, this.data.delay);
        },
        // 用速度计算时间(想要保持速度一样,2种状态时间不同需算出)
        ComputationTime() {
            this.firstAnimationTime = this.wordLength / this.speed;
            this.secondAnimationTime =
                (this.wordLength + this.backWidth) / this.speed;
        },
        // 根据状态切换动画
        changeState() {
            let text = this.$refs.text;
            if (this.state == 1) {
                text.style.animation = `firstAnimation ${this.firstAnimationTime}s linear`;
                this.state = 2;
            } else {
                text.style.animation = `secondAnimation ${this.secondAnimationTime}s linear infinite`;
            }
        },
        Listener() {
            let text = this.$refs.text;
            console.log(text);
            text.addEventListener(
                'animationend',
                res => {
                    this.changeState();
                },
                false
            );
        }
    },
    mounted() {
        this.Listener();
        setTimeout(res => {
            this.getData();
        }, 100);
    }
};
</script>
<style lang="less" scoped>
.noticebar {
    display: flex;
    align-items: center;
    height: 100%;
    width: 100%;
    background-color: #fff7cc;
    .icon {
        img {
            height: 100%;
            width: 100%;
        }
    }
    .back {
        overflow: hidden;
        white-space: nowrap;
        margin: 0 auto;
        height: 100%;
        width: 100%;
        position: relative;
        .text {
            position: absolute;
            display: inline-block;
            padding: 2px 0;
        }
    }
}
</style>

父组件调用:

<template>
  <transition name="fade">
    <div class="wrap">
      <div class="father">
        <noticebar :options=options></noticebar>
      </div>
    </div>
  </transition>
</template>
<script>
import noticebar from './noticebar';
export default {
    components: {
        noticebar
    },
    data() {
        return {
            // noticebar 组件的配置项
            options: {
                text:'日本网友momopoi家的柯基,表情管理经常崩坏,可以说是喜怒形于色的典范', // 通知内容
                icon:'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=236296424,1105446647&fm=26&gp=0.jpg', // 左侧图标(不需要icon不传)
                iconSize: '16px', // icon大小(正方形默认16px)
                size: '16px', // 通知内容文字大小(默认16px)
                color: '#1989fa', // 通知内容文字颜色(默认#f60)
                backround: '#fff7cc', //背景颜色(默认#fff7cc)
                delay: '1000', // 动画延迟时间(默认一秒后开始滚动,单位毫秒)
                speed: '50' // 滚动速率默认50 (px/s)
            }
        };
    }
};
</script>
<style lang="less" scoped>
.wrap {
    .father {
        margin: 150px auto;
        height: 60px;
        width: 100%;
        img {
            height: 100%;
            width: 20px;
        }
    }
}
</style>

目前可供的配置项在option中,以后有什么好的建议请在评论留言,我会关注并且经常更新这个组件。

相关文章

  • 手写一个NoticeBar 通知栏组件

    我们无论是移动端还是PC端都会遇到像滚动新闻的展示方式 自己做了一个组件,方便以后调用下面是组件内部代码: 父组件...

  • web端 系统通知设计 Part 1

    写在前面: 关于通知的设计在现阶段的形式有很多,例如Toast,Modal,Noticebar等等以及每种通知形式...

  • 建立生活秩序 part2 设计自己的手机布局

    巧用小组件功能 将一些常用的小组件放到通知栏里,只需要把通知栏拉到最下面,点击编辑小组件功能即可。 比如我常用的就...

  • react 路由传参 高阶组件

    路由 手写路由 控制地址栏 歌手 根据改变渲染不同的组件

  • 天气王v9.1开发总结

    天气王v9.1负责小组件,通知栏技术优化,共有以下收获: 1、提升进程优先级 2、通知栏UI适配 3、Pendin...

  • Android 8.0+ 通知栏适配

    对于通知栏,大家都不陌生,应该算是设备的基础功能组件了吧,像推送消息,任务提醒,闹钟提示等等都需要借助设备的通知栏...

  • Android 8.0+ 通知栏适配

    对于通知栏,大家都不陌生,应该算是设备的基础功能组件了吧,像推送消息,任务提醒,闹钟提示等等都需要借助设备的通知栏...

  • Android 8.0+(一) 通知栏适配

    对于通知栏,大家都不陌生,应该算是设备的基础功能组件了吧,像推送消息,任务提醒,闹钟提示等等都需要借助设备的通知栏...

  • 安卓组件之通知栏

    通知是安卓中比较常见的一种展示后台发生的消息的方式,使用 NotificationManager 发送一个 Not...

  • react-native-snap-carousel 使用

    开发中我们经常用到通知栏, react-native-snap-carousel 这个组件很强大 ,下面介绍下...

网友评论

      本文标题:手写一个NoticeBar 通知栏组件

      本文链接:https://www.haomeiwen.com/subject/ejdxgctx.html