vue学习记录 3

近日笔记简写。


 

功能实现汇总


 

页面循环次数创建控件:制作一个11行11列的表格,用v-for实现。

    <table>
      <tr v-for="index_y in 11" :key="index_y">
        <td colspan="1" v-for="index_x in 11" :key="index_x"></td>
      </tr>
    </table>

 

制作一个可以点击后改变颜色的按钮:temple需要设置class和@click,script在methods里写事件,style写切换类。

<template>
  <div class="hello">
    <button
      class="btn1"
      @click="btn1data()"
      :class="showmode ? 'active' : 'btn1'"
    >
      按钮1
    </button>
  </div>
</template>

<script>
export default {
  data () {
    return {
      msg: 'Welcome to Vue.js App: Winmine',
      showmode: true
    }
  },
  methods: {
    btn1data () {
      this.showmode = !(this.showmode)
    }
  }
}
</script>

<style scoped>
.btn1 {
  width: 140px;
  height: 40px;
  border: 1px solid #d9d9d9;
  border: 0;
  outline: none;
}
.btn1.active {
  background: green;
}
</style>

 

组件父传子:props

<!-- 根组件 -->
<template>
  <div><!-- ...... -->
    <game-page v-if="showGame" :game-info="gameInfo"></game-page>
  <!-- ...... --></div>
</template>

<script>
import GamePage from '@/components/GamePage.vue'
export default {
  components: {
    GamePage
  },
  data () {  // 搁父组件参数
    return {
      gameInfo: [8, 8, 10]
    }
  },
  methods: {  // 搁父组件函数
    //..............
  }
}
</script>
<!-- 子组件 -->
<template>
  <div>
    <div>地雷数:{{ num }}</div>
    <div>地雷数:{{ gameInfo }}</div>
  </div>
</template>
<!-- 函数调用也一样,直接用名字 -->
<script>
export default {
  props: ['gameInfo'],
  data () {
    return {
      rows: this.gameInfo[0],
      cols: this.gameInfo[1],
      num: this.gameInfo[2]
    }
  }
}
</script>

 

组件子传父:$emit

<!-- 根组件 -->
<template>
  <div><!-- -->
    <game-page @back-chose="backChose"></game-page>
  <!-- --></div>
</template>

<script>
import GamePage from '@/components/GamePage.vue'
export default {
  components: {
    GamePage
  },
  data () { // 搁父组件参数
    return {}
  },
  methods: {  // 搁父组件函数
    backChose () {
      //............
    }
  }
}
</script>
<!-- 子组件 -->
<template>
  <div>
    <button @click="showDangers()">查看地雷</button>
  </div>
</template>

<script>
export default {
  data () {
    return {}
  },
  methods: {
    backPage () {
      this.$emit('back-chose')
    }
  }
}
</script>

 

列表绑数据:

<template>
  <div>
    <div>选择难度</div>
    <ul>
      <li v-for="(item, index) in level" :key="index" @click="handlelevel(item.value)">
      {{ item.text }}
    </li>
    </ul>
  </div>
</template>

<script>
export default {
  data () {
    return {
      level: [
        {
          text: '简单',
          value: [9, 9, 10]
        }, {
          text: '困难',
          value: [16, 16, 50]
        }
      ]
    }
  },
  methods: {
    handlelevel (level) {
      console.log('set', level)
    }
  }
}
</script>

 

assets图片资源调用:

<!-- 普通路径调用 -->
<img :src="require('../assets/null.png')"/>
<!-- 加参选择文件调用:${value} 为变量 -->
<img :src="require(`../assets/cell${value}.png`)"/>

 

v-for双层循环且绑定对象,v-if / v-else-if / v-else筛条件显示:

 1     <div class="board">
 2     <!-- for 行 -->
 3       <div v-for="(row, rowIndex) in board" :key="rowIndex"
 4       class="row">
 5     <!-- for 列-->
 6         <div v-for="(cell, cellIndex) in row" :key="cellIndex"
 7         :class="[{ opened: cell.opened }, `cell-${cell.value}`]"
 8         @click="clickCell(rowIndex, cellIndex)">
 9     <!-- for内 v-if -->
