小白学VUE——实现抖音时钟(CDN方式)

上一篇我写了NPM方式开发抖音时钟,但是对于小团队来说,没那么资金搞前后端分离,那在传统模式下如何使用Vue呢?这一篇就用CDN引入的方式再次实现抖音时钟,并对代码进行简化。

话不多说,开始吧!

文件目录如下:

以一个Springboot程序搭的框架

抖音时钟实现原理上一篇已经讲到了,所以这里不再过多阐述,直接看代码:

view/timer.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>时钟</title>
    <!--引入vue最新包,调试时用vue.js,发布时用vue.min.js,否则无法调试-->
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <!--引入时钟语言库-->
    <script src="../store/timer.js"></script>
    <!--引入时钟样式-->
    <link rel="stylesheet" href="../css/timer.css" type="text/css">
</head>
<body>
<!--时钟入口-->
<div id="timer">
    <Year :v="year"></Year>
    <Month :v="month" :d="monthBox" :r="50"></Month>
    <Week :v="week" :d="weekBox" :r="90"></Week>
    <Day :v="day" :d="dayBox" :r="130"></Day>
    <Apm :v="apm" :d="apmBox" :r="170"></Apm>
    <Hour :v="hour" :d="hourBox" :r="200"></Hour>
    <Minute :v="minute" :d="minuteBox" :r="250"></Minute>
    <Second :v="second" :d="secondBox" :r="295"></Second>
    <Swap></Swap>
</div>
<!--年份模板-->
<template id="yearComp">
    <ul>
        <li>{{yearLabel}}</li>
    </ul>
</template>
<!--时间模板-->
<template id="timeComp">
    <ul :style="{transform:`rotate(${-360 / list.length * (rotates - 1)}deg)`}">
        <li v-for="(item,index) in list" :key="index"
            :class="{hover: index == rotates -1}"
            :style="{transform:`rotate(${360 / list.length * index}deg)  translateX(${range}px)`}">
            {{ item }}
        </li>
    </ul>
</template>
<!--切换按钮-->
<template id="switchComp">
    <ul style="bottom: -35px;">
        <li>
            <input type="checkbox" id="checkbox" @click="swap" style="z-index: 9999999;position: relative;">
        </li>
    </ul>
</template>
</body>
<!--引入时钟初始化脚本,脚本必须放在模板之后,否则初始化会失败-->
<script src="../js/timer.js"></script>
</html>

这里将月、周、日、午时、小时、分钟、秒钟合同成了一个统一的时间模板timeComp,并将开关也封装成一个模板使用

再来看看js中如何实现

js/timer.js

/**
 * 年份组件
 */
var _yearComp = {
    template : '#yearComp',
    props : ['v'],
    data : function(){
        return {
            yearLabel : '1989'
        }
    },
    watch : {
        v : {
            immediate:true,
            handler : function(val){
                this.yearLabel = val;
            }
        }
    }
};

/**
 * 时间组件
 */
var _timeComp = {
    template : '#timeComp',
    props : ['v','d','r'],
    data : function(){
        return {
            rotates : '',
            list : [],
            range : 0
        }
    },
    //vue的监听器是个坑,注意immediate:true,不加的话数据不会立刻生效,相当于监听器无效
    //下面对数据监听的这种写法(handler写法)等同于v(val){}这种写法
    watch : {
        v : {
            immediate:true,
            handler : function(val){
                this.rotates = val;
            }
        },
        d : {
            immediate:true,
            handler : function(val){
                this.list = val;
            }
        },
        r : {
            immediate:true,
            handler : function(val){
                this.range = val;
            }
        }
    }
};

/**
 * 切换组件
 */
var _switchComp = {
    template : '#switchComp',
    methods: {
        swap(){
            this.$parent.switchFont();
        }
    }
};

/**
 * Vue初始化时,一定要将模板代码放在前面,否则无法识别模板
 */
