为了账号安全,请及时绑定邮箱和手机立即绑定

用vue开发一个所谓的数独

标签:
Vue.js

1.前言

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

2.运行效果

https://img1.sycdn.imooc.com//5b5068980001598905380538.jpg

3.实现步骤

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

3-1.准备数据和排版

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

https://img1.sycdn.imooc.com//5b5068b600014a6604000136.jpg

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

https://img1.sycdn.imooc.com//5b506938000150cb05770559.jpg

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);

https://img1.sycdn.imooc.com//5b50694f0001346a06120576.jpg

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;     } }

https://img1.sycdn.imooc.com//5b506967000160e306020565.jpg

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);

https://img1.sycdn.imooc.com//5b5069880001908c03280137.jpg

看到这个坐标,大家很容易的知道,数组的一个元素,就是第一行,‘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]] = '';     } }

https://img1.sycdn.imooc.com//5b50699b0001cbe705580558.jpg

这样相信大家都觉得奇怪,下面进行下样式的该写,就是把设空了的格子的样式改一下!.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>

https://img1.sycdn.imooc.com//5b5069ae0001240e05530555.jpg

3-4.显示数字键盘

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

https://img1.sycdn.imooc.com//5b5069c40001390605820527.jpg

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

https://img1.sycdn.imooc.com//5b5069d300013a7005570558.jpg

如上图,我点击的是第一行第三个格子,首先,我期待被点击的格子的样式有所改变,方便我区分,这个不难,用一个class改变样式就可以了,这个可以看下面的代码,我用一个.curclass控制样式。还有一个就是期待数字键盘在第二行,第四个格子那里出现。这样的话,大家就知道,数字键盘的位置是怎么定位的了!数字键盘的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;     } },

运行效果

https://img1.sycdn.imooc.com//5b5069e90001db2905700566.jpg

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

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

https://img1.sycdn.imooc.com//5b5069fd00011dfe08000192.jpg

然后,高亮显示列,复杂一点,但是也很简单,原理我想大家也知道,就是当鼠标进如格子的时候,在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>

运行效果

https://img1.sycdn.imooc.com//5b506a0d0001139705680554.jpg

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; }

https://img1.sycdn.imooc.com//5b506a220001944305380579.jpg

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

1..err 这个class是设置红色字体所使用的,至于判断,就是在inputText这个函数里面,有optionNowoptionNowInRowoptionNowInCol。只要格子的坐标等于三者其中之一,就会添加这个class,就会变红。
2..isShake这个class是控制,抖动的动画,添加上了之后,在一秒后,要去掉这个class,不然下次添加没有动画效果。
3.在inputText这个函数里面,我操作的数独列表,并不是之前,提到的allNum,而是利用allNum,深度拷贝生成出的allNumTextthis.allNumText = JSON.parse(JSON.stringify(this.allNum));)。主要就是为了避免下图的情况!

https://img1.sycdn.imooc.com//5b500d220001e7a805710538.jpg

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

4.完整代码

<!DOCTYPE html> <html> <head>     <meta charset="UTF-8">     <title>vue-所谓的数独</title>     <link rel="stylesheet" href="../../reset.css">     <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 class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="../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.cssvue.min.js大家自行到github下载!

5.小结

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


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
Web前端工程师
手记
粉丝
1.7万
获赞与收藏
966

关注作者,订阅最新文章

阅读免费教程

  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消