vue 井号

This tutorial assumes that you have a little prior knowledge of JavaScript and the Vue framework. You also need to have Node and Git installed on your system.

本教程假定您具有JavaScript和Vue框架的先验知识。 您还需要在系统上安装Node和Git。

介绍 ( Introduction )

This tutorial focuses on building a game with the Vue framework. You will also learn about vue-cli, vue-loader and the workflow of making user interfaces for the web using Vue. At the end of the tutorial, you will have a playable Tic-Tac-Toe game like this below:

本教程重点介绍使用Vue框架构建游戏。 您还将了解vue-cli , vue-loader和使用Vue制作Web用户界面的工作流程。 在本教程的最后,您将拥有一个可玩的井字游戏,如下所示:

什么是井字游戏? ( What is Tic-Tac-Toe? )

In this tutorial, we are going to build a simple tic-tac-toe game with the Vue framework. Tic-Tac-Toe is a two-players pencil and paper game. One player is Cross 'X' and the other one is Nought 'O'. The game is based on a 3x3 grid with each box in the grid having the space to be marked with either X or O. One move consists of one mark. The game is turn-based meaning that players own a move one after the other. Once a mark has been placed, it cannot be altered. So, who wins the game? The one who is able to place 3 consecutive Xs or Os in a line. The line can be vertical, horizontal or diagonal. And to get acquainted with it, search Google for tic-tac-toe and play it the times until you don't want to any longer.

在本教程中,我们将使用Vue框架构建一个简单的井字游戏。 Tic-Tac-Toe是两人玩的纸笔游戏。 一个球员是十字“X”,另一个是徒劳“O”。 游戏基于3x3网格,网格中的每个框都有要用XO标记的空间。 一招由一分组成。 游戏是基于回合制的,这意味着玩家拥有一个接一个的动作。 标记一旦放置,就无法更改。 那么,谁赢得了比赛? 能够在一行中连续放置3个X或O的人。 该线可以是垂直,水平或对角线。 并且要熟悉它,请在Google上搜索 井字游戏,并播放几次,直到您不再想要。

Hey Hammad, I already knew all this stuff and I've played it a hundred times before? I know, I know. Forgive me for this intro and let's get started to dive in.

嘿哈玛德,我已经知道所有这些东西了,我玩过一百次了吗? 我知道我知道。 请原谅我的介绍,让我们开始深入。

为什么选择Vue ( Why Vue )

This version of Tic-Tac-Toe is going to be browser-based and implemented using Vue. The reason we are building it with Vue is that there can't be anything simpler than that. And by anything, I mean any other JavaScript framework. You know you can use something else. But in this particular tutorial, you have to stick by me.

此版本的Tic-Tac-Toe将基于浏览器并使用Vue实施。 我们之所以用Vue构建它,是因为没有比这更简单的了。 而到任何东西 ,我的意思是任何其他JavaScript框架。 您知道您可以使用其他东西。 但是在这个特定的教程中,您必须坚持我。

建立 ( Setup )

For the setup, we are going to use vue-loader with vue-cli.

对于设置,我们将使用vue-loadervue-cli

@media (max-width: 1280px) { .go-go-gadget-react img:first-child { display: none; } }@media (max-width: 780px) {.go-go-gadget-react { flex-direction: column; }.go-go-gadget-react img { margin-left: 0 !important; margin-bottom: 12px !important; }.header-thingy { margin-top: 20px; }.button-thingy { margin-left: 0 !important; margin-top: 12px !important; }} @media (max-width: 1280px) { .go-go-gadget-react img:first-child { display: none; } }@media (max-width: 780px) {.go-go-gadget-react { flex-direction: column; }.go-go-gadget-react img { margin-left: 0 !important; margin-bottom: 12px !important; }.header-thingy { margin-top: 20px; }.button-thingy { margin-left: 0 !important; margin-top: 12px !important; }}

Vue-Cli (vue-cli)

vue-cli is a simple CLI (Command Line Interface) tool for scaffolding Vue projects. It provides project boilerplate, allows you to write ES2015, convert processors into plain CSS and handles all the rest. Install vue-cli on your machine using the following command:

vue-cli是用于搭建Vue项目的简单CLI(命令行界面)工具。 它提供了项目样板,允许您编写ES2015,将处理器转换为纯CSS并处理所有其余内容。 使用以下命令在您的计算机上安装vue-cli:

npm install -g vue-cli

Now that you vue-cli, run the following commands in the terminal for vue-cli to scaffold the project structure for you:

现在您已经建立了vue-cli,在终端中运行以下命令以使vue-cli可以为您搭建项目结构:

vue init webpack-simple vue-tic-tac-toe

Here, vue-tic-tac-toe is the name of the project, in which vue-cli will init in. webpack-simple is a template that includes both Webpack and vue-loader.

在这里,VUE,井字棋是项目,其中VUE-CLI将在初始化的名字。 的WebPack,简单的是包括的WebPack和VUE装载机的模板。

After that, cd in the vue-tic-tac-toe and install the dependencies using npm:

之后,在vue-tic-tac-toe中使用cd并使用npm安装依赖项:

cd vue-tic-tac-toe
npm install

加载器 (vue-loader)

vue-loader is a loader for Webpack that allows you to write the template and CSS for a component all in one file. The file needs to have .vue extension. This is how an example .vue file looks like:

vue-loader是Webpack的加载器,它使您可以在一个文件中编写组件的模板和CSS。 该文件必须具有.vue扩展名。 这是一个示例.vue文件的样子:

<template><div class="message">{{ speaker }} says: {{ message }} to the <world></world></div>
</template><script>import World from './World.vue'export default {components: { World },data () {return {speaker: 'Hammad',message: 'I will rule the world'}}}
</script><style>.message {padding: 10px;background-color: steelblue;color: #fff;}
</style>

Create a components folder in the src directory present in the root. It will contain all of our components. Now that everything is ready, run this command to view this app in the browser:

在根目录下的src目录中创建一个components文件夹。 它将包含我们所有的组件。 现在一切就绪,运行以下命令在浏览器中查看此应用程序:

npm run dev

This command will load http://localhost:8080/ in the browser. Every change you make in your code will be reflected in the browser even without refreshing the page. Open App.vue in your code editor and delete all the unnecessary stuff present in the template and script tag. Now your App.vue file looks like this:

该命令将在浏览器中加载http://localhost:8080/ 。 您对代码进行的每项更改都将反映在浏览器中,即使不刷新页面也是如此。 在代码编辑器中打开App.vue,然后删除模板和脚本标签中存在的所有不必要的内容。 现在,您的App.vue文件如下所示:

<template><div id="app"></div>
</template><script>
export default {name: 'app',data () {return {}}
}
</script><style>
#app {font-family: 'Avenir', Helvetica, Arial, sans-serif;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;text-align: center;color: #2c3e50;margin-top: 60px;
}h1, h2 {font-weight: normal;
}ul {list-style-type: none;padding: 0;
}li {display: inline-block;margin: 0 10px;
}a {color: #42b983;
}
</style>

游戏元素 ( Game Elements )

Thinking of this game, all the things that come to my mind are:

考虑到这个游戏,我想到的所有东西都是:

  • 2 Players (X and O)2位玩家(X和O)
  • The Board Grid板格
  • 3 Rows3排
  • 3 Columns3栏
  • 9 Grid Cells9个网格单元
  • Scoreboard (The number of wins for each player)计分板(每个玩家的获胜数)
  • Number of match being played参加比赛的次数
  • Player turn玩家回合
  • Restarting the game重新开始游戏

We will extract some of them elements into their own components and others as properties of those components.

我们将其中一些元素提取到它们自己的组件中,并将其他元素提取为那些组件的属性。

Vue组件 ( Vue Components )