10           <span v-if="cell.opened && cell.value !== 'mine'">
11             <img :src="require(`../assets/cell${cell.value}.png`)"/>
12           </span>
13     <!-- for内 v-else-if -->
14           <span v-else-if="cell.opened">
15             <img :src="require('../assets/mine.png')"/>
16           </span>
17     <!-- for内 v-else -->
18           <span v-else>
19             <img :src="require('../assets/null.png')"/>
20           </span>
21         </div>
22     <!-- for 列 结束-->
23       </div>
24     <!-- for 行 结束-->
25     </div>

 

data写了对象但是没写属性,没关系:

<script>
export default {
  data () {
    return {
      board: []
    }
  },
  methods: {
    initGame () {
      for (let i = 0; i < this.rows; i++) {
        const row = []
        for (let j = 0; j < this.cols; j++) {
          row.push({value: '', opened: false, flagged: false})
        }
        this.board.push(row)
        // board其实是二维list
        // 如果只有一层for,board就是一维list
      }
    }
}
</script>

 

methods中关于随机数生成: (0~n):Math.floor(Math.random() * n) 

methods中,对扫雷游戏rows*cols规格棋盘随机生成num个地雷:

getMines () {
  let cnt = 0
  while (cnt < this.num) {
    const row = Math.floor(Math.random() * this.rows)
    const col = Math.floor(Math.random() * this.cols)
    if (!this.board[row][col].value) {
      this.board[row][col].value = 'mine'
      cnt++
    }
  }
}

 

页面警告(methods函数内): alert('You Game Over') 

 

增加按键右键事件:

<template>
  <div class="cell"
       @contextmenu.prevent="onRightClick">
  </div>
</template>
<script>
export default {
  methods: {
    onRightClick(event) {
      // TODO
    }
  }
}
</script>

 



 

新建项目后清空自带页面,并自建内容 教程参考网址: 

https://blog.csdn.net/Tsailing666/article/details/127954443

需求目录:(非必需)

 1 api
 2 assets
 3 components
 4 icons
 5 layout
 6 router
 7 store
 8 styles
 9 utils
10 views
src文件夹目录

 



 

简单的扫雷功能实现:(包括难度选择/插旗判断/点周围无雷扩散格子)

涉及目录及文件:其他的都不用动

<<src
--|<<assets
--|--|<<cell0.png......<<cell8.png
--|--|<<flag.png
--|--|<<mine.png
--|--|<<null.png
--|<<components
--|--|<<GamePage.vue
--|--|<<SelectLevel.vue
--|<<App.vue

App.vue:

 1 <!-- 根组件 -->
 2 <template>
 3   <div id="app">
 4     helloworld-vue
 5     <!-- 游戏盘 v-if判断showGame,是的话就展示 -->
 6     <game-page
 7     v-if="showGame"
 8     :game-info="gameInfo"
 9     @back-chose="backChose"></game-page>
10     <!-- 难度选择框,带参函数但是此处不需要写参 -->
11     <select-level
12     v-else
13     @chose-level="choseLevel"></select-level>
14   </div>
15 </template>
16 
17 <script>
18 // import 子组件 from 路径
19 import SelectLevel from '@/components/SelectLevel.vue'
20 import GamePage from '@/components/GamePage.vue'
21 export default {
22   name: 'App',
23   // 增加子组件
24   components: {
25     GamePage,
26     SelectLevel
27   },
28   // 搁本组件参数
29   data () {
30     return {
31       showGame: false,
32       gameInfo: [8, 8, 10]
33     }
34   },
35   // 搁本组件函数
36   methods: {
37     choseLevel (level) {
38       this.gameInfo = level
39       this.showGame = true
40       console.log('get', level)
41     },
42     backChose () {
43       this.showGame = false
44     }
45   }
46 }
47 </script>
48 
49 <style>
50 #app {
51   font-family: 'Avenir', Helvetica, Arial, sans-serif;
52   -webkit-font-smoothing: antialiased;
53   -moz-osx-font-smoothing: grayscale;
54   text-align: center;
55   color: #2c3e50;
56   margin-top: 60px;
57 }
58 </style>
App.vue

