Разработайте так называемую судоку с помощью vue.

JavaScript Vue.js CSS

1. Введение

Недавняя страница системы управления фоном, нового спроса на функцию нет, я думал о том, что разместить на главной странице Недавно я подумал о том, чтобы поставить так называемую судоку, почему она называется судоку, потому что правила разные из стандартного судоку, просто требуйте, чтобы каждая строка и каждый столбец имели разные числа! Этот пример также основан на Vue, и код предоставлен вам. Код для всех заключается не в том, чтобы позволить всем копировать код напрямую, а в том, чтобы каждый относился к нему как к практическому проекту или изучению знаний. Если вы считаете, что я написал плохо или неправильно, пожалуйста, укажите на это, чтобы все могли обменяться мнениями и вместе добиться прогресса. Код выложен на гитхаб: можете поставить звездочку, если нужно!vue-demos

2. Эффект операции

3. Этапы реализации

Шаги реализации кажутся немного запутанными, рекомендуется читать статью во время написания, чтобы не запутаться. Или перейти непосредственно к исходному коду (sudoku), читайте исходный код! Этот проект тоже не сложный!

3-1. Подготовьте данные и макет

Напечатаетhtml+cssПро код много говорить не буду, раскладка очень простая, думаю это не составит труда для всех. Чуть сложнее взаимодействие данных!
Давайте начнем первый шаг. Сначала подготовьте данные судоку. Все знают, что это за данные. Это данные, подобные следующим!

Эффект набора текста заключается в следующем.

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

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

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

Увидев эту координату, вы можете легко понять, что элемент массива является первой строкой, '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]] = '';
    }

}

Я считаю, что все думают, что это странно.Следующий стиль должен быть написан, который должен изменить стиль пустой сетки!.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>

3-4 Отображение цифровой клавиатуры

Прежде всего, я просто использую блок-схему для объяснения логики следующим образом.

Тогда о положении цифровой клавиатуры см. рисунок ниже (я не буду много говорить о стиле цифровой клавиатуры, одно относительное позиционирование, а другое абсолютное позиционирование)

Как показано на картинке выше, я нажал на третью сетку в первом ряду. Прежде всего, я ожидаю, что изменится стиль нажатой сетки, чтобы я мог ее различить. Это не сложно, просто используйтеclassВы можете изменить стиль, это видно в следующем коде, я использую.curизclassСтиль управления. Другой — ожидать, что цифровая клавиатура появится во втором ряду и четвертой сетке. В этом случае все будут знать, как позиционируется цифровая клавиатура! цифровая клавиатураtopТо есть индекс строки, где находится кликнутая сетка +1

60 (60 — ширина и высота сетки),leftТо есть индекс столбца, где находится нажатая сетка +1
60 (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;
    }
},

текущий результат

3-5.Выделите ту же строку в той же строке

Этот шаг очень простой, в первую очередь выделяем строку, как это сделать знают все, то есть строка соответствуетdiv, установить:hover, а затем установите соответствующий стиль ячейки! Об этом много не скажешь!

Затем выделите столбец, что немного сложнее, но тоже очень просто.Я думаю, всем известен принцип, то есть, когда мышь входит в сетку,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>

текущий результат

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

Приведенная выше логика кода, кратко

1..errЭтот класс используется для установки красного шрифта.Что касается суждения, то оно вinputTextВ этой функции естьoptionNowа такжеoptionNowInRowа такжеoptionNowInCol. Пока координаты сетки равны одному из трех, класс будет добавлен, и он станет красным.
2..isShakeЭтот класс - анимация управления и тряски, после добавления необходимо удалить этот класс через одну секунду, иначе при следующем добавлении эффекта анимации не будет.
3. ВinputTextВ этой функции список судоку, с которым я работаю, отличается от упомянутого ранее.allNum, но используяallNum, сгенерированный глубокой копией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">
    <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.Основная причина в том, что логика немного запутана.Я думаю, что другие задачи не вызовут у всех затруднений. Этот пример немного более громоздкий, чем три небольших примера из предыдущего краткого руководства, но его также легко понять! Всем нетрудно понять, если немного присмотреться! Наконец, если вы считаете, что статья написана не очень хорошо или что-то не так, вы можете высказать свои предложения или указания. Будем рады обменяться с вами мнениями и вместе добиться прогресса!



------------------------- Великолепная разделительная линия --------------------
Хотите узнать больше, обратите внимание на мой публичный аккаунт WeChat: В ожидании книжного магазина