The benefit of using components is that we can reuse them. Like, we can use the Cell component 9 times, without having the need to duplicate it. This keeps our code DRY (Don't Repeat Yourself). Our component structure will look like this:

使用组件的好处是我们可以重用它们。 就像,我们可以使用Cell组件9次,而无需重复它。 这使我们的代码保持干燥(不要重复自己)。 我们的组件结构如下所示:

-- App
---- Board
------ Cell x9

Create these components: Board.vue and Cell.vue in the components folder with the following boilerplate code.

创建以下组件:具有以下样板代码的components文件夹中的Board.vue和Cell.vue。

<template></template><script>export default {data () {}}
</script><style></style>

造型 ( Styling )

To make sure that this game doesn't hurt your eyes, you can grab all the styling and fonts from here and paste them in your code.

为确保该游戏不会伤害您的眼睛,您可以从此处获取所有样式和字体,并将其粘贴到代码中。

In the index.html file, I only added two fonts and changed the title. The Dosis font is for the whole body and the Gochi Hand font is for the X and O placed in the grid. Both are taken from Google Fonts. This is how our index.html file looks like:

index.html文件中,我仅添加了两种字体并更改了标题。 Dosis字体适用于整个身体, Gochi Hand字体适用于放置在网格中的X和O。 两者均取自Google字体。 这就是我们的index.html文件的样子:

<!DOCTYPE html>
<html lang="en"><head><meta charset="utf-8"><title>Tic-Tac-Toe Game</title><link href="https://fonts.googleapis.com/css?family=Dosis|Gochi+Hand" rel="stylesheet"></head><body><div id="app"></div><script src="/dist/build.js"></script></body>
</html>

Change the <style> tag of your App component to this:

将您的App组件的<style>标记更改为此:

<style>
body {background-color: #fff;color: #fff;font-family: 'Dosis', Helvetica, sans-serif;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;text-align: center;margin: 0px;
}#app {margin: 0 auto;max-width: 270px;color: #34495e;
}h1 {text-transform: uppercase;font-weight: bold;font-size: 3em;
}.restart {background-color: #e74c3c;color: #fff;border: 0px;border-bottom-left-radius: 10px;border-bottom-right-radius: 10px;font-family: 'Dosis', Helvetica, sans-serif;font-size: 1.4em;font-weight: bold;margin: 0px;padding: 15px;width: 100%;
}.restart:hover {background-color: #c0392b;cursor: pointer;
}.scoreBoard {display: flex;flex-direction: row;justify-content: space-around;align-items: center;width: 100%;height: 15px;background-color: #16a085;box-shadow: 10px solid #fff;padding: 20px;overflow-x: none;
}.scoreBoard h2 {margin: 0px;
}.scoreBoard span {float: right;font-size: 1.5em;font-weight: bold;margin-left: 20px;
}
</style>

Add this to the <style> tag of the Grid component:

将此添加到Grid组件的<style>标记中:

.grid {background-color: #34495e;color: #fff;width: 100%;border-collapse: collapse;
}.gameStatus {margin: 0px;padding: 15px;border-top-left-radius: 20px;border-top-right-radius: 20px;background-color: #f1c40f;color: #fff;    font-size: 1.4em;font-weight: bold;
}.statusTurn {background-color: #f1c40f;
}.statusWin {background-color: #2ecc71;
}.statusDraw {background-color: #9b59b6;
}

And this to that of the Cell component:

这与Cell组件有关:

.cell {width: 33.333%;height: 90px;border: 6px solid #2c3e50;font-size: 3.5em;font-family: 'Gochi Hand', sans-serif;
}.cell:hover {background-color: #7f8c8d;
}.cell::after {content: '';display: block;
}.cell:first-of-type {border-left-color: transparent;border-top-color: transparent;
}.cell:nth-of-type(2) {border-top-color: transparent;
}.cell:nth-of-type(3) {border-right-color: transparent;border-top-color: transparent;
}tr:nth-of-type(3) .cell {border-bottom-color: transparent;
}

组件模板 ( Component Templates )

The template section of a component contains all the markup that makes up the component. Our App component will contain the Gird component and the Gird component will contain 9 Cell components. The App component is very simple and only contains a heading and a grid for the game. We will add more functionality later.

组件的模板部分包含组成该组件的所有标记。 我们的App组件将包含Gird组件,而Gird组件将包含9个Cell组件。 App组件非常简单,仅包含游戏的标题和网格。 稍后我们将添加更多功能。

