利用vue开发一个所谓的数独方法实例


Posted in Javascript onDecember 21, 2017

1.前言

最近工作中遇到一个问题,因为后台管理系统页面功能暂时没有新的需求,就在想首页放什么东西,最近我想到的就是放个所谓的数独,为什么是所谓的数独,因为规则不同于标准的数独,只要求每一行每一列数字不一样就可以了!这个实例也是基于vue的,代码分享给大家。给大家代码,并不是要让大家直接拷贝代码,而是希望能让大家当做是一个练手的项目,或者学习到知识。如果大家觉得我哪里写得不好,写错了,欢迎指出,让大家交流意见,一起进步。

代码上传到github了:有需要的可以star一下!vue-demos

2.运行效果

利用vue开发一个所谓的数独方法实例

3.实现步骤

实现步骤,感觉说得有点绕,建议大家边写边看文章,这样不会懵。或者直接去看源码(sudoku),把源码看懂!这个项目也不复杂!

3-1.准备数据和排版

排版的html+css代码我不多说了,排版很简单,这个相信都难不倒大家的。复杂一点的就是数据的交互!
下面开始第一步,把数独的数据先准备好,数据是什么,大家都知道,就是像下面这样的数据!

利用vue开发一个所谓的数独方法实例

排版出来的效果就是下面这样。

利用vue开发一个所谓的数独方法实例

html代码如下

<div class="num-table" @mouseleave="hoverCol=''" :class="{'shake':isShake}">
 <!--遍历每一行-->
 <div v-for="row,index in allNum" class="num-row chearfix">
 <!--遍历行里面的每一列-->
 <div v-for="num1,indexSub in row" class="num-col">
  {{allNumText[index][indexSub]}}
 </div>
 </div>
</div>

代码也很简单,如下

mounted(){
 let arr1 = [1, 2, 3, 4, 5, 6, 7, 8, 9];
 let row = [], rowCol = 0;
 for (let i = 0, len = arr1.length; i < len; i++) {
 row = Object.assign([], arr1);
 this.allNum.push(row);
 //删除第一个数字并记录下来
 rowCol = arr1.splice(0, 1)[0];
 //在最后面插入数字
 arr1.push(rowCol)
 }
}

大家也可以发现,这个数据,的每一行和每一列的数字都是不同样的!

3-2.打乱行

之后就是随机打乱顺序了,打乱顺序这个得保证一个前提,就是保证每一行每一列的数字都不一样。这样的话,我用了一个简单粗暴的方法-以行或者列为单位,进行打乱。比如,第一行和第三行进行位置交互,第一列和第五列进行位置的交换。下面说下以行为单位的打乱顺序!

行的打乱,很简单,就是随机打乱数组而已!一行代码搞定!

this.allNum.sort((n1, n2) => Math.random() - 0.5);

利用vue开发一个所谓的数独方法实例

3-3.打乱列

行打乱了,下面进行以列为单位的打乱,这个稍微复杂一点。

大家想下,比如第二列是第五列的值进行交换,那就是每一行的第二个格子的值和第五个格子的值进行交换,那么就需要遍历每一行!来进行交换,至于前面说的第二列和第五列的这个列数,可以用一个函数实现!

下面看代码!

//随机获取两列的索引
function randomText() {
 let rondomIndex = 0, rondomIndexAfter = 0;
 //获取第一列的索引
 rondomIndex = Math.floor(Math.random() * 9);
 function randomDo() {
 rondomIndexAfter = Math.floor(Math.random() * 9);
 //如果第一列和第二列索引一样,第二列的索引再次重新随机获取
 if (rondomIndexAfter === rondomIndex) {
  randomDo();
 }
 }
 randomDo();
 //返回两列的索引
 return [rondomIndex, rondomIndexAfter]
}
//打乱列
let randomArr = [], nowValue = 0;
//同样遍历9次
for (let i = 0; i < 9; i++) {
 randomArr = Object.assign([], randomText());
 //遍历每一行,给每一行的随机两列交换值
 for (let j = 0, len = this.allNum.length; j < len; j++) {
 //随机两列交换值
 nowValue = this.allNum[j][randomArr[0]];
 this.allNum[j][randomArr[0]] = this.allNum[j][randomArr[1]];
 this.allNum[j][randomArr[1]] = nowValue;
 }
}

