美文网首页饥人谷技术博客
使用Vue CLI脚手架一键搭建项目——井字棋

使用Vue CLI脚手架一键搭建项目——井字棋

作者: PingerL | 来源:发表于2019-11-07 13:07 被阅读0次

    3×3连子棋(也叫做井字棋)其实还并不算复杂,3×3的棋盘最多可以放9个棋子,一旦有一方连成三子,则此局棋结束。现使用Vue.js来使用Vue CLI搭建井字棋项目,并将其发布到github上

    井字棋项目预览链接

    一:需要用到的工具

    Node.js、Vue CLI、VScode

    二:项目搭建

    1. 搭建好项目原型后,将项目拖入VScode中:
    项目初始结构如下: 屏幕快照 2019-11-06 下午7.13.50.png
    2. 打开src目录下的App.vue,清空里面的内容,只保留如下结构,我们可以在标签template中写html结构,script标签中写 js代码,在style标签中写css代码
    <template>
        
    </template>>
    <script>
    export default {
        
    }
    </script>
    <style>
    </style>
    
    3. 在src目录下新建一个Cell.vue,创建井字格组件

    实现的功能:点击井字格,切换格子里的棋子x0
    主要点:条件渲染v-if,v-else;事件处理v-on,简写为@

    <template>
      <div class="cell" @click="change">
        <template v-if="a">x</template>
        <template v-else>o</template>
      </div>
    </template>
    <script>
    export default {
      data(){
        return {
          a: false
        }
      },
      methods:{
        change(){
          this.a = !this.a
        }
      }
    }
    </script>
    
    
    4. 将Cell.vue引入App.vue中,打开App.vue,

    主要点:在 模块系统中局部注册组件import xx from './xx',components{xx}
    此时,我们就可以在App模版中使用Cell组件了

    <template>
      <Cell></Cell>
    </template>
    <script>
    import Cell from './Cell'
    export default {
      components:{Cell}
    }
    </script>
    
    5. 创建完整的井字棋结构,3*3结构

    坑:不能直接在template中直接复用多个Cell,会报Component template should contain exactly one root element这样的错误,此时我们应该用一个元素将他们包裹起来

    //错误写法
    <template>
      <Cell></Cell>
      <Cell></Cell>
      <Cell></Cell>
      <Cell></Cell>
    </template>
    //正确写法
    <template>
      <div class="container">
        <div class="row">
          <Cell />
          <Cell />
          <Cell />
        </div>
        ...
      </div>
    </template>
    ...
    
    此时页面展示的如下图 屏幕快照 2019-11-06 下午9.02.38.png
    6. 我们希望点击的时候再出现ox

    实现思路:在 App中设置一个参数n,每点击一次格子则n加1,再将n传到组件Cell中,判断此时n的值为奇数还是偶数,偶数时格子中显示x,奇数时显示o
    主要点:父子组件中传递参数,
    父组件 to 子组件:父组件v-bind:n="n",@click="cellClick" 子组件:props:['n']
    子组件 to 父组件:子组件:this.$emit('xxx',data),父组件:<Cell @click="cellClick($event)" />

    // App.vue
    <template>
      <div class="container">
        <div class="row">
          <Cell :n="n" @click="cellClick" />
          <Cell :n="n" @click="cellClick" />
          <Cell :n="n" @click="cellClick" />
        </div>
       ...
      </div>
    </template>
    <script>
    import Cell from './Cell'
    export default {
      components:{Cell},
      data(){
        return {
          n:0
        }
      },
      methods: {
        cellClick(){
          this.n += 1
        }
      }
    }
    </script>
    
    //Cell.vue
    <template>
      <div class="cell" @click="change">
        <template v-if="a">{{text}}</template>
        <template v-else></template>
      </div>
    </template>
    <script>
    export default {
      props:['n'],
      data(){
        return {
          a: false,
          text:''
        }
      },
      methods:{
        change(){
          this.a = true
          if(this.text !== '') return //点击过的格子不能再点击
        //   console.log(this.n)
          this.text = this.n % 2 === 0? 'x':'o'
          this.$emit('click')
        }
      }
    }
    </script>
    

    此时,大概完成了井字棋的雏型,点击格子轮流切换棋子

    7. 判断输赢

    思路:将点击过的格子里的值用3x3的数组记录下来,再判断数组相关值是否相等,相等则游戏结束。游戏结束,则重新渲染页面,开始新一轮游戏
    主要点:1. 子组件向父组件传递参数 2. 游戏胜利的条件判断 3. 游戏结束后如何重新渲染页面this.$nextTick()

    //App.vue
    <template>
      <div class="container">
        <div>第{{n}}手</div>
        <div class="row">
          <Cell :n="n"  @click="cellClick(0,$event)" v-if="update"/>
          ...
        </div>
        ...
    </template>
    <script>
    import Cell from './Cell'
    export default {
      components:{Cell},
      data(){
        return {
          n:0,
          result:'',
          update:true, //用来判断组件页面重新渲染与否
          isend: false, //用来判断是游戏是否结束
          map:[[null,null,null],[null,null,null],[null,null,null]]
        }
      },
      methods: {
        cellClick(i,text){
          this.n += 1
          this.map[Math.floor(i/3)][i%3] = text
          this.win()
          this.isended()
        },
        win(){
         ...
        },
        isended(){
          ...
            }
    
        },
        reload() {
       ...
        }
    }
    </script>
    
    8. 将项目部署到 github上
    • 手动推送更新
      在 vue.config.js 中设置正确的 publicPath。
    • 如果打算将项目部署到 https://<USERNAME>.github.io/上,publicPath将默认被设为 "/",你可以忽略这个参数。
    • 如果打算将项目部署到https://<USERNAME>.github.io/<REPO>/上 (即仓库地址为https://github.com/<USERNAME>/<REPO>),可将 publicPath设为 "/<REPO>/"。举个例子,如果仓库名字为“my-project”,那么vue.config.js 的内容应如下所示:
    module.exports = {
      publicPath: process.env.NODE_ENV === 'production'
        ? '/my-project/'
        : '/'
    }
    
    9. 具体部署
      1. 新建一个名为vue.config.js的文件,文件内容为:
    module.exports = {
      publicPath: process.env.NODE_ENV === 'production'
        ? '/Tic-Tac-Toe/dist/'
        : '/'
    }
    
      1. 将文件build,npm run build完成后会自动生成一个dist文件夹(dist文件夹用于存放编译后用于发布的线上代码),完成后我们将dist文件夹上传到github上Tic-Tac-Toe上即可

    三:总结,遇到的坑

    1. 游戏结束时,我想使用alert函数来通知游戏结束,没想到先弹出来alert,后才在页面上渲染最后一颗棋子
    • 原因:div加载到页面需要时间,还没等加载到页面就执行到alert了,此时alert会阻塞线程,这里阻塞的是GUI渲染线程.所以等alert执行完毕后这个线程才会继续执行,将div内容显示到页面上
    • 解决办法:给把alert放进setTimeout中去执行
    1. 好,我想alert后页面重新渲染,添加 this.reload()函数。什么?函数未定义?
    • 原因,setTmeout里的this指向的是window
    • 解决办法,先在外层赋值let _this = this,再在setTimeout内部调用_this.reload()
    1. 啥,为什么我的reload函数明明执行里,页面却没有重新渲染?
    • 原因,粗心忘记在组件上使用v-if=Boolean来控制页面了,加上
    • <Cell :n="n" @click="cellClick(0,$event)" v-if="update"/>
    1. 要点:
      a)父子组件间相互传值
      b)页面重新渲染: data重置,$nextTick()函数的使用
      c)各种条件的设置与判断

    具体代码:见我的github=======https://github.com/PingerL/Tic-Tac-Toe

    PS :项目的具体创建

    1. 在官网下载对应版本的Node.js,下载完后常规安装,打开终端,运行node -v来查看是否安装成功,若安装成功会显示对应的版本号
      屏幕快照 2019-11-06 下午6.41.59.png
    2. 全局安装CLI,在终端里运行命令sudo npm install -g @vue/cli
    3. 进入到要创建的文件夹的目录,比如我要创建的文件放在在桌面上名为89的文件夹下:cd /Users/PingerL/Desktop/89
    4. 在当前文件夹下创建一个项目,项目名为demovue1,运行指令:vue create demovue1,选择默认方式创建,至此就创建好了一个项目的原型,具体创建可参考官网

    相关文章

      网友评论

        本文标题:使用Vue CLI脚手架一键搭建项目——井字棋

        本文链接:https://www.haomeiwen.com/subject/kqgebctx.html