最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Vue組件實現(xiàn)卡片動畫倒計時示例詳解

 更新時間:2022年07月25日 10:40:05   作者:紫衣小生  
這篇文章主要介紹了Vue組件實現(xiàn)卡片動畫倒計時示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

前言

最近有朋友在做投票的項目,里面有用到一個倒計時的組件,還想要個動畫效果。cv大法浸染多年的我,首先想到的是直接找個現(xiàn)有的組件。

通過一通搜索,看上的只有一個 vue2-flip-countdown,但是當(dāng)我要修改大小和顏色的時候發(fā)現(xiàn)改不了,從而直接把源碼拉到項目里面,改起來也挺麻煩。

而且,在搜索大法運(yùn)行幾個周天以后,其實心理已經(jīng)有了一個倒計時開發(fā)整體思路,便決定自己封裝一個倒計時出來,最終實現(xiàn)效果如下:

需求拆解

  • 開發(fā)一個開箱即用的組件,實現(xiàn)倒計時的效果,顯示模式為 01日01時01分01秒。
  • 以終止時間為入?yún)?,計算倒計時顯示的各個數(shù)據(jù)。
  • 方便的控制顯示的文案,以及主題顏色,大小。

組件設(shè)計思路

  • 組件分為兩個部分
    • animate-clock,控制組件數(shù)據(jù)結(jié)構(gòu),例如:自定義文案、將中文時間單位改成英文,是否換行等等
    • animate-card,動畫卡片,即組件里面的具體數(shù)字部分,并加上動畫。
  • clock 組件中,對傳入的 props 進(jìn)行處理,最核心的為 終止時間(terminalTime),根據(jù)終止時間計算天、時、分、秒。
  • 通過定時任務(wù),把計算出來的 天、時、分、秒 數(shù)據(jù)傳入 card 組件,觸發(fā)視圖更新。
  • card 組件中,當(dāng)數(shù)據(jù)發(fā)生改變的時候觸發(fā)動畫效果。
  • 【升級】在此基礎(chǔ)上進(jìn)行擴(kuò)展,變?yōu)橐粋€倒計時通用解決方案:
    • 反向倒計時
    • 只有數(shù)字的倒計時
    • 只有分、秒的倒計時
    • 中文、英文字符串倒計時
    • 動畫抽獎
    • 專注時間計時器
    • ...

具體開發(fā)

animate-clock.vue

首先設(shè)計視圖部分:

<template>
  <div class="animate-clock">
    <!-- <p>{{days}}{{hours}}{{minites}}{{seconds}}</p> -->
    <span>距離結(jié)束還剩</span>
    <animate-card :val="days" :size="16" :self-disabled="disabled" />
    <span>天</span>
    <animate-card :val="hours" :size="16" :self-disabled="disabled" />
    <span>時</span>
    <animate-card :val="minites" :size="16" :self-disabled="disabled" />
    <span>分</span>
    <animate-card :val="seconds" :size="16" :self-disabled="disabled" />
    <span>秒</span>
  </div>
</template>
<style lang="scss" scoped>
.animate-clock {
  width: 100%;
  text-align: center;
  font-size: 16px;
  font-weight: bold;
  padding: 40px 0 ;
}
</style>

很簡單的結(jié)構(gòu),現(xiàn)在版本為截圖所示的一行結(jié)構(gòu),可以看到,完全可以通過業(yè)務(wù)組件中通過傳入 props 的形式,修改每一個部分的文案,而且 樣式也可以隨時控制。

js 部分主要做這么幾件事:

  • 接收 props,并聲明 data
  • 聲明一個 工具函數(shù),用來 處理 小于 10 的數(shù)字,前面增加 0
  • 聲明主要業(yè)務(wù)函數(shù),被定時任務(wù)調(diào)用的更新數(shù)據(jù)方法