利用vue开发一个所谓的数独方法实例

3-3.随机掏空单元格

掏空单元格就是把一些格子随机设空,然后让玩数独的人。把这些单元格给填上!

需求,我现在实现的就是,每一行有把两个格子设空,这里我的做法是,把每一个格子的坐标先记录下来,然后再从记录的坐标里面随机获取坐标,用获取到的坐标,进行设空!

首先,获取所有点的坐标

//记录所有坐标
let rowText = '', arrText = []
for (let i = 0; i < 9; i++) {
 rowText = ''
 for (let j = 0; j < 9; j++) {
  rowText += i + '-' + j + ',';
 }
 arrText.push(rowText.substr(0, rowText.length - 1))
}
console.log(arrText);

利用vue开发一个所谓的数独方法实例

看到这个坐标,大家很容易的知道,数组的一个元素,就是第一行,‘0-0'就是第一行第一个格子。数组最后一个元素,就是最后一行,‘8-8'就是最后一行,最后一个格子,其他如此类推!

下面进行随机掏空,代码也很简单!

//随机掏空
let nowItme = [], _option, nowOption = [];
for (let i = 0; i < 9; i++) {
 //抽取当前行的所有坐标
 nowItme = arrText[i].split(',');
 nowOption = [];
 //当前行的随机两个坐标掏空
 for (let j = 0; j < 2; j++) {
  //抽取当前行的随机一个坐标
  _option = Math.floor(Math.random() * nowItme.length);
  //分割坐标的x,y
  nowOption = nowItme.splice(_option,1)[0].split("-");
  this.allNum[nowOption[0]][nowOption[1]] = '';
 }
}

利用vue开发一个所谓的数独方法实例

这样相信大家都觉得奇怪,下面进行下样式的该写,就是把设空了的格子的样式改一下!.no这个class对应的样式我在css那里写好了,大家注意下。

<!--遍历每一行-->
<div v-for="row,index in allNum" class="num-row chearfix">
 <!--遍历行里面的每一列-->
 <!--
  no:被掏空数组的样式
 -->
 <div v-for="num1,indexSub in row" :class="{'no':num1===''}" class="num-col">
  {{allNumText[index][indexSub]}}
 </div>
</div>

利用vue开发一个所谓的数独方法实例

3-4.显示数字键盘

首先,我简单的用一个流程图说下逻辑,如下

利用vue开发一个所谓的数独方法实例

然后关于数字键盘的位置,看下图(数字键盘的样式我不多说了,就是一个是相对定位,一个绝对定位的设置而已)

利用vue开发一个所谓的数独方法实例

如上图,我点击的是第一行第三个格子,首先,我期待被点击的格子的样式有所改变,方便我区分,这个不难,用一个class改变样式就可以了,这个可以看下面的代码,我用一个.cur的class控制样式。还有一个就是期待数字键盘在第二行,第四个格子那里出现。这样的话,大家就知道,数字键盘的位置是怎么定位的了!数字键盘的top就是,被点击格子所在的行的索引+160(60是格子的宽高),left就是,被点击格子所在的列的索引+160(60是格子的宽高)。比如上图,第一行第三个格子,top=(0+1)*60+'px',left=(2+1)*60+'px'。

代码如下

<!--遍历每一行-->
 <div v-for="row,index in allNum" class="num-row chearfix">
  <!--遍历行里面的每一列-->
  <!--
   no:被掏空数组的样式
   cur:格子被点击时触发,被点击的格子样式
  -->
  <div v-for="num1,indexSub in row"
    :class="{'no':num1==='',
    'cur':curRow===index&&indexSub===curCol}"
    @click="showCheck(index,indexSub)" class="num-col">
   {{allNumText[index][indexSub]}}
  </div>
 </div>
