Vue3+Ts实现缓存功能的示例代码

 更新时间:2024年03月08日 11:09:11   作者:大阳光男孩  
这篇文章主要为大家详细介绍了Vue3+Ts如何实现缓存,用户搜索词本地排名,延迟消费或者消息队列,用户签到和锁,以及接口限流,还有全局ID等功能,需要的可以参考下

帮助类具体代码

import { onMounted, ref } from "vue";
import emitter from '@/utils/mitt'
 
interface Prop {
    exp: number;
    key: string;
    data: any;
    tag?: any;
}
 
 
 
export default function(){
 
    // 缓存的仓库
    let cacheStore  = ref( {} as Map< string, Prop >);
 
    // 用于本地排名
    let ranking = ref( {} as Map< string, any[] > );
 
    // 延迟队列
    let delayMsg = ref( {} as Map< string, any[] > );
 
    // 用户签到打卡
    let sign = ref( {} as Map< string, any[] > );
 
    // 限流
    let limiting = ref( {} as Map< string, number> );
 
 
    function limit( key : string ) {
        if (limiting.value.has(key)) {
            let temp = limiting.value.get(key) as number;
            limiting.value.set(key,temp + 1);
        }else {
            limiting.value.set(key,1);
        }
    }
 
    function takeLimit( key : string ) : number {
        return limiting.value.get(key) as number;
    }
 
    function delLimit( key : string ) {
        limiting.value.delete(key);
    }
 
    // 放入打卡的数据
    function punchSetting( key : string , signInData : number[]) {
        sign.value.set(key,signInData);
    }
 
 
    // 打卡
    function startSign( key : string ,  day : number ): boolean {
        let signInData = sign.value.get(key) as any[];
        if (signInData) {
            signInData.splice(day - 1,1,1);
            return true;
        }
        return false;
    }
 
    // 返回连续打卡的天数
    function continuousClocking( key : string ) : number {
       if(sign.value.size > 0) {
           let signInData = sign.value.get(key) as any[];
           if (signInData) {
               let day = 1;
               let continuous : any[] = [];
               signInData.forEach( (value, index) => {
                   if(signInData[index] === signInData[index+1] && value ==1) {
                       day++;
                   }else {
                       continuous.push(day);
                       day = 1;
                   }
               });
               return Math.max.apply(null,continuous);
           }
       }
       return 0;
    }
 
    function putDelayMsg( prop : Prop ) {
        prop.tag = getUUID();
        if (delayMsg.value.has(prop.key)) {
           let delayMsgs = delayMsg.value.get(prop.key) as any[];
           delayMsgs.push(prop);
           delayMsg.value.set(prop.key,delayMsgs);
        }else {
            let temp = [];
            temp.push(prop);
            delayMsg.value.set(prop.key,temp);
        }
    }
 
    onMounted(() => {
       cacheStore.value = new Map();
       ranking.value = new Map();
       delayMsg.value = new Map();
       sign.value = new Map();
       // 轮询清除过期的缓存
       setInterval(() => {
            if(cacheStore.value.size > 0) {
                Array.from(cacheStore.value.keys()).forEach( key => {
                    let data = cacheStore.value.get(key);
                    if (data) {
                        let nowDate = new Date().valueOf();
                        if (data.exp < nowDate && data.exp != -1) {
                            cacheStore.value.delete(key);
                        }
                    }
                });
            }
       },100);
        // 发送过期消息让Mitt进行通知 emitter.on('xxx', e => {  console.log(e) } )
        setInterval(() => {
            if(delayMsg.value.size > 0) {
                Array.from(delayMsg.value.keys()).forEach( key => {
                    let temp = delayMsg.value.get(key) as any[];
                    temp.forEach( item => {
                        let nowDate = new Date().valueOf();
                        if( item.exp < nowDate - 100 ) {
                            emitter.emit(item.key, item.data);
                            temp = temp.filter( dispose  => dispose .tag != item.tag);
                            delayMsg.value.set(item.key,temp);
                        }
                    });
                })
            }
        },100);
    });
 
 
    function putRanking( key : string , data : any) {
        if(ranking.value.has(key)) {
           let rank  = ranking.value.get(key) as any[];
           let temp = rank.find(item => item.data === data);
           if(temp) {
               let newVal =  rank.filter(item => item.data !== data );
               newVal.push({ data: data.toString() , score : temp.score + 1 });
               ranking.value.set(key,newVal);
           }else {
               rank.push({ data: data.toString() , score : 1 });
               ranking.value.set(key,rank);
           }
        }else {
           let temp = [] as any[];
           temp.push({ data: data.toString() , score: 1 });
           ranking.value.set(key,temp);
        }
    }
 
    function takeRanking( key : string , total : number , desc : boolean): any[] {
        let rank = ranking.value.get(key) as any[];
        if(desc) {
            rank.sort( ( a , b ) => b.score - a.score );
        }else {
            rank.sort( ( a , b ) => a.score - b.score );
        }
        return rank.slice(0, total != 1 ? total - 1 : total);
    }
 
    // 放入缓存
    function putCache( prop : Prop ) {
        cacheStore.value.set(prop.key,prop);
    }
 
 
    // 获取缓存
    function takeCache<T>( key : string ) : any {
        return cacheStore.value.get(key) as T;
    }
 
    // 加锁
    function lock( prop : Prop ) : boolean {
        if (getLock(prop.key)) {
            return false;
        }
        cacheStore.value.set(prop.key,prop);
        return true;
    }
 
 
    // 获取锁
    function getLock( key : string ) : boolean {
        return cacheStore.value.has(key);
    }
 
    // 解锁
    function unLock( key : string , id : any) {
        let lock = cacheStore.value.get(key);
        if( lock ) {
            if( lock.data == id ) {
                cacheStore.value.delete(key);
            }
        }
    }
 
 
    // 全局id
    function getUUID () {
        return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
            const r = Math.random() * 16 | 0
            const v = c === 'x' ? r : (r & 0x3 | 0x8)
            return v.toString(16)
        });
    }
 
    return { takeCache , putCache , unLock , lock , getLock , putRanking , takeRanking , getUUID , putDelayMsg , startSign , punchSetting , continuousClocking }
}