<script>
import animateCard from './animate-card.vue'
export default {
  components: { animateCard },
  props: {
    terminalTime: String,
  },
  data() {
    return {
      days: ['0', '0'],
      hours: ['0', '0'],
      minites: ['0', '0'],
      seconds: ['0', '0'],
      setIntVal: null,
      disabled: false,
    }
  },
  mounted() {
    // 先調(diào)用一次
    this.updateClock()
    // 箭頭函數(shù)不修改當(dāng)前作用域下的 this 指向
    this.setIntVal = setInterval(() => {
      this.updateClock()
    }, 1000)
  },
  methods: {
     /**
     * 更新計時器
     * @result void
     */
    updateClock() {
      let now = new Date().getTime()
      let stopTime = 0
      // 錯誤入?yún)?處理邏輯
      try {
        stopTime = new Date(this.terminalTime).getTime()
      } catch (err) {
        console.error(err)
        return false
      }
      // 終止邏輯
      const remainingTime = stopTime - now
      if (remainingTime < 1000) {
        clearInterval(this.setIntVal)
        this.setIntVal = null
        // 計時器 清零
        this.days = this.hours = this.minites = this.seconds = ['0', '0']
        this.disabled = true
        console.log('時間到!')
        return false
      }
      // 計算 日、時、分、秒
      let days = parseInt(remainingTime / (24 * 60 * 60 * 1000))
      let hours = parseInt(
        (remainingTime - 24 * 60 * 60 * 1000 * days) / (60 * 60 * 1000)
      )
      let minites = parseInt(
        (remainingTime - 24 * 60 * 60 * 1000 * days - 60 * 60 * 1000 * hours) /
          (60 * 1000)
      )
      let seconds = parseInt(
        (remainingTime -
          24 * 60 * 60 * 1000 * days -
          60 * 60 * 1000 * hours -
          60 * 1000 * minites) /
          1000
      )
      // 更新 data
      this.days = this.toStringAndUnshiftZero(days)
      this.hours = this.toStringAndUnshiftZero(hours)
      this.minites = this.toStringAndUnshiftZero(minites)
      this.seconds = this.toStringAndUnshiftZero(seconds)
    },
    /**
     * 轉(zhuǎn)化數(shù)字為數(shù)組,并在 頭部填充 0
     * @params num: numnber
     * @result string[]
     */
    toStringAndUnshiftZero(num) {
      const val = num.toString().split('')
      if (num < 10) {
        val.unshift('0')
      }
      return val
    },
  },
}
</script>

這一塊根本沒有什么技術(shù)含量,主要是異常數(shù)據(jù)的處理,和停止邏輯。 其實計時器清零理論上是不需要出現(xiàn)的,但是在測試過程中發(fā)現(xiàn),會出現(xiàn)最后一幀為 01 的情況,就直接清零了。

animate-card

這個組件一開始考慮的很復(fù)雜,想著監(jiān)聽數(shù)據(jù)的變化,觸發(fā)一個動畫的方法,然后這個方法支持重寫,提高組件的擴(kuò)展性,但是時間不允許,后面又覺得不太必要。

最后選擇的方案很簡單,卻提供了一個可以實現(xiàn) css 能實現(xiàn)的所有效果的思路。

主要思路是通過 vue 的 transition-group 機(jī)制,將 0-9 所有的卡片都渲染好,隱藏起來,通過 v-show 來觸發(fā)綁定在 transition-group 上的動畫效果,從而實現(xiàn)動態(tài)監(jiān)聽數(shù)據(jù)變化的效果。

需要注意的是因為宿主項目中 引入了 animate.css,所以就直接使用 animate 的動畫效果了。

有需要的,可以翻看文檔 【animate.css 官方文檔】進(jìn)行配置。

如果直接CV這套代碼的話,沒有動畫效果。

代碼如下:

<template>
  <div class="aimate-card">
    <div class="card-group" v-for="(item,idx) in val" :key="idx" :style="{'font-size': size+'px'}">
      <transition-group enter-active-class="animate__animated animate__bounceIn" leave-active-class="animate__animated animate__fadeOutDown">
        <div class="card-item" :class="{'disabled': selfDisabled}" v-for="num in 10" :key="num" v-show="item== num-1">{{num-1}}</div>
      </transition-group>
    </div>
  </div>
</template>
<script>
export default {
  props: {
    val: {
      type: Array,
      default: () => ['0', '0'],
    },
    size: {
      type: Number,
      default: 16,
    },
    selfDisabled: {
      type: Boolean,
      default: false,
    },
  },
  mounted() {
    console.log(this.selfDisabled)
  },
}
</script>
<style lang="scss" scoped>
.aimate-card {
  width: auto;
  display: inline-block;
  height: 100%;
  .card-group {
    display: inline-block;
    position: relative;
    width: 40px;
    padding: 5px;
    height: 100%;
    vertical-align: middle;
    .card-item {
      position: absolute;
      background: #3a7fe4;
      color: #fff;
      width: 30px;
      height: 40px;
      top: -20px;
      line-height: 40px;
    }
    .disabled {
      background: #ccc !important;
    }
  }
}
</style>

看完代碼以后很容易發(fā)現(xiàn),我設(shè)計的樣式其實一點都不好看,可以對 card-item 寫一些前端比較炫的效果。而且動畫效果也可以自定義。

項目中使用

粘貼上面兩個 vue 文件

在業(yè)務(wù)頁面中 引入并使用

使用方法如下:

<div class="vote-clock">
    <animate-clock :terminalTime="'2023-07-11 23:27:00'" />
</div>

CV大法只支持 terminalTime 這一個入?yún)ⅰ?/p>

后記

這個組件很簡單,但是也有很多可以琢磨的地方,更重要的是整理出一個開發(fā)通用組件的思路。

另外,這套代碼其實只是一個基礎(chǔ)結(jié)構(gòu),擴(kuò)展性還是很強(qiáng)的,尤其是前面設(shè)計思路中第5條中提到的其他功能,在此基礎(chǔ)上可以很快速的進(jìn)行開發(fā),感興趣的道友可以簡單琢磨一下。