<!--数字键盘-->
<div class="num-check chearfix" :style="{'top':(curRow+1)*60+'px','left':(curCol+1)*60+'px'}"
  v-show="checkShow">
 <ul>
  <li @click="inputText(1)">1</li>
  <li @click="inputText(2)">2</li>
  <li @click="inputText(3)">3</li>
  <li @click="inputText(4)">4</li>
  <li @click="inputText(5)">5</li>
  <li @click="inputText(6)">6</li>
  <li @click="inputText(7)">7</li>
  <li @click="inputText(8)">8</li>
  <li @click="inputText(9)">9</li>
 </ul>
</div>

js代码

/**
 * @description 显示数字键盘
 * @param i1
 * @param i2
 */
showCheck(i1, i2){
 //点击的格子是否是被掏空的格子
 if (this.allNum[i1][i2] !== '') {
  return
 }
 //点击的格子如果是上一次点击的格子(当前格子)
 if (i1 === this.curRow && i2 === this.curCol) {
  //隐藏数字键盘,curRow和curCol设空
  this.checkShow = false;
  this.curRow = '';
  this.curCol = '';
 }
 else {
  //隐藏数字键盘,curRow和curCol分别设置成当前的点
  this.checkShow = true;
  this.curRow = i1;
  this.curCol = i2;
 }
},

运行效果

利用vue开发一个所谓的数独方法实例

3-5.高亮显示同行同列

这一步很简单,首先,高亮显示行,大家都知道怎么做了,就是行对应的div,设置一个:hover,然后对应设置单元格的样式而已!这个不多说!

利用vue开发一个所谓的数独方法实例

然后,高亮显示列,复杂一点,但是也很简单,原理我想大家也知道,就是当鼠标进如格子的时候,在data里面,用一个变量储存进入的格子的列的索引,然后加上判断,如果格子的列的索引等于进入的格子的列的索引。就加上一个class,这里我用.cur-col。

代码如下

<!--遍历每一行-->
<div v-for="row,index in allNum" class="num-row clear">
 <!--遍历行里面的每一列-->
 <!--
  no:被掏空数组的样式
  cur:格子被点击时触发,被点击的格子样式
  cur-col:鼠标进入的时候触发,和被点击格子同一列的格子的样式
 -->
 <div v-for="num1,indexSub in row"
   :class="{'no':num1==='',
   'cur':curRow===index&&indexSub===curCol,
   'cur-col':hoverCol===indexSub}"
   @click="showCheck(index,indexSub)" @mouseenter="hoverCol=indexSub;" class="num-col">
  {{allNumText[index][indexSub]}}
 </div>
</div>

运行效果

利用vue开发一个所谓的数独方法实例

3-6.填写操作和错误提示

这一步的操作函数,我直接发代码吧,看代码比我说的会清晰些,毕竟说的有点绕

<!--遍历每一行-->
<div v-for="row,index in allNum" class="num-row clear">
 <!--遍历行里面的每一列-->
 <!--
  no:被掏空数组的样式
  cur:格子被点击时触发,被点击的格子样式
  cur-col:鼠标进入的时候触发,和被点击格子同一列的格子的样式
  err:填写错误的时候触发的样式
 -->
 <div v-for="num1,indexSub in row"
   :class="{'no':num1==='',
   'cur':curRow===index&&indexSub===curCol,
   'cur-col':hoverCol===indexSub,
   'err':(optionNow.x===index&&optionNow.y===indexSub)||(optionNowInRow.x===index&&optionNowInRow.y===indexSub)||(optionNowInCol.x===index&&optionNowInCol.y===indexSub)}"
   @click="showCheck(index,indexSub)" @mouseenter="hoverCol=indexSub;" class="num-col">
  {{allNumText[index][indexSub]}}
 </div>
</div>

js代码