new Vue({
    el : '#timer',
    //这里定义的是局部组件,可以对通用组件直接引用,若使用Vue.component方式(全局组件)引用组件,不能直接引用_timeComp,需将_timeComp中的代码全部写入组件中,否则无法实例出多个组件
    components : {
        'Year':_yearComp,
        'Month':_timeComp,
        'Week':_timeComp,
        'Day':_timeComp,
        'Apm':_timeComp,
        'Hour':_timeComp,
        'Minute':_timeComp,
        'Second':_timeComp,
        'Swap':_switchComp
    },
    data : function(){
        return {
            //当前时间
            second : '',
            minute : '',
            hour : '',
            apm : '',
            day : '',
            week : '',
            month : '',
            year : '2020',
            //周期列表,初始化各种时间的语言库
            secondBox : [],
            minuteBox : [],
            hourBox : [],
            apmBox : [],
            dayBox : [],
            weekBox : [],
            monthBox : [],
            //当月天数,用于计算月份分割角度(网上有些把月份直接写成30天,设置成固定月份,存在bug)
            days : 0,
            //字体开关,默认简体
            fontType : "Simplified"
        }
    },
    methods: {
        start() {
            //装配时间语言库
            this.makeDate();
            //更新时间,获取实时时间
            setInterval(
                () => {
                    let date = new Date();
                    //组装年份
                    this.year = date.getFullYear();
                    //组装月份
                    this.month = date.getMonth() + 1;
                    //获取当月总天数
                    this.days = new Date(this.year,this.month,0).getDate();
                    //获取当年的天干地支信息
                    this.year = store.sky[this.year % 10] + store.land[this.year % 12];
                    //获取星期几
                    this.week = date.getDay();
                    //获取当天几号
                    this.day = date.getDate();
                    //获取当前小时(12小时制)
                    this.hour = (date.getHours() > 12 ? (date.getHours() -12) : date.getHours());
                    //获取当前分钟(从0分钟开始,因此分钟需增加1)
                    this.minute = date.getMinutes() + 1;
                    //获取当前秒钟(从0秒钟开始,因此秒钟需增加1)
                    this.second = date.getSeconds() + 1;
                    //获取当前是上午还是下午
                    if(this.hour > 12) {
                        this.apm = 2;
                    }else{
                        this.apm = 1;
                    }
                    //组装数据,更新语言库,让数据动起来
                    this.makeDate();
                }
                , 1000);
        },
        makeDate(){
            //初始化数据
            this.secondBox = [];
            this.minuteBox = [];
            this.hourBox = [];
            this.apmBox = [];
            this.dayBox = [];
            this.weekBox = [];
            this.monthBox = [];
            //获取配置数据
            let fdata = null;
            if(this.fontType == "Simplified"){
                fdata = store.format_Simplified;
            }else{
                fdata = store.format_Traditional;
            }
            //组装月
            for(let i=1 ; i<= 12 ; i++){
                if(i <= 10){
                    this.monthBox.push(fdata[i] + "月");
                }else {
                    this.monthBox.push(fdata[10] + fdata[i % 10] + "月");
                }
            }
            //组装周
            for(let i=1 ; i<= 7 ; i++){
                this.weekBox.push("星期" + fdata[i]);
            }
            //组装日
            for(let i=1 ; i<= this.days ; i++){
                if(i <= 10){
                    this.dayBox.push(fdata[i] + "日");
                }else if(i < 20){
                    this.dayBox.push(fdata[10] + fdata[i % 10] + "日");
                }else{
                    if(i % 10 == 0){
                        this.dayBox.push(fdata[parseInt(i / 10)] + fdata[10] + "日");
                    }else{
                        this.dayBox.push(fdata[parseInt(i / 10)] + fdata[10] + fdata[i % 10] + "日");
                    }
                }
            }
            //组装午时
            this.apmBox.push("上午");
            this.apmBox.push("下午");
            //组装小时
            for(let i=1 ; i<= 12 ; i++){
                if(i <= 10){
                    this.hourBox.push(fdata[i] + "点");
                }else{
                    this.hourBox.push(fdata[10] + fdata[i % 10] + "点");
                }
            }
            //组装分钟
            for(let i=0 ; i< 60 ; i++){
                if(i <= 10){
                    this.minuteBox.push(fdata[i] + "分");
                }else if(i < 20){
                    this.minuteBox.push(fdata[10] + fdata[i % 10] + "分");
                }else{
                    if(i % 10 == 0){
                        this.minuteBox.push(fdata[parseInt(i / 10)] + fdata[10] + "分");
                    }else{
                        this.minuteBox.push(fdata[parseInt(i / 10)] + fdata[10] + fdata[i % 10] + "分");
                    }
                }
            }
            //组装秒
            for(let i=0 ; i< 60 ; i++){
                if(i <= 10){
                    this.secondBox.push(fdata[i] + "秒");
                }else if(i < 20){
                    this.secondBox.push(fdata[10] + fdata[i % 10] + "秒");
                }else{
                    if(i % 10 == 0){
                        this.secondBox.push(fdata[parseInt(i / 10)] + fdata[10] + "秒");
                    }else{
                        this.secondBox.push(fdata[parseInt(i / 10)] + fdata[10] + fdata[i % 10] + "秒");
                    }
                }
            }
        },
        //简体、繁体字体切换开关
        switchFont(){
            console.log(11);
            this.fontType = (this.fontType == "Simplified" ? "Traditional" : "Simplified");
        }
    },
    created() {
        //页面加载完成后启动
        this.start();
    }
});

css样式不能使用SCSS方式写了,所以规规矩矩来吧

css/timer.css

#timer ul {
    list-style-type: none;
    padding: 0;
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    margin: auto;
    height: 60px;
    width: 60px;
    transition: 0.1s 0.1s ease-in;
}

#timer ul li {
    position: absolute;
    height: 60px;
    width: 60px;
    color: rgb(204, 46, 46);
    text-align: center;
    font-size: 9px;
    line-height: 60px;
}

.hover {
    text-shadow: #009be5 0px 0px 10px,
    #98f24e 0px 0px 20px,
    #0c16d6 0px 0px 30px,
    #b5e927 0px 0px 40px,
    #d32cbe 0px 0px 70px,
    #dc1313 0px 0px 80px,
    #9a17c0 0px 0px 100px;
}

语言库没什么变化,还是原来的配方,但是得用js方式写了

store/timer.js

var store = {
  format_Traditional : ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖', '拾', '佰', '仟', '万'],
  format_Simplified : ['〇', '一', '二', '三', '四', '五', '六', '七', '八', '九', '十', '百', '千', '万'],
  sky : ['庚', '辛', '壬', '癸', '甲', '乙', '丙', '丁', '戊', '己'],
  land : ['申', '酉', '戌', '亥','子', '丑', '寅', '卯', '辰', '巳', '午', '未']
}

运行效果:

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值