大家在工作中不可避免的會遇到多種多樣的需要復(fù)用的代碼塊,有的道友會選擇提出為一個公共組件或者公共代碼塊,有的道友則選擇使用CV大法直接復(fù)用,也有的可能會另辟蹊徑在第一個場景的基礎(chǔ)上優(yōu)化為第二套代碼。

我以為這三種情況其實就是一個遞進(jìn)的關(guān)系,首先CV大法好,發(fā)功后發(fā)現(xiàn)場景不是完全一致,進(jìn)行些許優(yōu)化,進(jìn)而搞出一個兼容多個可能存在的場景的通用解決方案。

在設(shè)計一個組件的時候,需要盡可能的考慮多種場景,并考慮一下后續(xù)的升級方案。想兼容所有的場景肯定不可能,那么就要知道當(dāng)前組件的邊界在哪里。所以,在設(shè)計組件的時候不能只著眼于當(dāng)前業(yè)務(wù),更要考慮到其他場景。最簡單的例如:一個Button組件,除了保證全局的按鈕風(fēng)格一致的前提下,也要考慮到按鈕禁用狀態(tài),大按鈕,帶圖標(biāo)按鈕,按鈕組這些方面的東西。

以上就是我關(guān)于做這個小組件之后進(jìn)行的一些淺顯的思考,共勉之,更多關(guān)于Vue卡片動畫倒計時的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • vue 使用monaco實現(xiàn)代碼高亮

    vue 使用monaco實現(xiàn)代碼高亮

    這篇文章主要介紹了vue 使用monaco實現(xiàn)代碼高亮的方法,幫助大家更好的理解和學(xué)習(xí)使用vue框架,感興趣的朋友可以了解下
    2021-03-03
  • vue-editor-bridge報錯的解決方案

    vue-editor-bridge報錯的解決方案

    這篇文章主要介紹了vue-editor-bridge報錯的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • Vue3?基礎(chǔ)概念與環(huán)境搭建過程詳解

    Vue3?基礎(chǔ)概念與環(huán)境搭建過程詳解

    本文介紹了Vue3的基礎(chǔ)概念,包括響應(yīng)式系統(tǒng)、組合式API和更好的TypeScript支持,同時,文章手把手教你如何搭建Vue3開發(fā)環(huán)境,使用Vite創(chuàng)建項目,并解析了項目的結(jié)構(gòu),通過這些內(nèi)容,讀者可以快速上手Vue3,并為后續(xù)的學(xué)習(xí)打下堅實的基礎(chǔ),感興趣的朋友一起看看吧
    2025-02-02
  • vue使用axios跨域請求數(shù)據(jù)問題詳解

    vue使用axios跨域請求數(shù)據(jù)問題詳解

    這篇文章主要為大家詳細(xì)介紹了vue使用axios跨域請求數(shù)據(jù)的問題,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • vue?表格單選按鈕的實現(xiàn)方式

    vue?表格單選按鈕的實現(xiàn)方式

    這篇文章主要介紹了vue?表格單選按鈕的實現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • 在vue中使用Echarts利用watch做動態(tài)數(shù)據(jù)渲染操作

    在vue中使用Echarts利用watch做動態(tài)數(shù)據(jù)渲染操作

    這篇文章主要介紹了在vue中使用Echarts利用watch做動態(tài)數(shù)據(jù)渲染操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-07-07
  • vue.js+element-ui動態(tài)配置菜單的實例

    vue.js+element-ui動態(tài)配置菜單的實例

    今天小編就為大家分享一篇vue.js+element-ui動態(tài)配置菜單的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-09-09
  • Vue項目中引入ESLint校驗代碼避免代碼錯誤

    Vue項目中引入ESLint校驗代碼避免代碼錯誤

    這篇文章主要為大家介紹了Vue項目中引入ESLint插件校驗代碼避免代碼錯誤的使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • Vue watch響應(yīng)數(shù)據(jù)實現(xiàn)方法解析

    Vue watch響應(yīng)數(shù)據(jù)實現(xiàn)方法解析

    這篇文章主要介紹了Vue watch響應(yīng)數(shù)據(jù)實現(xiàn)方法解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-07-07
  • vue實現(xiàn)nav導(dǎo)航欄的方法

    vue實現(xiàn)nav導(dǎo)航欄的方法

    這篇文章主要為大家詳細(xì)介紹了vue項目nav導(dǎo)航欄的實現(xiàn)方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-12-12

最新評論

铜山县| 石嘴山市| 韶关市| 南康市| 安陆市| 馆陶县| 游戏| 秀山| 盘山县| 秀山| 竹溪县| 平安县| 桃园市| 凤台县| 如东县| 潼南县| 会昌县| 晋城| 东丽区| 苍南县| 霍林郭勒市| 耒阳市| 河东区| 青浦区| 临猗县| 双鸭山市| 博兴县| 隆回县| 班戈县| 青海省| 齐齐哈尔市| 徐闻县| 和平县| 高碑店市| 始兴县| 凤城市| 铜梁县| 平山县| 高邮市| 博客| 汤阴县|