inputText(_text){
 //*****************************检查前的初始化
 let _row = this.curRow, _col = this.curCol;
 this.curRow = '';
 this.curCol = '';
 this.isErr = false;
 this.optionNow = {
  x: '',
  y: '',
 }
 this.optionNowInRow = {
  x: '',
  y: '',
 }
 this.optionNowInCol = {
  x: '',
  y: '',
 }
 //*****************************检查行
 //根据当前格子进行赋值
 this.allNumText[_row][_col] = _text;
 let rowCheck = Object.assign(this.allNumText[_row], []);
 this.checkShow = false;
 for (let i = 0, len = rowCheck.length; i < len; i++) {
  //如果值一样,但是坐标不一样,就是填写错误
  if (_text === rowCheck[i] && _col !== i) {
   this.isErr = true;
   this.isShake = true;
   //记录当前格子的信息
   this.optionNow = {
    x: _row,
    y: _col,
   }
   //记录和当前格子同一行,以及同一个值的格子的坐标
   this.optionNowInRow = {
    x: _row,
    y: i,
   }
  }
 }
 //*****************************检查列
 let colCheck = [];
 //首先把每一行的那一列的数值保存起来
 for (let i = 0, len = this.allNumText.length; i < len; i++) {
  colCheck.push(this.allNumText[i][_col]);
 }
 //遍历检查
 for (let i = 0, len = colCheck.length; i < len; i++) {
  //如果值一样,但是坐标不一样,就是填写错误
  if (_text === colCheck[i] && _row !== i) {
   this.isErr = true;
   this.isShake = true;
   //记录和当前格子同一列,以及同一个值的格子的坐标
   this.optionNowInCol = {
    x: i,
    y: _col,
   }
  }
 }
 //如果发现的同样的
 if (this.isErr) {
  setTimeout(() => {
   this.isShake = false;
  }, 1000)
  return;
 }
 //如果数组去重后,长度小于9,就是行没完成
 rowCheck = rowCheck.filter(item => item !== '');
 if (rowCheck.length !== 9) {
  //console.log('行没完成')
  return;
 }
 let coloCheck = [];
 //如果数组去重后,长度小于9,就是列没完成
 for (let i = 0, len = this.allNumText.length; i < len; i++) {
  coloCheck = [...new Set(this.allNumText[i])];
  coloCheck = coloCheck.filter(item => item !== '');
  if (coloCheck.length !== 9) {
   //console.log('没完成')
   return;
  }
 }
 alert('挑战成功,但是没奖品');
 this.numShow = false;
}

利用vue开发一个所谓的数独方法实例

上面的代码逻辑,简单说下

1..err 这个class是设置红色字体所使用的,至于判断,就是在inputText这个函数里面,有optionNow和 optionNowInRow和optionNowInCol。只要格子的坐标等于三者其中之一,就会添加这个class,就会变红。

2..isShake这个class是控制,抖动的动画,添加上了之后,在一秒后,要去掉这个class,不然下次添加没有动画效果。

3.在inputText这个函数里面,我操作的数独列表,并不是之前,提到的allNum,而是利用allNum,深度拷贝生成出的allNumText(this.allNumText = JSON.parse(JSON.stringify(this.allNum));) 。主要就是为了避免下图的情况!

利用vue开发一个所谓的数独方法实例

这样是为了往掏空的格子输入数字的时候,然后那个格子就不能再改了,即使是填错了,都不能改。样式控制也不正确!正确的格式应该是下面这样,即使填入了,格子的样式还是灰色的,这样可以方便的知道哪个格子是当时被掏空的,填写错了,也是可以改的。

