allNumText(this.allNumText = JSON.parse(JSON.stringify(this.allNum));)
。主要就是为了避免下图的情况!
这样是为了往掏空的格子输入数字的时候,然后那个格子就不能再改了,即使是填错了,都不能改。样式控制也不正确!正确的格式应该是下面这样,即使填入了,格子的样式还是灰色的,这样可以方便的知道哪个格子是当时被掏空的,填写错了,也是可以改的。
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>
内容版权声明:除非注明,否则皆为本站原创文章。