SelectLevel.vue

 1 <!-- 选择难度组件 -->
 2 <template>
 3   <div>
 4     <div>选择难度</div>
 5     <ul>
 6       <li
 7       v-for="(item, index) in level" :key="index"
 8       @click="handlelevel(item.value)">
 9       {{ item.text }}
10     </li>
11     </ul>
12   </div>
13 </template>
14 
15 <script>
16 export default {
17   name: 'index',
18   data () {
19     return {
20       level: [
21         {
22           text: '简单',
23           value: [9, 9, 10]
24         }, {
25           text: '困难',
26           value: [16, 16, 50]
27         }
28       ]
29     }
30   },
31   methods: {
32     handlelevel (level) {
33       this.$emit('chose-level', level)
34       console.log('set', level)
35     }
36   }
37 }
38 </script>
39 
40 <style scoped>
41 ul {
42     list-style-type: none;
43     padding: 0;
44 }
45 li {
46     display: inline-block;
47     margin: 20px;
48     border-width: 0.1cm;
49     border-color: rgb(15, 75, 15);
50     background: rgb(147, 234, 147);
51     width: 1.8cm;
52 }
53 </style>
SelectLevel.vue

GamePage.vue

  1 <!-- 游戏界面组件 -->
  2 <template>
  3   <div>
  4     <button @click="backPage()">返回主页</button>
  5     <button @click="showDangers()">查看地雷</button>
  6     <button @click="resetGame()">重新开始</button>
  7     <div>地雷数:{{ num }}</div>
  8     <div class="board">
  9       <div
 10       v-for="(row, rowIndex) in board" :key="rowIndex"
 11       class="row">
 12         <div
 13         v-for="(cell, cellIndex) in row" :key="cellIndex"
 14         :class="[{ opened: cell.opened }, `cell-${cell.value}`]"
 15         @click="clickCell(rowIndex, cellIndex)"
 16         @contextmenu.prevent="onRightClick(rowIndex, cellIndex)">
 17           <span v-if="cell.flagged">
 18             <img :src="require('../assets/flag.png')"/>
 19           </span>
 20           <span v-else-if="cell.opened && cell.value !== 'mine'">
 21             <img :src="require(`../assets/cell${cell.value}.png`)"/>
 22           </span>
 23           <span v-else-if="cell.opened">
 24             <img :src="require('../assets/mine.png')"/>
 25           </span>
 26           <span v-else>
 27             <img :src="require('../assets/null.png')"/>
 28           </span>
 29         </div>
 30       </div>
 31     </div>
 32   </div>
 33 </template>
 34 
 35 <script>
 36 export default {
 37   props: ['gameInfo'],
 38   data () {
 39     return {
 40       rows: this.gameInfo[0],
 41       cols: this.gameInfo[1],
 42       num: this.gameInfo[2],
 43       board: [],
 44       gameover: false
 45     }
 46   },
 47   created () {
 48     this.initGame()
 49   },
 50   methods: {
 51     onRightClick (row, col) {
 52       console.log('onRightClick')
 53       // Event.preventDefault()
 54       this.board[row][col].flagged = !this.board[row][col].flagged
 55       this.checkWin()
 56     },
 57     initGame () {
 58       for (let i = 0; i < this.rows; i++) {
 59         const row = []
 60         for (let j = 0; j < this.cols; j++) {
 61           row.push({value: '', opened: false, flagged: false})
 62         }
 63         this.board.push(row)
 64       }
 65       this.getMines()
 66       this.calculateMines()
 67     },
 68     getMines () {
 69       let cnt = 0
 70       while (cnt < this.num) {
 71         const row = Math.floor(Math.random() * this.rows)
 72         const col = Math.floor(Math.random() * this.cols)
 73         if (!this.board[row][col].value) {
 74           this.board[row][col].value = 'mine'
 75           cnt++
 76         }
 77       }
 78     },
 79     calculateMines () {
 80       for (let i = 0; i < this.rows; i++) {
 81         for (let j = 0; j < this.cols; j++) {
 82           if (this.board[i][j].value !== 'mine') {
 83             let cnt = 0
 84             // 上3
 85             if (i > 0 && j > 0 && this.board[i - 1][j - 1].value === 'mine') cnt++
 86             if (i > 0 && this.board[i - 1][j].value === 'mine') cnt++
 87             if (i > 0 && j < this.cols - 1 && this.board[i - 1][j + 1].value === 'mine') cnt++
 88             // 中2
 89             if (j > 0 && this.board[i][j - 1].value === 'mine') cnt++
 90             if (j < this.cols - 1 && this.board[i][j + 1].value === 'mine') cnt++
 91             // 下3
 92             if (i < this.rows - 1 && j > 0 && this.board[i + 1][j - 1].value === 'mine') cnt++
 93             if (i < this.rows - 1 && this.board[i + 1][j].value === 'mine') cnt++
 94             if (i < this.rows - 1 && j < this.cols - 1 && this.board[i + 1][j + 1].value === 'mine') cnt++
 95             // end
 96             this.board[i][j].value = cnt
 97           }
 98         }
 99       }
100     },
101     clickCell (row, col) {
102       if (this.gameover) return
103       const cell = this.board[row][col]
104       if (cell.opened || cell.flagged) return
105       cell.opened = true
106       if (cell.value === 'mine') {
107         this.gameover = true
108         this.showDangers()
109       } else if (cell.value === 0) {
110         this.openCell(row, col)
111       }
112       if (this.checkWin()) {
113         this.gameover = true
114       }
115     },
116     openCell (row, col) {
117       if (row > 0 && col > 0) {
118         this.clickCell(row - 1, col - 1)
119       }
120       if (row > 0) {
121         this.clickCell(row - 1, col)
122       }
123       if (row > 0 && col < this.cols - 1) {
124         this.clickCell(row - 1, col + 1)
125       }
126       if (col > 0) {
127         this.clickCell(row, col - 1)
128       }
129       if (col < this.cols - 1) {
130         this.clickCell(row, col + 1)
131       }
132       if (row < this.rows - 1 && col > 0) {
133         this.clickCell(row + 1, col - 1)
134       }
135       if (row < this.rows - 1) {
136         this.clickCell(row + 1, col)
137       }
138       if (row < this.rows - 1 && col < this.cols - 1) {
139         this.clickCell(row + 1, col + 1)
140       }
141     },
142     checkWin () {
143       let clickcnt = 0
144       for (let i = 0; i < this.rows; i++) {
145         for (let j = 0; j < this.cols; j++) {
146           // 点开格子且格子有雷
147           if (this.board[i][j].opened) {
148             clickcnt++
149             if (this.board[i][j].value === 'mine') {
150               alert('You Game Over')
151               return false
152             }
153           }
154           // 镖旗但没雷
155           if (this.board[i][j].flagged) {
156             clickcnt++
157             if (this.board[i][j].value !== 'mine') {
158               alert('You Game Over')
159               return false
160             }
161           }
162         }
163       }
164       if (clickcnt === this.rows * this.cols) {
165         // 所有格子都点过且没踩雷
166         alert('You Win! Good job!')
167         return true
168       }
169       return false
170     },
171     resetGame () {
172       this.board = []
173       this.gameover = false
174       this.initGame()
175     },
176     showDangers () {
177       for (let i = 0; i < this.rows; i++) {
178         for (let j = 0; j < this.cols; j++) {
179           this.board[i][j].opened = true
180         }
181       }
182     },
183     backPage () {
184       this.$emit('back-chose')
185     }
186   }
187 }
188 </script>
189 
190 <style scoped>
191 button {
192     background-color: lightgreen;
193     color: white;
194     border-color: white;
195     margin: 0.5cm;
196     width: 3cm;
197     height: 1.2cm;
198 }
199 .board {
200   background-color: lightgreen;
201   display: inline-block;
202   border: 10px solid lightgreen;
203   margin: 10px;
204 }
205 .row {
206   display: flex;
207 }
208 img {
209   width: 30px;
210   height: 30px;
211 }
212 </style>
GamePage.vue

 

参考的资料比较多,甚至有问GPT机器人解决的。机器人也有点坑,比如右键事件给了我一个写了会报错的函数。现在算是入门了。

接下来几天研究线程和数据库。打算写个简单的书籍管理系统。

 

posted @ 2023-06-14 14:49  yyn工作号  阅读(24)  评论(0)    收藏  举报