4.完整代码

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>vue-所谓的数独</title>
 <link rel="stylesheet" href="../../reset.css" rel="external nofollow" >
 <style>
  li{
   list-style-type: none;
  }
  .shake {
   animation: shake-opacity 500ms 1 ease-in-out;
  }
  @keyframes shake-opacity {
   0% {
    transform: translate(0px, 0px) rotate(0deg);
    opacity: 0.6;
   }
   10% {
    transform: translate(-2px, -1px) rotate(-0.5deg);
    opacity: 0.5;
   }
   20% {
    transform: translate(-4px, 4px) rotate(1.5deg);
    opacity: 0.4;
   }
   30% {
    transform: translate(-4px, -1px) rotate(-1.5deg);
    opacity: 0.8;
   }
   40% {
    transform: translate(-2px, -1px) rotate(-2.5deg);
    opacity: 0.3;
   }
   50% {
    transform: translate(-4px, 1px) rotate(-2.5deg);
    opacity: 0.5;
   }
   60% {
    transform: translate(-2px, 4px) rotate(0.5deg);
    opacity: 0.1;
   }
   70% {
    transform: translate(-3px, 1px) rotate(-0.5deg);
    opacity: 0.4;
   }
   80% {
    transform: translate(0px, 0px) rotate(-0.5deg);
    opacity: 0.5;
   }
   90% {
    transform: translate(2px, -1px) rotate(-2.5deg);
    opacity: 0.8;
   }
  }
  .num-box {
   margin: 0 auto;
   width: 540px;
   position: relative;
  }
  .num-box .num-check {
   position: absolute;
   width: 180px;
   box-shadow: 0 0 10px 0 #000;
   left: 0;
   top: 0;
  }
  .num-box .num-check li {
   box-sizing: border-box;
   float: left;
   background: #fff;
   color: #58B7FF;
   width: 60px;
   height: 60px;
   text-align: center;
   line-height: 60px;
   font-size: 24px;
   border: 1px solid #58B7FF;
   cursor: pointer;
   transition: all .5s;
  }
  .num-box .num-check li:hover {
   color: #fff;
   background: #58B7FF;
   border: 1px solid #fff;
  }
  .num-tips{
   color: #333;
   line-height: 32px;
   font-size: 16px;
  }
  .num-table{
   position: relative;
  }
  .num-row {
   font-size: 0;
  }
  .num-row:hover .num-col, .num-row:hover .num-col.no, .num-row:hover .num-col.cur-col {
   background: #0068b7;
  }
  .num-row .num-col {
   width: 60px;
   height: 60px;
   line-height: 60px;
   float: left;
   box-sizing: border-box;
   text-align: center;
   background: #58B7FF;
   color: #fff;
   font-size: 24px;
   font-weight: bold;
   border: 1px solid #ccc;
  }
  .num-row .num-col.no {
   background: #ccc;
   border: 1px solid #fff;
  }
  .num-row .num-col.err {
   color: #ff4949;
  }
  .num-row .num-col.cur-col {
   background: #0068b7;
  }
  .num-row .num-col.cur {
   background: #fff !important;
  }
 </style>
</head>
<body>
<div class="num-box" v-show="numShow" id="num">
 <div class="num-tips">
  <p>所谓的数独:规则</p>
  <p>1.每一行数字不重复</p>
  <p>2.每一列数字不重复</p>
 </div>
 <div class="num-table" @mouseleave="hoverCol=''" :class="{'shake':isShake}">
  <!--遍历每一行-->
  <div v-for="row,index in allNum" class="num-row clear">
   <!--遍历行里面的每一列-->
   <!--
    no:被掏空数组的样式
    cur:格子被点击时触发,被点击的格子样式
    cur-col:鼠标进入的时候触发,和被点击格子同一列的格子的样式
    err:填写错误的时候触发的样式
   -->
   <div v-for="num1,indexSub in row"
     :class="{'no':num1==='',
     'cur':curRow===index&&indexSub===curCol,
     'cur-col':hoverCol===indexSub,
     'err':(optionNow.x===index&&optionNow.y===indexSub)||(optionNowInRow.x===index&&optionNowInRow.y===indexSub)||(optionNowInCol.x===index&&optionNowInCol.y===indexSub)}"
     @click="showCheck(index,indexSub)" @mouseenter="hoverCol=indexSub;" class="num-col">
    {{allNumText[index][indexSub]}}
   </div>
  </div>
  <!--数字键盘-->
  <div class="num-check clear" :style="{'top':(curRow+1)*60+'px','left':(curCol+1)*60+'px'}"
    v-show="checkShow">
   <ul>
    <li @click="inputText(1)">1</li>
    <li @click="inputText(2)">2</li>
    <li @click="inputText(3)">3</li>
    <li @click="inputText(4)">4</li>
    <li @click="inputText(5)">5</li>
    <li @click="inputText(6)">6</li>
    <li @click="inputText(7)">7</li>
    <li @click="inputText(8)">8</li>
    <li @click="inputText(9)">9</li>
   </ul>
  </div>
 </div>