<div id="app"><div id="details"><h1>Tic Tac Toe</h1></div><grid></grid>
</div>

The Grid component contains a table that has three rows and three cells in each row. The cell number is passed down as a prop to uniquely identify each cell. The template of the Grid component:

网格组件包含一个表,该表具有三行和每行三个单元格。 信元编号作为唯一标识每个信元的道具向下传递。 Grid组件的模板:

<table class="grid"><tr><cell name="1"></cell><cell name="2"></cell><cell name="3"></cell></tr><tr><cell name="4"></cell><cell name="5"></cell><cell name="6"></cell></tr><tr><cell name="7"></cell><cell name="8"></cell><cell name="9"></cell></tr>
</table>

The Cell component contains only a <td> tag to hold the mark X or O.

Cell组件仅包含<td>标记,以保留标记XO。

<td class="cell">{{ mark }}</td>

游戏流程 ( The Game Flow )

To start adding functionality to our game, we need to determine the flow of events which will take place with each user interaction. The flow of the game is as follows:

要开始为我们的游戏添加功能,我们需要确定每次用户交互都会发生的事件流。 游戏流程如下:

  • The App is loaded.该应用已加载。
  • All cells are empty.所有单元格均为空。
  • O is the first player.O是第一位玩家。
  • The player can place an O in any of the cells.玩家可以在任何单元格中放置一个O。
  • The player-turn is changed X.玩家回合更改为X。
  • Each time a player places a mark, the turn is handed to the non-active player.每次玩家放置一个标记,该回合将移交给无效玩家。
  • After each strike, we need to check if the game meets any winning condition.每次罢工后,我们需要检查游戏是否满足任何获胜条件。
  • We also need to check if the game is a draw.我们还需要检查游戏是否平局。
  • After or anytime in between a game, a button called Restart can be clicked to restart the game.在游戏之后或之间的任何时间,都可以单击名为“ 重新启动”的按钮以重新启动游戏。
  • The status of the game that is if the game is in progress or won or is a draw.游戏的状态,即游戏进行中,获胜或平局。
  • In terms of progress, the status displays the turn of the respective player.根据进度,状态显示相应玩家的回合。
  • The game also displays the number of matches and the number of wins for each player.游戏还会显示每个玩家的比赛次数和获胜次数。

For all of this to be able to happen, our components need some data properties and methods.

为了使所有这些事情都能发生,我们的组件需要一些数据属性和方法。

资料属性 ( Data Properties )

We will divide the data among the components according to their relation or ease of access to that component.

我们将根据组件之间的关系或访问该组件的难易程度在组件之间划分数据。

The App component will hold the number of matches and the number of wins for each player.

应用程序组件将保留每个玩家的比赛次数和获胜次数。

data () {return {matches: 0,wins: {O: 0,X: 0}}
}

The Grid component holds the data for the active player (X or O), the game status, status message, status color (for displaying on the top bar), the number of moves played by both players to (check for a draw), the mark placement for each cell and all (8) the winning conditions. The winning conditions array contains 8 arrays, and each array contains possible winning same cell (all X or all O) mark arrangement of cell number. These conditions can be compared with the cells object to check for a win.

网格组件保存活动玩家的数据( XO ),游戏状态,状态消息,状态颜色(用于显示在顶部栏上),两个玩家进行的移动次数(检查抽签),每个单元的标记位置以及所有(8)获胜条件。 获胜条件数组包含8个数组,每个数组包含可能的获胜同一个单元格(所有X或所有O )标记的单元格编号排列。 可以将这些条件与单元格对象进行比较以检查获胜。

