打字游戏(使用Vue开发)

这是一个打字游戏。

规则如下

1、当输入第一个字母的时候,开始计时,当完全输入正确,计时停止。并且不能继续输入。
2、输入字母正确时显示为绿色,错误的显示为红色。
3、输入正确后,点击刷新按钮,可以换题目。

截图如下

开始游戏页面
输入正确页面

你可以学习到以下知识点

1、组件的全局使用。
2、模版的使用。
3、props。从父组件传递参数到子组件。
4、自定义事件。子组件通过emit与父组件进行通讯。

代码如下:

<!DOCTYPE html>
<html>
<head>
    <title>打字游戏</title>
    <script src="https://cdn.bootcss.com/vue/2.5.13/vue.js"></script>
    <style type="text/css">
        .main {
            border: 1px solid #ccc;
            padding: 15px;
            font-size: 20px;
        }
        .green {
            color: green;
        }
        .red {
            color: red;
        }
    </style>
</head>
<body>

    <div id="app" class="main">
        <h1>{{ title }}</h1>
        <hr>
        <typing-game :time-status="currentStatus" @toggle-time-status="toggleStatus" ></typing-game>
        <time-record :time-status="currentStatus" ></time-record>
    </div>

    <div>
        还可以优化的地方:
        1、计数器刷新清零。实现单独计时。(完成)
        2、统计多次计时,算出总数。
        3、不要使用focus触发计时器,使用watch触发。(完成)
    </div>

    <!--模版区域-->
    <script type="text/x-template" id="typing-game-template">
        <div>
            <div>题目 
                <button @click="refresh" :disabled="buttonDisabled">刷新</button>
                <!--
                {{ timeStatus }}
                <button @click="toggleTime">切换</button>
                -->
            </div>
          <div>{{ question }}</div>

          <div><input type="text" v-model="input" :disabled="textDisabled" >  <!--@focus="toggleTime"-->    </div>
          <div v-html="answer"></div>
        </div>
    </script>

    <script type="text/x-template" id="time-record-template">
        <div>
            {{ time.toFixed(2) }}
        </div>
    </script>
    <!--模版区域-->

    <script type="text/javascript">
        let timeCounter; //计数器变量

        Vue.component('typing-game', {
            template: '#typing-game-template',
            props: ['timeStatus'],
            data () {
                return {
                    question: getRandomString() ,
                    input: '',
                    textDisabled: false,
                    buttonDisabled: false,
                    isTyping: true //是否正在输入
                }   
            },
            computed: {
                answer () {
                    let questionLen = this.question.length;
                    let questionAry = [];
                    let input = this.input;
                    let inputLen = input.length;
                    let inputAry = [];
                    let output = '';
                    let count = 0;
                    for (let i = 0; i < questionLen; i ++) {
                        questionAry.push(this.question[i])
                    }
                    
                    for (let i = 0; i < inputLen; i ++) {
                        inputAry.push(input[i])
                    }

                    inputAry = inputAry.map((value, index) => {
                        if (value === questionAry[index]) {
                            value = '<span class="green">' + value + '</span>';
                            count ++;
                        } else {
                            value = '<span class="red">' + value + '</span>';
                        }
                        return value;
                    })
                    if (questionLen === count && questionLen === inputLen ) {
                        output = inputAry.join('') + ' 完全正确';
                        this.textDisabled = true;
                        this.toggleTime();
                    } else {
                        output = inputAry.join('');
                    }
                    return output;
                }
            },
            methods: {
                refresh () {
                    this.question = getRandomString();
                    this.input = '';
                    this.textDisabled = false;
                },
                toggleTime () {
                    this.buttonDisabled = !this.buttonDisabled;
                    this.isTyping = !this.isTyping;
                    this.$emit('toggle-time-status');
                }
            },
            watch: {
                input: function (newValue, oldValue) {
                    if (this.isTyping) {
                        this.toggleTime();
                    } 
                }
            }
        })

        Vue.component('time-record', {
            template: '#time-record-template',
            //props: ['timeStatus', 'currentTime'],
            props: {
                timeStatus: String,
                currentTime: Number
            },
            data () {
                return {
                    time: 0.00,
                }
            },
            watch: {
                timeStatus (newValue, oldValue) {
                    console.log(111111);
                    if (newValue === 'start') {
                        this.time = 0.00;
                        timeCounter = setInterval(() => {
                            this.time += 0.01
                            //this.time = this.time.toFixed(2);
                        }, 10); 
                    } else {
                        clearInterval(timeCounter)
                    }
                }
            }
        })

        var app = new Vue({
            el: '#app',
            data: {
                title: 'Typing Game',
                currentStatus: 'end'
            },
            methods: {
                toggleStatus () {
                    this.currentStatus = this.currentStatus === 'start' ? 'end' : 'start';
                }
            }
        })

        function getRandomString() {
            let chars = 'abcdefghijklmnopqsrtuvwxyz';
            const max =  20; //less than 20
            let randomString = '';
            let randomNumber = Math.floor(Math.random() * max); 
            randomNumber = randomNumber === 0 ? max : randomNumber;
            for (let i = 0; i < randomNumber; i ++) {
                randomString += chars.charAt(Math.floor(Math.random() * 26));

            }
            return randomString;
        }
    </script>
</body>
</html>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,544评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,430评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,764评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,193评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,216评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,182评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,063评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,917评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,329评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,543评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,722评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,425评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,019评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,671评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,825评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,729评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,614评论 2 353

推荐阅读更多精彩内容

  • HTML模版 之后出现的React代码嵌套入模版中。 1. Hello world 这段代码将一个一级标题插入到指...
    ryanho84阅读 6,232评论 0 9
  • 下载安装搭建环境 可以选npm安装,或者简单下载一个开发版的vue.js文件 浏览器打开加载有vue的文档时,控制...
    冥冥2017阅读 6,037评论 0 42
  • 最近看了一本关于学习方法论的书,强调了记笔记和坚持的重要性。这几天也刚好在学习React,所以我打算每天坚持一篇R...
    gaoer1938阅读 1,675评论 0 5
  • 这篇笔记主要包含 Vue 2 不同于 Vue 1 或者特有的内容,还有我对于 Vue 1.0 印象不深的内容。关于...
    云之外阅读 5,048评论 0 29
  • 此文基于官方文档,里面部分例子有改动,加上了一些自己的理解 什么是组件? 组件(Component)是 Vue.j...
    陆志均阅读 3,825评论 5 14