</div>
</body>
<script src="../vue.min.js"></script>
<script>
 new Vue({
  el:'#num',
  data:{
    name: 'welcome',
    testText: '欢迎来到',
    nowIndex: 0,
    allNum: [],//数字排列
    answer: [],//所有答案的坐标点
    allNumText: [],//数字,包括输入后的数字
    curRow: '',//当前格子所在的行的索引
    curCol: '',//当前格子所在的列的索引
    checkShow: false,//数字键盘的显示
    hoverCol: '',//鼠标进去的当前列
    hoverRow: 0,//鼠标进入的当前行
    numShow: true,//数独的显示
    optionNow: {},//输入后的格子的坐标
    optionNowInRow: {},//和输入后的格子在同一行,并且同样值的格子的坐标
    optionNowInCol: {},//和输入后的格子在同一列,并且同样值的格子的坐标
    isErr: false,//是否输入错误后
    isShake: false//是否显示震动的样式
  },
  methods: {
   /**
    * @description 显示数字键盘
    * @param i1
    * @param i2
    */
   showCheck(i1, i2){
    //点击的格子是否是被掏空的格子
    if (this.allNum[i1][i2] !== '') {
     return
    }
    //点击的格子如果是上一次点击的格子(当前格子)
    if (i1 === this.curRow && i2 === this.curCol) {
     //隐藏数字键盘,curRow和curCol设空
     this.checkShow = false;
     this.curRow = '';
     this.curCol = '';
    }
    else {
     //隐藏数字键盘,curRow和curCol分别设置成当前的点
     this.checkShow = true;
     this.curRow = i1;
     this.curCol = i2;
    }
   },
   inputText(_text){
    //*****************************检查前的初始化
    let _row = this.curRow, _col = this.curCol;
    this.curRow = '';
    this.curCol = '';
    this.isErr = false;
    this.optionNow = {
     x: '',
     y: '',
    }
    this.optionNowInRow = {
     x: '',
     y: '',
    }
    this.optionNowInCol = {
     x: '',
     y: '',
    }
    //*****************************检查行
    //保存当前格子的值
    this.allNumText[_row][_col] = _text;
    let rowCheck = Object.assign(this.allNumText[_row], []);
    this.checkShow = false;
    for (let i = 0, len = rowCheck.length; i < len; i++) {
     //如果值一样,但是坐标不一样,就是填写错误
     if (_text === rowCheck[i] && _col !== i) {
      this.isErr = true;
      this.isShake = true;
      //记录当前格子的信息
      this.optionNow = {
       x: _row,
       y: _col
      }
      //记录和当前格子同一行,以及同一个值的格子的坐标
      this.optionNowInRow = {
       x: _row,
       y: i
      }
     }
    }
    //*****************************检查列
    let colCheck = [];
    //首先把每一行的那一列的数值保存起来
    for (let i = 0, len = this.allNumText.length; i < len; i++) {
     colCheck.push(this.allNumText[i][_col]);
    }
    //遍历检查
    for (let i = 0, len = colCheck.length; i < len; i++) {
     //如果值一样,但是坐标不一样,就是填写错误
     if (_text === colCheck[i] && _row !== i) {
      this.isErr = true;
      this.isShake = true;
      //记录和当前格子同一列,以及同一个值的格子的坐标
      this.optionNowInCol = {
       x: i,
       y: _col
      }
     }
    }
    //如果发现的同样的
    if (this.isErr) {
     setTimeout(() => {
      this.isShake = false;
     }, 1000)
     return;
    }
    //如果数组去重后,长度小于9,就是行没完成
    rowCheck = rowCheck.filter(item => item !== '');
    if (rowCheck.length !== 9) {
     console.log('行没完成')
     return;
    }
    let coloCheck = [];
    //如果数组去重后,长度小于9,就是列没完成
    for (let i = 0, len = this.allNumText.length; i < len; i++) {
     coloCheck = [...new Set(this.allNumText[i])];
     coloCheck = coloCheck.filter(item => item !== '');
     if (coloCheck.length !== 9) {
      console.log('没完成')
      return;
     }
    }
    alert('挑战成功,但是没奖品');
    this.numShow = false;
   }
  },
  mounted(){
   let arr1 = [1, 2, 3, 4, 5, 6, 7, 8, 9];
   let row = [], rowCol = 0;
   for (let i = 0, len = arr1.length; i < len; i++) {
    row = Object.assign([], arr1);
    this.allNum.push(row);
    rowCol = arr1.splice(0, 1)[0];
    arr1.push(rowCol)
   }
   //打乱行
   this.allNum.sort((n1, n2) => Math.random() - 0.5);
   //随机获取两列的索引
   function randomText() {
    let rondomIndex = 0, rondomIndexAfter = 0;
    //获取第一列的索引
    rondomIndex = Math.floor(Math.random() * 9);
    function randomDo() {
     rondomIndexAfter = Math.floor(Math.random() * 9);
     //如果第一列和第二列索引一样,第二列的索引再次重新获取
     if (rondomIndexAfter === rondomIndex) {
      randomDo();
     }
    }
    randomDo();
    //返回两列的索引
    return [rondomIndex, rondomIndexAfter]
   }
   //打乱列
   let randomArr = [], nowValue = 0;
   //同样遍历9次
   for (let i = 0; i < 9; i++) {
    randomArr = Object.assign([], randomText());
    //遍历每一行,给每一行的随机两列交换值
    for (let j = 0, len = this.allNum.length; j < len; j++) {
     //随机两列交换值
     nowValue = this.allNum[j][randomArr[0]];
     this.allNum[j][randomArr[0]] = this.allNum[j][randomArr[1]];
     this.allNum[j][randomArr[1]] = nowValue;
    }
   }
   //记录所有坐标
   let rowText = '', arrText = []
   for (let i = 0; i < 9; i++) {
    rowText = ''
    for (let j = 0; j < 9; j++) {
     rowText += i + '-' + j + ',';
    }
    arrText.push(rowText.substr(0, rowText.length - 1))
   }
   console.log(arrText);
   //随机掏空
   let nowItme = [], _option, nowOption = [];
   for (let i = 0; i < 9; i++) {
    //抽取当前行的所有坐标
    nowItme = arrText[i].split(',');
    nowOption = [];
    //当前行的随机两个坐标掏空
    for (let j = 0; j < 2; j++) {
     //抽取当前行的随机一个坐标
     _option = Math.floor(Math.random() * nowItme.length);
     //分割坐标的x,y
     nowOption = nowItme.splice(_option,1)[0].split("-");
     this.allNum[nowOption[0]][nowOption[1]] = '';
    }
   }
   //深度拷贝数独的数字
   this.allNumText = JSON.parse(JSON.stringify(this.allNum));
  }
 })