使用代码

<template>
  <div style="display: flex;justify-content: center;align-items: center;height: 120px;gap: 12px">
    <button @click="getCache">获取缓存</button>
    <button @click="getSearch">获取前三搜索</button>
    <button @click="makeOrder">生成订单</button>
    <button @click="initSign">初始打卡数据</button>
    <button @click="simulationSign">模拟打卡</button>
    <button>获取练习打卡{{continuousClocking('3')}}</button>
  </div>
</template>
 
<style scoped>
    @import 'animate.css';
    .ske {
      display: flex;
      justify-content: center;
      align-items: center;
      animation: hinge;
      animation-duration: 3s;
    }
</style>
 
<script setup lang="ts">
 
 
    import { onMounted } from 'vue';
 
    import emitter from '@/utils/mitt'
 
    import CacheHelp from '@/hooks/CacheHelp'
 
    const { putCache , takeCache , putRanking , takeRanking ,  putDelayMsg , punchSetting , continuousClocking , startSign } = CacheHelp();
 
    onMounted(() => {
      putCache({ key: 'UserInfo' , data : { name: 'Jack' , age : 12 } , exp: new Date().valueOf() + 3000 });
      putRanking("word","成都");
      putRanking("word","北京");
      putRanking("word","成都");
      putRanking("word","重庆");
      putRanking("word","武汉");
      putRanking("word","北京");
      putRanking("word","成都");
      putRanking("word","上海");
    });
 
    function simulationSign() {
      startSign('3',2);
      startSign('3',3);
      startSign('3',4);
      startSign('3',12);
      startSign('3',13);
      startSign('3',14);
      startSign('3',15);
      startSign('3',16);
      startSign('3',18);
      startSign('3',31);
    }
 
 
 
    function getCache() {
      console.log(`获取的缓存:${JSON.stringify(takeCache("UserInfo"))}`);
    }
 
    function getMonthDays( year : number, month : number ) : number {
      let days = [31,28,31,30,31,30,31,31,30,31,30,31]
      if ( ( year % 4 === 0 ) && ( year % 100 !== 0 || year % 400 === 0) ) {
        days[1] = 29
      }
      return days[month - 1];
    }
 
    function initSign() {
      let signData = []
      for (let i = 0; i < getMonthDays(2024,3); i++) {
        signData.push(0);
      }
      punchSetting('3',signData);
    }
 
    function getSearch() {
      console.log(`排名考前的缓存:${JSON.stringify(takeRanking('word',3,true))}`);
    }
 
    function makeOrder() {
        console.log(`发送的时间:${new Date().toLocaleTimeString()}`);
        putDelayMsg({ key: 'orderDelay' , data: { price :12.9 , id : 1 , name : '大衣' } , exp : new Date().valueOf() + 10000 });
        putDelayMsg({ key: 'orderDelay' , data: { price :15.9 , id : 2 , name : '短袖' } , exp : new Date().valueOf() + 10000 });
    }
 
    emitter.on("orderDelay",e => {
      console.log(`收到延迟消息:${JSON.stringify(e)}\t接收时间:${new Date().toLocaleTimeString()}`)
    })
 
 
 