data () {return {// can be O or XactivePlayer: 'O',// maintains the status of the game: turn or win or drawgameStatus: 'turn',gameStatusMessage: `O's turn`,// status color is used as background color in the status bar// it can hold the name of either of the following CSS classes// statusTurn (default) is yellow for a turn// statusWin is green for a win// statusDraw is purple for a drawgameStatusColor: 'statusTurn',// no. of moves played by both players in a single game (max = 9)moves: 0,// stores the placement of X and O in cells by their cell numbercells: {1: '', 2: '', 3: '',4: '', 5: '', 6: '',7: '', 8: '', 9: ''},// contains all (8) possible winning conditionswinConditions: [[1, 2, 3], [4, 5, 6], [7, 8, 9], // rows[1, 4, 7], [2, 5, 8],    [3, 6, 9], // columns[1, 5, 9], [3, 5, 7]             // diagonals],}
}

The Cell component holds the mark that the player placed in it. By default that value is set to an empty string. The frozen property is used to ensure that the player is not able to change the mark, once it is placed.

Cell组件保留玩家放置在其中的标记。 默认情况下,该值设置为空字符串。 冻结属性用于确保放置标记后玩家无法更改标记。

props: ['name'],
data () {return {// enables the player to place a markfrozen: false,// holds either X or O to be displayed in the tdmark: ''}
}

The Cell component also has a name prop for uniquely identifying each cell with a number.

单元组件还具有名称道具,用于用数字唯一标识每个单元。

活动巴士 ( Event Bus )

Our components need to talk to each other to inform them about a change in their data property or an action performed by the user like placing a mark in a cell. To do so, we will use an event bus. To make an event bus, we will assign a new Vue instance to a property called Event on the window object. You can change this to anything you want depending on the context of your code, but Event, here, will do just fine.

我们的组件需要互相交谈,以通知他们有关其数据属性的更改或用户执行的操作,例如在单元格中放置标记。 为此,我们将使用事件总线。 为了创建事件总线,我们将新的Vue实例分配给窗口对象上名为Event的属性。 您可以根据代码的上下文将其更改为所需的任何内容,但是这里的Event会很好。

window.Event = new Vue()

With it, you can do things like Event.$emit() and Event.$on for firing and listening to events respectively. The event name as the first argument. You can also include any other data after the name argument. The other data is called Payload. Consider this example:

有了它,您可以分别执行Event.$emit()Event.$on来触发和监听事件。 事件名称作为第一个参数。 您还可以在name参数之后包含其他任何数据。 其他数据称为有效负载。 考虑以下示例:

Event.$emit('completed', this.task)

This fires an event called completed and passes this.task as payload. You can listen to this event fire with the Event.$on() method like this:

这将触发一个名为complete的事件,并将this.task作为有效载荷传递。 您可以使用Event.$on()方法侦听此事件触发:

Event.$on('completed' (task) => {// do something
})

To continue listening to an event fire, we can place the Event.$on method in the created method of that Vue component.

为了继续监听事件,我们可以将Event.$on方法放在该Vue组件的创建方法中。

created () {Event.$on('completed' (task) => {// do something})
}

After adding the Event bus to your main.js file, it will look like this:

将事件总线添加到main.js文件后,它将如下所示:

import Vue from 'vue'
import App from './App.vue'window.Event = new Vue()new Vue({el: '#app',render: h => h(App)
})

Now, we are ready to fire and listen for events in our game.

现在,我们准备解雇并监听游戏中的事件。

下一步是什么 ( What's Next )

We will continue, adding functionality to our game, in a follow-up lesson of this two-part series.

在这个分为两部分的系列的后续课程中,我们将继续为游戏添加功能。

结论 ( Conclusion )

In this tutorial, we wireframed almost all the parts of our game. We have added styling, templates and data properties and distributed them among components. At the end, we also created an event bus to handle all of the data flow and user action notifications between our components. If you did not undertand something, experienced a bug or have some other question, feel free to ask in the comments below.

在本教程中,我们对游戏的几乎所有部分进行了线框设计。 我们添加了样式,模板和数据属性,并将它们分布在组件之间。 最后,我们还创建了一个事件总线,以处理组件之间的所有数据流和用户操作通知。 如果您不了解任何内容,遇到错误或有其他问题,请随时在下面的评论中提问。

翻译自: https://scotch.io/tutorials/building-a-tic-tac-toe-game-with-vue-2-part-1

vue 井号

vue 井号_使用Vue 2制作井字游戏:第1部分相关推荐

  1. axios vue 回调函数_前端Vue 面试题大全

    点蓝色字关注"程序员报刊" 「  学习 新闻 招聘 」 vue的底层原理? vue组件之间的通信? JS中判断数据类型的方法有几种? 最常见的判断方法:typeof 判断已知对象类 ...

  2. vue filter对象_学习vue源码(3) 手写Vue.directive、Vue.filter、Vue.component方法

    一.Vue.directive Vue.directive(id,[definition]); 1)参数 { string } id{ Function | Object } [ definition ...

  3. vue tree组件_使用Vue 3.0做JSX(TSX)风格的组件开发

    前言 我日常工作都是使用React来做开发,但是我对React一直不是很满意,特别是在推出React Hooks以后. 不可否认React Hooks极大地方便了开发者,但是它又有非常多反直觉的地方, ...

  4. 覆盖vue.js样式_使用Vue.js和Cloudinary在化身上覆盖眼镜/面罩

    覆盖vue.js样式 Deep Learning, a subset of machine learning, helps break down tasks in ways that makes al ...

  5. vue 路由重定向_使用Vue和Vue路由器进行高级路由:重定向和Nav Guard

    vue 路由重定向 While the basics of routing in Vue.js have already been covered, today we'll explore some ...

  6. vue 图片裁剪工具_使用Vue.js的图片裁剪工具,包括预览

    vue 图片裁剪工具 Vue作物 (vue-crop) Images Crop tool with Vue.js including preview. 使用Vue.js的图片裁剪工具,包括预览. Vi ...

  7. vue canvas插件_基于vue.js 制作在线桌椅定制选择交互特效源码

    码农那点事儿 关注我们,一起学习进步 基于vue.js写的在线桌子椅子垫子选择拼成的自己理想的书桌椅图像,这是一款交互式的课桌椅在线定制选择功能.非常不错,感兴趣的朋友前来下载使用. 下载源码(提取码 ...

  8. vue日程安排_在Vue项目中用fullcalendar制作日程表的示例代码

    前言 最近老牌日历插件fullcalendar更新了v4版本,而且添加了vue支持,所以用最新的fullcalendar v4制作一个完整日历体验一下,效果图: 安装 fullcalendar的功能被 ...

  9. vue 图片剪辑_用vue制作的图片剪辑组件

    vue 图片剪辑 形状 (vueShapeImg) Picture clipping component made with vue. 用vue制作的图片剪辑组件. View demo 查看演示 Do ...

最新文章

  1. 第三部分:MFC中控件的样式
  2. tnsname.ora文件配置详解
  3. 使用Goldengate 实现Oracle for Oracle 单向数据同步
  4. 要找到现阶段最适合自己的方法
  5. 【java】Java中TypeReference用法说明
  6. HTTP从入门到入土(1)——五层网络模型
  7. 简单计算器——两种方法
  8. 6.微服务设计 --- 部署
  9. java 文件流 追加_JAVA向文件中追加内容(转)
  10. quartus仿真13:D触发器和JK触发器
  11. 批量修改图片格式类型
  12. Python基础语法题库
  13. 448. Find All Numbers Disappeared in an Array -- Python
  14. QUALCOMM MDM9X15 LCD初始化流程
  15. 西门子S7-300 PLC 的50个经典问题
  16. 高档微型计算机,五款中高端声卡综合横向评测
  17. 第十二届noc网络机器人赛项成绩_我省在第十二届中小学NOC活动决赛中获佳绩
  18. python基础3-----list/dict/set/tuple
  19. 滑膜炎的表现、诊断与治疗
  20. 最近使用的一款session工具:sa-Token

热门文章

  1. CSS3 使用@font-face引入字体的兼容性方案及优化
  2. 虚拟服务器liter,liter_sheng
  3. [测试通过]svn详细权限配置
  4. Android后台切回到应用显示广告页
  5. 华为交换机查看设备型号
  6. MongoDB学习记录10-分片-副本集(mongodb3.2版本以前)
  7. 读《编码:隐匿在计算机软硬件背后的语言》有感
  8. springboot实战—BMI体脂计算器-服务器端
  9. python生成摸头GIF动态图
  10. 行业集中度数据(2000-2020年 )