</script>
</html>

reset.css和vue.min.js大家自行到github下载!

5.小结

好了,用vue做的所谓的数独,就写到这里了,主要就是逻辑有点绕,其它的问题相信都难不倒大家。这个实例比之前快速入门的三个小实例要麻烦一点,但是也很好理解!大家只要稍微看下估计都不难理解!最后,如果大家觉得文章写得不好,哪里写错了,欢迎给建议或者指点下迷津。期待和大家交流意见,共同进步!

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
List Installed Hot Fixes
Jun 12 Javascript
Ajax执行顺序流程及回调问题分析
Dec 10 Javascript
利用javascript实现禁用网页上所有文本框,下拉菜单,多行文本域
Dec 14 Javascript
解析JavaScript模仿块级作用域
Dec 29 Javascript
Angular如何引入第三方库的方法详解
Jul 13 Javascript
JavaSctit 利用FileReader和滤镜上传图片预览功能
Sep 05 Javascript
nuxt+axios解决前后端分离SSR的示例代码
Oct 24 Javascript
json数据传到前台并解析展示成列表的方法
Aug 06 Javascript
深入理解JavaScript 中的执行上下文和执行栈
Oct 23 Javascript
微信小程序淘宝首页双排图片布局排版代码(推荐)
Oct 29 Javascript
解决removeEventListener 无法清除监听的问题
Oct 30 Javascript
原生js实现自定义消息提示框
Nov 19 Javascript
开发Vue树形组件的示例代码
Dec 21 #Javascript
详解使用vuex进行菜单管理
Dec 21 #Javascript
Angular5.1新功能分享
Dec 21 #Javascript
vue2中的keep-alive使用总结及注意事项
Dec 21 #Javascript
webpack写jquery插件的环境配置
Dec 21 #jQuery
基于Vue 2.0的模块化前端 UI 组件库小结
Dec 21 #Javascript
使用Bootstrap4 + Vue2实现分页查询的示例代码
Dec 21 #Javascript
You might like
php+xml编程之xpath的应用实例
2015/01/24 PHP
php递归法读取目录及文件的方法
2015/01/30 PHP
CentOS7.0下安装PHP5.6.30服务的教程详解
2018/09/29 PHP
JS 判断代码全收集
2009/04/28 Javascript
基于jquery的弹出提示框始终处于窗口的居中位置(类似于alert弹出框的效果)
2011/09/28 Javascript
javascript中onmouse事件在div中失效问题的解决方法
2012/01/09 Javascript
mailto的使用技巧分享
2012/12/21 Javascript
JS获取月的最后一天与JS得到一个月份最大天数的实例代码
2013/12/16 Javascript
javascript获取form里的表单元素的示例代码
2014/02/14 Javascript
JS实现屏蔽shift,Ctrl,alt等功能键的方法
2015/06/01 Javascript
Bootstrap3制作自己的导航栏
2016/05/12 Javascript
Nodejs中Express 常用中间件 body-parser 实现解析
2017/05/22 NodeJs
jQuery实现腾讯信用界面(自制刻度尺)样式
2017/08/15 jQuery
微信小程序实现城市列表选择
2018/06/05 Javascript
小程序实现分类页
2019/07/12 Javascript
JS实现简单tab选项卡切换
2019/10/25 Javascript
pyQt4实现俄罗斯方块游戏
2018/06/26 Python
Python2和Python3.6环境解决共存问题
2018/11/09 Python
使用APScheduler3.0.1 实现定时任务的方法
2019/07/22 Python
python函数参数(必须参数、可变参数、关键字参数)
2019/08/16 Python
YUV转为jpg图像的实现
2019/12/09 Python
MNIST数据集转化为二维图片的实现示例
2020/01/10 Python
django迁移文件migrations的实现
2020/03/31 Python
pandas.DataFrame.drop_duplicates 用法介绍
2020/07/06 Python
Python图像识别+KNN求解数独的实现
2020/11/13 Python
南非领先的在线旅行社:Travelstart南非
2016/09/04 全球购物
翻新二手苹果产品的网络领导者:Mac of all Trades
2017/12/19 全球购物
外包公司软件测试工程师
2014/11/01 面试题
机电专业毕业生推荐信
2013/11/10 职场文书
留学推荐信写作指南
2014/01/25 职场文书
30年同学聚会邀请函
2014/01/25 职场文书
绘画专业自荐信
2014/07/04 职场文书
王兆力在市委党的群众路线教育实践活动总结大会上的讲话稿
2014/10/25 职场文书
小学国庆节活动总结
2015/03/23 职场文书
大一新生军训新闻稿
2015/07/17 职场文书
详细谈谈JavaScript中循环之间的差异
2021/08/23 Javascript