</script>

效果

到此这篇关于Vue3+Ts实现缓存功能的示例代码的文章就介绍到这了,更多相关Vue3 Ts缓存内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • vue中三种调用接口的方法

    vue中三种调用接口的方法

    这篇文章主要介绍了vue中三种调用接口的方法,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-08-08
  • 详解vue如何给特殊字段设置插槽

    详解vue如何给特殊字段设置插槽

    这篇文章主要为大家详细介绍了vue如何实现给特殊字段设置插槽,文中的示例代码讲解详细,具有一定的借鉴价值,有需要的小伙伴可以学习一下
    2023-09-09
  • vue踩坑记录:属性报undefined错误问题

    vue踩坑记录:属性报undefined错误问题

    这篇文章主要介绍了vue踩坑记录:属性报undefined错误问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-04-04
  • OpenDataV低代码平台新增组件流程详解

    OpenDataV低代码平台新增组件流程详解

    这篇文章主要为大家介绍了OpenDataV低代码平台新增组件流程详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09
  • vue3.0中setup中异步转同步的实现

    vue3.0中setup中异步转同步的实现

    这篇文章主要介绍了vue3.0中setup中异步转同步的实现方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-06-06
  • vue-router 4使用实例详解

    vue-router 4使用实例详解

    虽然 vue-router 4 大多数 API 保持不变,但是在 vue3 中以插件形式存在,所以在使用时有一定的变化。接下来就学习学习它是如何使用的
    2021-11-11
  • vue项目打包为APP,静态资源正常显示,但API请求不到数据的操作

    vue项目打包为APP,静态资源正常显示,但API请求不到数据的操作

    这篇文章主要介绍了vue项目打包为APP,静态资源正常显示,但API请求不到数据的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-09-09
  • 使用element-ui实现行合并过程

    使用element-ui实现行合并过程

    这篇文章主要介绍了使用element-ui实现行合并过程,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-08-08
  • vue项目中怎样嵌入其它项目的页面

    vue项目中怎样嵌入其它项目的页面

    这篇文章主要介绍了vue项目中怎样嵌入其它项目的页面问题,具有很好 的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-10-10
  • vue2.0项目实现路由跳转的方法详解

    vue2.0项目实现路由跳转的方法详解

    这篇文章主要介绍了vue2.0项目实现路由跳转的详细方法,非常不错,具有一定的参考借鉴借鉴价值,需要的朋友可以参考下
    2018-06-06

最新评论