美文网首页Vue
Vue搭建的小项目(学习)

Vue搭建的小项目(学习)

作者: 区块链0 | 来源:发表于2019-03-15 14:59 被阅读3次

    用Vue搭建项目--小博彩(详)

    一:项目环境准备

    1. 项目目录结构准备

    (1)搭建脚手架

    npm install -g vue-cli
    复制代码
    

    (2)一定要在当前的目录结构下输入

    vue init webpack 目录名
    
    ?Project name lottery
    ?Project description this is a niubility project
    ?Author xiaokaikai
    ?Vue build (选择一种构建的形式)
    > Runtime + Compiler: recommended for most users
    ?Install vue-router?(Y/n) Y  --这里说是否安装路由插件
    ?Use ESLint to lint your code? N-- 是否检查代码格式
    ?Pick an ESLint preset Standard  -- 选择一种代码检查的规范
    ?Set up unit tests  N  是否进行单元测试
    ?Setup e2e tests with Nightwatch N 是否使用e2e工具进行构建
    ?Should we run 'npm install' for you after the project has been created? npm --选择npm方式安装
    
    输入完成之后,工具就开始构建我们的工程啦!
    复制代码
    

    (3)我们可以自定义目录出来,例如

    pages : 所有的页面组件放在这里
    pages/home: 页面所有的公用组件
    pages/user:
    utils : 放置工具类
    store : 放置vuex数据仓库
    复制代码
    

    (4)整理包结构

    <1>App.vue

    <template>
      <div id="app">
        <router-view/>
      </div>
    </template>
    
    <script>
    export default {
      name: 'App'
    }
    </script>
    
    <style>
    
    </style>
    复制代码
    

    <2>删除component目录

    <3>删除assets/logo

    1. 安装JQuery和Bootstrap

    (1)安装JQuery

    由于bootstrap依赖Jquery,所以需要先安装jquery,这里版本使用1.12.4

    npm install jquery@1.12.4 --save
    复制代码
    

    (2)验证

    pages/home/HomePage

    <template>
      <!--
      1.测试npm i jquery@1.12.4 --save之后能不能跑得动-->
      <!--
      2.在router目录下更改配置-->
      <!---->
    <div>
      网站
    </div>
    </template>
    
    <script>
      $(function(){
        alert(123);
      }
    
        export default {
            name: "home-page"
        }
    </script>
    
    <style scoped>
    
    </style>
    复制代码
    

    (3)在router/index做配置

    import Vue from 'vue'
    import Router from 'vue-router'
    //配置HomePage
    import HomePage from '@/pages/home/HomePage'
    
    Vue.use(Router)
    
    export default new Router({
      routes: [
        //更改访问对象
        {
          path: '/',
          name: 'HomePage',
          component: HomePage
        }
      ]
    })
    复制代码
    

    (4)找到build/webpack.base.conf.js文件中:

    在文件头部添加引用

    const webpack = require('webpack');
    复制代码
    

    在文件配置对象的末尾增加如下配置

    plugins: [
        new webpack.ProvidePlugin({
          $: "jquery",
          jQuery: "jquery",
          "windows.jQuery": "jquery"
        })
      ]
    复制代码
    

    (5)npm run dev再执行一次

    3.安装Bootstrap

    (1)安装bootstrap3.3.7

     npm install bootstrap@3.3.7 --save
    复制代码
    

    (2)引入bootstrap

    在src/main.js文件的顶部加入bootstrap的主要文件引用

    import 'bootstrap/dist/css/bootstrap.min.css'
    import 'bootstrap/dist/js/bootstrap.min.js'
    复制代码
    

    (3)导入我们之前案例中编写的lottery.css

    • 将lottery.css复制粘贴进assets

    • 在src/main.js文件的顶部'引入lottery文件 import"@/assets/lottery.css"

      vue-devtool准备

      不安装也可以...

      vue-devtool是Vue官方提供的开发调试工具,能帮助我们查看Vue组件的数据,状态等属性。

      链接地址:https://github.com/vuejs/vue-devtools

    二:博彩首页

    (1)pages/common/TitleBar组件

    做标题栏部分

    <!--标题栏,可能有返回按钮-->
    <template>
        <div class="row title">
            <div class="col-xs-12 title">
    
              <router-link
                tag="div"
                v-if="needBack"
                class="div_back"
                to="/"
              >&lt;返回
              </router-link>
              {{title}}
            </div>
        </div>
    </template>
    
    <script>
        export default {
            name: "title-bar",
            props: {
              title: String,
              needBack: {
                type:Boolean,
                default:false
              }
            }
        }
    </script>
    
    <style scoped>
      .div_back{
        position: absolute;
        left: 15px;
      }
    </style>
    复制代码
    

    (2)home/HomePage.vue

    <template>
      <!--
      1.测试npm i jquery@1.12.4 --save之后能不能跑得动-->
      <!--
      2.在router目录下更改配置-->
      <!---->
    <div>
     <title-bar></title-bar>
    </div>
    </template>
    
    <script>
      // $(function(){
      //   alert(123);
      // })
    
      //HomePage要使用TitleBar里面的内容,要import.注意from里面的路径写法
      import TitleBar from"@/pages/common/TitleBar"
      //单文件也相当于是局部组件,那么就要注册或者说是绑定到下面的格式里面去
        export default {
            name: "home-page",
          //绑定
          components:{
              TitleBar
          }
        }
    </script>
    
    <style scoped>
    
    </style>
    复制代码
    

    (3)pages/common/TitleBar.vue完成标题栏部分的返回按钮和博彩首页的样式

    <template>
    <div class="row">
      <div class = "col-xs-12 title" >
        <!--网站标题-->
        <!--指定返回的样式....控制返回的显示和隐藏-->
        <div class="div-back" v-if="needback">&lt;返回</div>
        {{title}}
    
      </div>
    </div>
    </template>
    
    <script>
        export default {
          //vue将字母进行了拆分
            name: "title-bar",
          //接收外部传过来的数据
          props:["title","needback"]
        }
    </script>
    
    <style scoped>
      .div-back{
        position: absolute;
      }
    
    </style>
    复制代码
    

    (4)home/HomePage.vue

    <div>
      <!--在页面上调用的时候传值     显示返回按钮-->
     <title-bar :title="title" needback="true"></title-bar>
    </div>
    </template>
    
    <script>
      //HomePage要使用TitleBar里面的内容,要import.注意from里面的路径写法
      import TitleBar from"@/pages/common/TitleBar"
      //单文件也相当于是局部组件,那么就要注册或者说是绑定到下面的格式里面去
        export default {
            name: "home-page",
          //绑定
          components:{
              TitleBar
          },
          //取title这个变量
          data(){
              return{
                title:"博彩首页"
              }
          }
        }
    </script>
    <style scoped>
    </style>
    复制代码
    

    三:Swiper轮播图组件

    (1)在bootstrap插件中将轮播图部分代码复制过来

    pages/common/Carousel.vue

    <template>
      <div id="carousel-example-generic" class="carousel slide row" data-ride="carousel">
        <!-- Indicators -->
        <ol class="carousel-indicators">
          <li data-target="#carousel-example-generic" data-slide-to="0" class="active"></li>
          <li data-target="#carousel-example-generic" data-slide-to="1"></li>
          <li data-target="#carousel-example-generic" data-slide-to="2"></li>
        </ol>
    
        <!-- Wrapper for slides -->
        <div class="carousel-inner" role="listbox">
          <div class="item active">
            <img src="@/assets/1.png" alt="...">
            <div class="carousel-caption">
              ...
            </div>
          </div>
          <div class="item">
            <img src="@/assets/2.png" alt="...">
            <div class="carousel-caption">
              ...
            </div>
          </div>
          <div class="item">
            <img src="@/assets/3.png" alt="...">
            <div class="carousel-caption">
              ...
            </div>
          </div>
        </div>
    
        <!-- Controls -->
        <a class="left carousel-control" href="#carousel-example-generic" role="button" data-slide="prev">
          <span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
          <span class="sr-only">Previous</span>
        </a>
        <a class="right carousel-control" href="#carousel-example-generic" role="button" data-slide="next">
          <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
          <span class="sr-only">Next</span>
        </a>
      </div>
    </template>
    
    <script>
      export default {
        name: "carousel"
      }
    </script>
    <style scoped>
    </style>
    复制代码
    

    (2)将轮播图图片放在assets文件夹中

    (3)在common/Carousel.vue中,导入Carousel和绑定Carsousel

    <template>
      <!--
      1.测试npm i jquery@1.12.4 --save之后能不能跑得动-->
      <!--
      2.在router目录下更改配置-->
      <!---->
      <div>
        <!--这是标题栏.....   在页面上调用的时候传值     显示返回按钮-->
        <title-bar :title="title" needback="true"></title-bar>
        <!--这是轮播图-->
        <Carousel></Carousel>
      </div>
    </template>
    
    <script>
      // $(function(){
      //   alert(123);
      // })
    
      //HomePage要使用TitleBar里面的内容,要import.注意from里面的路径写法
      import TitleBar from "@/pages/common/TitleBar"
      //HomePage要使用Carousel里面的内容,要import.注意from里面的路径写法
      import Carousel from "@/pages/common/Carousel"
    
      //单文件也相当于是局部组件,那么就要注册或者说是绑定到下面的格式里面去
      export default {
        name: "home-page",
        //绑定
        components: {
          //将TieleBar注册到home-page这里来
          TitleBar,
          //将Carousel注册到home-page这里来
          Carousel
        },
        //取title这个变量
        data() {
          return {
            title: "博彩首页"
          }
        }
      }
    </script>
    <style scoped>
    </style>
    复制代码
    

    四:彩票历史记录

    (1)home/components/HistoryItem做彩票历史记录

    <template>
      <!--4.彩票历史记录-->
      <!--删除掉onclick-->
      <div class="row item">
        <!--左边11个格子-->
        <div class="col-xs-11">
          <!--开奖日期-->
          <div>
            <span style="font-size: 18px;">第2018019期</span>
            <span style="margin-left: 10px;">2018-02-13(二)</span>
          </div>
          <!--开奖号码-->
          <div style="margin-top: 10px;">
            <div class="ball-item ball-red">01</div>
            <div class="ball-item ball-red">11</div>
            <div class="ball-item ball-red">22</div>
            <div class="ball-item ball-red">23</div>
            <div class="ball-item ball-red">28</div>
            <div class="ball-item ball-red">30</div>
            <div class="ball-item ball-blue">15</div>
          </div>
        </div>
        <!--右边1个格子-->
        <div class="col-xs-1 div-right" >
          <span class="glyphicon glyphicon-chevron-right"></span>
        </div>
      </div>
    </template>
    
    <script>
      export default {
        name: "history-item"
      }
    </script>
    
    <style scoped>
      /*把div里面的样式抽取出来*/
      .item{
        border: 1px solid gainsboro;height: 80px;padding-top: 5px;
      }
      /*把div里面的样式抽取出来*/
      .div-right{
        padding-left: 0px;padding-top: 30px;
      }
    
    </style>
    复制代码
    

    (2)home/components/HistoryList做彩票历史记录

    <template>
      <div>
        <history-item v-for="i in 10" :key="i"></history-item></history-item>
      </div>
    </template>
    
    <script>
      // HistoryList这个组件要迭代这个HistoryItem,在这里导入
      import HistoryItem from "./HistoryItem"
    
      export default {
        name: "history-list",
          components:{
            HistoryItem
          }
      }
    </script>
    <style scoped>
    </style>
    复制代码
    

    五:将彩票历史记录写活

    (1)在HomePage上添加mounted,在mounted里面发送请求

      //取title这个变量
        data() {
          return {
            title: "博彩首页"
          }
        },
        mounted() {
          // 发起请求,当数据请求回来的时候,将数据渲染到页面上
          console.log("发送请求")
        }
      }
    复制代码
    

    (2)发送异步请求axios

    参考文档: https://www.kancloud.cn/yunye/axios/234845

    <1>安装

    npm install axios
    复制代码
    

    <2>在HomePage里面导入axios

    //HomePage要使用axios里面的内容,要import.注意from里面的路径写法
    import axios from "axios"
    复制代码
    

    <3>在static新建一个file,文件名为index,里面写入数据

    {
    data:["1","2","3","4"]
    }
    复制代码
    

    <4>在mouted()中用axios获取数据

        mounted() {
          // 发起请求,当数据请求回来的时候,将数据渲染到页面上
          console.log("发送请求")
          axios.get("/static/index").then(resp=>{
            console.log(resp.data);
          })
        }
    
    控制台能看到有static/index里面输出的结果.
    复制代码
    

    <5>将index里面的数据用数组的形式进行保存

     //取title这个变量
        data() {
          return {
            title: "博彩首页",
            //将index里面的数据进行保存
            historyList: []
          }
        },
        mounted() {
          // 发起请求,当数据请求回来的时候,将数据渲染到页面上
          console.log("发送请求")
          axios.get("/static/index").then(resp => {
            this.historyList = resp.data.data;
          })
        }
    复制代码
    

    <6>将保存的数据扔到历史记录里面

     <div>
        <!--这是标题栏.....   在页面上调用的时候传值     显示返回按钮-->
        <title-bar :title="title" needback="true"></title-bar>
        <!--这是轮播图-->
        <carousel></carousel>
        <!--历史记录-->
        <!--将历史记录的数据扔到这里来-->
        <history-list :data="historyList"></history-list>
      </div>
    复制代码
    

    <7>historyList接收data,用props

     export default {
        name: "history-list",
          components:{
            //将HistoryItem注册到home-page这里来
            HistoryItem,
            props:["data"]
          }
      }
    复制代码
    

    <8>循环

    <template>
      <div>
        <history-item v-for="history in data" :key="history.code" :history1="history"></history-item>
      </div>
    </template>
    复制代码
    

    <9>将history的数据history1传给historyItem,为了展现index里面的所有数据

    <script>
      export default {
        name: "history-item",
        props:["history1"]
      }
    </script>
    复制代码
    

    <10>将historyItem的数据进行整改

     <div>
            <span style="font-size: 18px;">第{{history1.code}}期</span>
            <span style="margin-left: 10px;">{{history1.data}}</span>
          </div>
    
        <!--开奖号码-->
          <div style="margin-top: 10px;">
            <div class="ball-item ball-red" v-for="red in history1.red.split(',')">{{red}}</div>
            <div class="ball-item ball-blue">{{history1.blue}}</div>
          </div>
        </div>
    
        script>
      export default {
        name: "history-item",
        props:["history1"]
      }
    </script>
    复制代码
    
    • 使用

      axios.get(url[, config]) axios.delete(url[, config]) axios.post(url[, data[, config]]) axios.put(url[, data[, config]]) //发生get请求 axios.get('/user?ID=12345') .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); });

      // 可选地,上面的请求可以这样做 axios.get('/user', { params: { ID: 12345 } }) .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); }); 发送post请求 axios.post('/user', { firstName: 'Fred', lastName: 'Flintstone' }) .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); });

    需求:当后台给了地址不断更换的时候的做法.

    只要网址有改变,就修改一下target里面的网址就行了.

    为了便于我们以后进行前后端联调,建议大家在代码中编写的时候,找到config/index.js修改proxyTable为如下的内容:

    proxyTable: {
          '/api':{
            target:'http://localhost:8080',
       //只要/以api开头的路径都重新改为static
            pathRewrite:{'^/api':'/static'}
          }
    }
    这段代码的意思是我将当前项目所有/api的内容,映射到http://localhost:8080这个路径里面,并且我需要将所有以/api开头的路径,修改为/static,实际的目标就是将如下路径进行一个修改
    axios.get('/api/index') --- 修改为 axios.get('/static/index')
    复制代码
    

    当我们项目进行联调的时候,我们就不需要修改vue中的代码,只需将proxyTable修改为:

    proxyTable: {
          '/api':{
            target:'目标服务器路径,例如http://localhost:3000',
          }
    }
    复制代码
    

    六:底部菜单栏设置

    (1)common/MenuBar

    <template>
      <div class="div-height">
      <div class="menu" >
        <div class="col-xs-4 menu-item menu-item-activied">
          <span class="glyphicon glyphicon-home"></span>
          <p>首页</p>
        </div>
        <div class="col-xs-4 menu-item">
          <span class="glyphicon glyphicon-shopping-cart"></span>
          <p>选号</p>
        </div>
        <div class="col-xs-4 menu-item">
          <span class="glyphicon glyphicon-user"></span>
          <p>我</p>
        </div>
      </div>
      </div>
    </template>
    
    <script>
        export default {
            name: "menu-bar"
        }
    </script>
    
    <style scoped>
      .div-height{
        height:50px;
      }
    </style>
    复制代码
    

    (2)各组件的步骤配置

    <div>
        <!--这是标题栏.....   在页面上调用的时候传值     显示返回按钮-->
        <title-bar :title="title" needback="true"></title-bar>
        <!--这是轮播图-->
        <carousel></carousel>
        <!--历史记录-->
        <!--将历史记录的数据扔到这里来-->
        <history-list :data="historyList"></history-list>
        <!--底部菜单栏-->
        <menu-bar></menu-bar>
      </div>
    
        //HomePage要使用MenuBar里面的内容,要import.注意from里面的路径写法
      import MenuBar from "@/pages/common/MenuBar"
    
        //将MenuBar注册到home-page这里来
          MenuBar,
    复制代码
    

    (3)在MenuBar里面,传入:class

    <template>
      <div class="div-height">
        <div class="menu">
          <div class="col-xs-4 menu-item" :class="{'menu-item-activied':index=='1'}">
            <span class="glyphicon glyphicon-home"></span>
            <p>首页</p>
          </div>
          <div class="col-xs-4 menu-item">
            <span class="glyphicon glyphicon-shopping-cart"></span>
            <p>选号</p>
          </div>
          <div class="col-xs-4 menu-item" :class="{'menu-item-activied':index=='3'}">
            <span class="glyphicon glyphicon-user"></span>
            <p>我</p>
          </div>
        </div>
      </div>
    </template>
    
    <script>
      export default {
        name: "menu-bar",
        props:{
          index:{
            type:String,
            default:"1"
          }
        }
      }
    </script>
    复制代码
    

    (4)在HomePage里面,传入一个index

     <div>
        <!--这是标题栏.....   在页面上调用的时候传值     显示返回按钮-->
        <title-bar :title="title" needback="true"></title-bar>
        <!--这是轮播图-->
        <carousel></carousel>
        <!--历史记录-->
        <!--将历史记录的数据扔到这里来-->
        <history-list :data="historyList"></history-list>
        <!--底部菜单栏-->
        <menu-bar index="3"></menu-bar>
      </div>
    复制代码
    

    七:点击历史记录跳转到历史记录详情页面

    (1)使用声明式跳转:router-link tag="div" to="url"

    home/components/DetailPage

    <template>
        <div>博彩详情组件</div>
    </template>
    
    <script>
        export default {
            name: "detail-page"
        }
    </script>
    
    <style scoped>
    
    </style>
    复制代码
    

    router/index

    import Vue from 'vue'
    import Router from 'vue-router'
    //配置HomePage
    import HomePage from '@/pages/home/HomePage'
    //配置DetailPage
    import DetailPage from '@/pages/home/DetailPage'
    
    Vue.use(Router)
    
    export default new Router({
      routes: [
        //更改访问对象
        {
          path: '/',
          name: 'HomePage',
          component: HomePage
        },
        //跳转到博采详情页面
        {
          path: '/detail',
          name: 'DetailPage',
          component: DetailPage
        }
      ]
    })
    复制代码
    

    home/components/HistoryList

    <template>
      <div>
        <router-link tag="div" to="/detail?code=123">点击跳转</router-link>
        <history-item v-for="history in data" :key="history.code" :history1="history"></history-item>
      </div>
    </template>
    复制代码
    

    home/components/DetailPage传参data

    <script>
      export default {
        name: "detail-page",
        data(){
         return{
           code:this.$route.query.code
         }
        }
      }
    </script>
    复制代码
    

    (2)使用编程式跳转

    • //this.$router:代表当时全局的路由器
      //this.$route:代表的是当前的路由信息
      复制代码
      

    (3)点击历史记录就跳转

    • @click.native="toToDetail('/detail?code='+history.code)"

    home/components/historyList

      <history-item 
          v-for="history in data"
          :key="history.code" 
          :history1="history"
          @click.native="goToDetail('/detail?code='+history.code)">
        </history-item>
    复制代码
    

    (4)优化返回按键

    DetailPage

    <template>
      <div>
        <!--&lt;!&ndash;把传入的参数带过来&ndash;&gt;-->
        <!--博彩详情组件{{code}}-->
        <title-bar title="博彩详情" :needback="true"></title-bar>
    
      <!--导入轮播图-->
        <carousel></carousel>
        <!--导入底部菜单栏-->
        <menu-bar></menu-bar>
    
      </div>
    </template>
    
    <script>
      //HomePage要使用TitleBar里面的内容,要import.注意from里面的路径写法
      import TitleBar from "@/pages/common/TitleBar"
      //HomePage要使用Carousel里面的内容,要import.注意from里面的路径写法
      import Carousel from "@/pages/common/Carousel"
      //HomePage要使用MenuBar里面的内容,要import.注意from里面的路径写法
      import MenuBar from "@/pages/common/MenuBar"
    
      export default {
        name: "detail-page",
        components:{
          TitleBar,
          MenuBar,
          Carousel
        },
        //跳转到详情页面的时候传入参数
        data() {
          return {
            code: this.$route.query.code
          }
        }
      }
    </script>
    
    <style scoped>
    
    </style>
    复制代码
    

    TitleBar

    <template>
      <div class="row">
        <div class="col-xs-12 title">
          <!--网站标题-->
          <!--指定返回的样式....控制返回的显示和隐藏-->
          <div class="div-back" v-if="needback">&lt;返回</div>
          {{title}}
        </div>
      </div>
    </template>
    
    <script>
      export default {
        //vue将字母进行了拆分
        name: "title-bar",
        //接收外部传过来的数据
        //   props: ["title", "needback"]
        // }
        props: {
          title: {
            type: String
          },
          needback: {
            type: Boolean,
            default:false
          }
        }
      }
    </script>
    
    <style scoped>
      .div-back {
        position: absolute;
      }
    
    </style>
    复制代码
    

    (5)导入老师发的detail文件到static文件里面

    DetailPage

    <template>
      <div>
        <title-bar title="博彩详情" :needback="true"></title-bar>
        <!--轮播图-->
        <carousel></carousel>
    
        <!--显示彩票信息-->
        <!--3.开奖日期-->
        <div style="margin-top: 8px;">
          <div style="float: left;">第{{history.code}}期</div>
          <div style="float: right;">{{history.date}}</div>
        </div>
    
        <!--清除浮动的div-->
        <div class="clearfix"></div>
    
        <!--4.中奖号码-->
        <div class="row text-center" style="margin-top: 10px;" v-if="history.red != null">
          <div class="ball-item ball-red" v-for="red in history.red.split(',')">{{red}}</div>
    
          <div class="ball-item ball-blue">{{history.blue}}</div>
        </div>
    
        <!--5.奖池金额-->
        <div style="margin-top: 14px;">
          <table class="table table-bordered">
            <thead>
            <tr style="background-color: gainsboro;">
              <td class="text-center">本期销量</td>
              <td class="text-center">奖池奖金</td>
            </tr>
            </thead>
            <tbody>
            <tr>
              <td class="text-center" style="color: red;">{{history.sales}}</td>
              <td class="text-center" style="color: red;">{{history.poolmoney}}</td>
            </tr>
            </tbody>
          </table>
        </div>
    
        <!--6.中奖信息-->
        <div>
          <table class="table table-bordered">
            <thead>
            <tr style="background-color: gainsboro;">
              <td class="text-center">奖项</td>
              <td class="text-center">中奖注数</td>
              <td class="text-center">奖金</td>
            </tr>
            </thead>
            <tbody>
              <tr v-for="prizegrade in history.prizegrades">
                <td class="text-center">{{prizegrade.type}}</td>
                <td class="text-center">{{prizegrade.typenum}}</td>
                <td class="text-center">{{prizegrade.typemoney}}</td>
              </tr>
            </tbody>
    
          </table>
        </div>
    
        <menu-bar></menu-bar>
    
      </div>
    </template>
    
    <script>
      import TitleBar from '@/pages/common/TitleBar';
      import Carousel from '@/pages/common/Carousel';
      import MenuBar from '@/pages/common/MenuBar'
    
      export default {
        name: "detail-page",
        components: {
          TitleBar,
          Carousel,
          MenuBar
        },
        data() {
          return {
            code: this.$route.query.code,
            history: {}
          }
        },
        mounted() {
          //发送请求获取 获取当前期的数据
          axios.get('/api/detail?code=' + this.code).then(resp => {
            console.log(resp.data)
            this.history = resp.data.data;
          });
        }
      }
    </script>
    
    <style scoped>
    
    </style>
    复制代码
    

    组件之间的跳转

    注意:如果提供了 path,params 会被忽略,上述例子中的 query 并不属于这种情况。取而代之的是下面例子的做法,你需要提供路由的 name 或手写完整的带有参数的 path:

    const userId = 123
    router.push({ name: 'user', params: { userId }}) // -> /user/123
    router.push({ path: `/user/${userId}` }) // -> /user/123
    // 这里的 params 不生效
    router.push({ path: '/user', params: { userId }}) // -> /user
    复制代码
    

    HistoryList示例

    <template>
      <div class="wraper">
    
        <div  v-for="history in list" :key="history.code" @click="handleItemClick(history.code)">
          <history-item :history="history"></history-item>
        </div>
    
      </div>
    </template>
    
    <script>
        import HistoryItem from './HistoryItem'
        export default {
            name: "history-list",
            props: ['list'],
            components: {
              HistoryItem
            },
            methods:{
              handleItemClick(history){
                this.$router.push({
                 name:'LotteryDetail',
                 params:{
                   code:history
                 }
                })
              }
            }
        }
    </script>
    
    <style scoped>
    
    </style>
    复制代码
    

    HistoryItem组件

    <template>
        <div class="row item">
          <!--左边11个格子-->
          <div class="col-xs-11">
            <!--开奖日期-->
            <div class="row">
              <span style="font-size: 18px;">第{{history.code}}期</span>
              <span style="margin-left: 10px;">{{history.date}}</span>
            </div>
            <!--开奖号码-->
            <div class="row" style="margin-top: 10px;">
              <div class="ball-item ball-red" v-for="redBall in history.red.split(',')">{{redBall}}</div>
              <div class="ball-item ball-blue">{{history.blue}}</div>
            </div>
          </div>
          <!--右边1个格子-->
          <div class="col-xs-1 item-arrow">
            <span class="glyphicon glyphicon-chevron-right"></span>
          </div>
        </div>
    </template>
    
    <script>
        export default {
            name: "history-item",
            props:["history"]
        }
    </script>
    
    <style scoped>
      .item{
        border: 1px solid gainsboro;
        height: 80px;
        padding-top: 5px;
        padding-left: 15px;
      }
    
      .item-arrow{
        padding-left: 0px;
        padding-top: 30px;
      }
    </style>
    复制代码
    

    LotteryDetail组件

    路由的配置

    {
          path: '/detail/:code',
          name: 'LotteryDetail',
          component: LotteryDetail,
          props:true
        }
    复制代码
    

    编程的方式跳转

    this.$router.push({
                 name:'LotteryDetail',
                 params:{
                   code:history
                 }
    });
    复制代码
    

    LotteryDetail的示例代码

    注意: vue的组件中对table标签要求比较严格,我们需要按如下方式来定义table

    <table>
        <thead>
            <tr><td></td></tr>
        </thead>
        <tbody>
            <tr><td></td></tr>
        </tbody>
    </table>
    复制代码
    

    LotteryDetail的示例代码

    <template>
        <div v-if="history != null">
          <!--标题栏-->
          <title-bar :needBack="needBack" :title="title"></title-bar>
          <!--广告轮播图-->
          <swiper></swiper>
    
          <!--彩票条目-->
          <div class="clearfix">
            <div class="pull-left">第{{code}}期</div>
            <div class="pull-right">{{history.date}}</div>
          </div>
    
          <!--显示本期中奖的球-->
          <div class="row text-center" style="margin-top: 10px;margin-bottom: 10px
    ">
            <div class="ball-item ball-red" v-for="redBall in history.red.split(',')">{{redBall}}</div>
            <div class="ball-item ball-blue">{{history.blue}}</div>
          </div>
    
          <!--显示中奖的信息-->
          <div>
            <table class="table table-bordered">
              <thead>
                <tr style="background-color: gainsboro">
                  <td class="text-center">本期销量</td>
                  <td class="text-center">奖池奖金</td>
                </tr>
              </thead>
              <tbody>
                <tr>
                  <td class="text-center">{{history.sales}}</td>
                  <td class="text-center">{{history.poolmoney}}</td>
                </tr>
              </tbody>
            </table>
          </div>
    
          <!--显示中奖的结果数据-->
          <div>
            <table class="table table-bordered">
              <thead>
                <tr style="background-color: gainsboro">
                  <td class="text-center">奖项</td>
                  <td class="text-center">中奖注数</td>
                  <td class="text-center">奖金</td>
                </tr>
              </thead>
              <tbody>
                <!--中奖结果数据循环生成-->
                <tr v-for="prizegrade in history.prizegrades" :key="prizegrade.type">
                  <td class="text-center">{{prizegrade.type}}</td>
                  <td class="text-center">{{prizegrade.typenum}}</td>
                  <td class="text-center">{{prizegrade.typemoney}}</td>
                </tr>
              </tbody>
            </table>
          </div>
    
          <menu-bar></menu-bar>
        </div>
    </template>
    
    <script>
        import TitleBar from '@/pages/common/TitleBar'
        import Swiper from '@/pages/common/Swiper'
        import axios from 'axios'
        import MenuBar from '@/pages/common/MenuBar'
    
        export default {
          name: "lottery-detail",
          props:['code'],
          components: {
            TitleBar,
            Swiper,
            MenuBar
          },
          data (){
            return {
              needBack : true,
              title : "博彩详情",
              history:null
            }
          },
          mounted (){
            axios.get("/api/detail?code="+this.code).then((res)=>{
              this.history = res.data.data;
            });
          }
        }
    </script>
    
    <style scoped>
    
    </style>
    复制代码
    

    用户页面

    Vuex的使用

    https://vuex.vuejs.org/zh/

    演示demo

    import Vuex from 'vuex'
    import Vue from 'vue'
    
    Vue.use(Vuex);
    
    export default new Vuex.Store({
      state:{
        all:['aa','bb','cc']
      },
      actions:{ //action中可执行异步操作
        action1(context,msg){
          console.log('action..'+msg);
          context.commit('mutations1',msg);
        }
      },
      mutations:{ //mutations中不能执行异步操作
        mutations1(state){
          state.all=['dd','ee']
        }
      }
    });
    
    注意:根Vue实例中需要引入store
    在组件中,我们就可以这样来修改这里面的数据:
    this.$store.dispatch("action1",'hahaha');
    复制代码
    

    定义Store

    import Vue from 'vue';
    import VueX from 'vuex';
    import User from './user'
    //使用插件
    Vue.use(VueX);
    
    export default new VueX.Store({
      modules:{
        User 
      }
    });
    复制代码
    

    定义UserStore

    const key = "user";
    
    const state = {
      user:null
    }
    
    const getters = {
      isLogin:(state)=>state.user != null,
      user:(state)=>state.user
    }
    
    const actions = {
      loadLocalUser:(context)=>{
        let user = localStorage.getItem(key);
        context.commit('setUser',user);
      },
      setUser:(context,user)=>{
        context.commit('setUser',user);
      },
      logout:(context)=>{
        localStorage.removeItem(key);
        context.commit('setUser',null);
      }
    }
    
    const mutations = {
      setUser:(state,user)=>{
        state.user = user;
        //保存
        localStorage.setItem(key,user);
      }
    }
    
    export default {
      state,actions,mutations,getters
    }
    复制代码
    

    常用的辅助函数:

    import {mapActions,mapGetters} from 'vuex'
    在computed中使用
        ...mapGetters(['对应getters中的属性'])
    在methods中使用
        ...mapActions(['对应action的名字'])
    复制代码
    

    登录页面

    <template>
      <div>
        <!--标题栏-->
        <title-bar title="登录页面"></title-bar>
        <!--登录的标蓝-->
        <div class="row" style="margin-top: 32px;">
          <!--空列-->
          <div class="col-xs-1"></div>
          <!--内容部分-->
          <div class="col-xs-10">
            <!--2.登录注册的标题-->
            <div class="row">
              <div class="col-xs-6 text-center" style="color: green;">登录</div>
              <div class="col-xs-6 text-center" onclick="location.href='03-注册页面.html'" >注册</div>
            </div>
    
            <!--3.水平分割线-->
            <hr style="border: 2px solid gainsboro;" />
    
              <!--4.表单输入项-->
              <div class="form-group">
                <input type="text" v-model="email" class="form-control" placeholder="请输入您的邮箱...">
              </div>
              <!--5.密码-->
              <div class="form-group">
                <input type="password" v-model="password" class="form-control" placeholder="请输入您的密码...">
              </div>
    
              <!--9.注册-->
              <div class="form-group">
                <input type="button" @click="handleLogin()" class="form-control btn btn-success" value="登录"  >
              </div>
    
              <!--跳转去登录-->
              <div style="margin-top: 15px;">
                <a href="#" style="color: green;">忘记密码</a>&nbsp;|&nbsp;<a href="03-注册页面.html" style="color: green;">去注册</a>
              </div>
    
          </div>
          <!--空列-->
          <div class="col-xs-1"></div>
        </div>
      </div>
    </template>
    
    <script>
        import TitleBar from '@/pages/common/TitleBar'
        import {mapGetters,mapActions} from 'vuex'
        import axios from 'axios'
    
        export default {
            name: "login-page",
            components:{
              TitleBar
            },
            data(){
              return {
                email:'',
                password:''
              }
            },
            methods:{
              ...mapActions(['setUser']),
              handleLogin(){
                //this.$store.dispatch('changeAction','李四');
                //this.$store.state.username = '王五'
                //this.changeAction('赵六')
                //发送异步请求去获取用户信息
                axios.get('/api/login',{params:{email:this.email,password:this.password}}).then(resp=>{
                  console.log(resp.data.data);
                  this.setUser(resp.data.data);
    
                  this.$router.push('/user');
                });
    
              }
            }
        }
    </script>
    
    <style scoped>
    
    </style>
    复制代码
    

    我的页面

    <template>
        <div>
          <title-bar title="用户信息"></title-bar>
    
          <!--用户信息栏-->
          <div class="row">
            <div class="col-xs-4">
              <img src="img/icon.jpg" alt="" class="img-circle img-thumbnail" style="width:80px;height:80px" />
            </div>
            <div class="col-xs-8" style="padding-top: 22px;padding-left: 5px;">
              <p style="font-size: 16px;">{{user.username}}</p>
              <p style="font-size: 14px;">手机号:{{user.mobile}}</p>
            </div>
          </div>
    
          <!--水平分割线-->
          <hr />
    
          <!--今日幸运中奖号码-->
          <div class="row">
            <div class="col-xs-12" style="color: red;margin-bottom: 9px;">
              您今日幸运中奖号码为:
            </div>
    
            <div class="col-xs-12 text-center" style="height:49px;">
              <div class="ball-item ball-red">01</div>
              <div class="ball-item ball-red">03</div>
              <div class="ball-item ball-red">08</div>
              <div class="ball-item ball-red">12</div>
              <div class="ball-item ball-red">23</div>
              <div class="ball-item ball-red">29</div>
              <div class="ball-item ball-blue">15</div>
            </div>
    
            <div class="col-xs-offset-7 col-xs-2">
              <button class="btn btn-default">购买立中大奖</button>
            </div>
          </div>
    
          <!--水平分割线-->
          <hr />
    
          <!--累计中奖次数-->
          <div class="row">
            <div class="col-xs-6">
              累计中奖次数:<span style="color:red;font-size: 14px;">1024</span>
            </div>
            <div class="col-xs-6">
              累计中奖金额:<span style="color:red">512万</span>
            </div>
          </div>
          <!--水平分割线-->
          <hr />
    
          <!--账户余额-->
          <div class="row">
            <div class="col-xs-12">
              账户余额:<span style="color:red;font-size: 14px;">{{user.money}}元</span>
            </div>
          </div>
          <!--水平分割线-->
          <hr />
    
          <!--我的订单-->
          <div class="row">
            <div class="col-xs-12">
              我的订单
            </div>
          </div>
          <!--水平分割线-->
          <hr />
    
          <!--基本信息-->
          <div class="row">
            <div class="col-xs-12">
              基本信息
            </div>
          </div>
          <!--水平分割线-->
          <hr />
    
          <!--设置信息-->
          <div class="row">
            <div class="col-xs-12">
              设置
            </div>
          </div>
          <!--水平分割线-->
          <hr />
    
          <!--底部菜单栏-->
          <menu-bar index="3"></menu-bar>
        </div>
    </template>
    
    <script>
        import TitleBar from '@/pages/common/TitleBar'
        import MenuBar from '@/pages/common/MenuBar'
        import {mapGetters} from 'vuex'
    
        export default {
            name: "user-page",
            components:{
              TitleBar,
              MenuBar
            },
            data(){
              return {
                name:this.$store.state.username
              }
            },
            computed:{
              ...mapGetters(['user'])
            }
        }
    </script>
    
    <style scoped>
    
    </style>
    复制代码
    

    localStorage的使用

    localStorage.getItem(key,value);
    localStorage.setItem(key,value);
    localStorage.removeItem(key)
    localStorage.clear()
    复制代码
    

    选号组件

    选号页面示例代码

    <template>
        <div>
          <!--标题栏-->
          <title-bar  :needBack="needBack" title="博彩选号"></title-bar>
    
          <!--信息声明-->
          <lottery-info></lottery-info>
    
          <div style="color:darkgray">请选择6个红球,1个蓝球</div>
    
          <!--红球展示区域-->
          <red-ball-picker :data="randomRed" @onRedSelected="handleRedSelected"></red-ball-picker>
          <!--蓝球展示区域-->
          <blue-ball-picker :data="randomBlue" @onBlueSelected="handleBlueSelected"></blue-ball-picker>
    
          <button type="button" class="btn btn-default pull-right clearfix" @click="addOne()">添加</button>
          <div class="clearfix"></div>
    
          <!--机选按钮-->
          <div class="rdm-div">
            <button type="button" class="btn btn-default pull-right"  @click="addRandom()">机选</button>
            <select class="form-control select" v-model="num">
              <option>1</option>
              <option>2</option>
              <option>3</option>
              <option>4</option>
              <option>5</option>
            </select>
          </div>
          <!--5.底部菜单栏-->
          <div class="menu">
            <div class="menu-item" @click="goToCart">
              <span class="glyphicon glyphicon-shopping-cart"></span>
              <span class="badge" >{{cartSize}}</span>
              <p>购物车</p>
            </div>
            <div class="menu-item" @click="goToCart">
              <span class="glyphicon glyphicon-save"></span>
              <p>立即投注</p>
            </div>
          </div>
        </div>
    </template>
    
    <script>
        import TitleBar from '@/pages/common/TitleBar'
        import RedBallPicker from '@/pages/shopping/components/RedBallPicker'
        import BallUtils from '@/utils/BallUtils'
        import BlueBallPicker from "./components/BlueBallPicker";
        import LotteryInfo from "./components/LotteryInfo";
        import {mapActions,mapGetters} from 'vuex'
    
        export default {
            name: "select-page",
            components:{
              BlueBallPicker,
              TitleBar,
              RedBallPicker,
              LotteryInfo
            },
            data (){
              return{
                needBack:true,
                redBalls:[],
                blueBall:null,
                randomRed:null,
                randomBlue:null,
                num:1
              }
            },
            computed:{
              ...mapGetters(['cartSize']),
            },
            methods:{
              ...mapActions(['addToCart']),
              handleRedSelected(balls){
                this.redBalls = balls;
              },
              handleBlueSelected(ball){
                this.blueBall = ball;
              },
              addOne(){
                //先判断红球=0,蓝球=0,一个没有选话就随机产生一组
                if(this.redBalls!=null && this.redBalls.length==0 && this.blueBall == null){
                  //随机产生一注彩票
                  this.randomOne();
                }else if(this.redBalls!=null && this.redBalls.length==6 && this.blueBall != null){
                  //判断选择的红球的数量是否=6,蓝球的数量=1,添加到购物车
                  this.addToCart({redBalls:this.redBalls,blue:this.blueBall,count:1})
                }else{
                  //否则条件不成立,提示红球6个蓝球1个
                  alert("红球的数量须为6个,蓝球的数量为1个");
                }
              },
              randomOne(){
                this.randomRed = BallUtils.randomRed()
                this.randomBlue = BallUtils.randomBlue()
              },
    
              addRandom(){
                //根据用户机选的数量,随机产生
                let self = this
                for(let i=0; i < this.num; i++){
                  self.randomOne();
                  //将每次随机产生的号码,添加到购物车中
                  self.addToCart({redBalls:self.randomRed,blue:self.randomBlue,count:1})
                }
              },
              goToCart(){
                this.$router.push('/cart')
              }
            }
        }
    </script>
    
    <style scoped>
      .select{
        float:right;
        width:90px;
      }
    
      .badge {
        background-color: red;
        position: absolute;
        top: -10px
      }
    
      .menu-item{
        width: 50%;
      }
    
      .rdm-div{
        margin-top: 15px;
      }
    </style>
    复制代码
    

    红球选号区域

    我们首先来解决一下页面上球的显示问题,红球总共33个,如果我们直接写死的话,重复代码会很多,我们考虑来初始化这33个红球,示例代码如下

    这里我们选用created这个生命周期钩子
    created(){
              //初始化页面中的球数据
              for(let i = 1; i<=33; i++){
                let red = i;
                if(i < 10){
                  red ="0"+i;
                }
                //每一个被初始化出来的红球都是没有被选中的状态
                this.balls.push({number:red.toString(),selected:false});
              }
     }
    复制代码
    

    某个红球被选中

    1. 先判断当前球是否已经被选中
      1. 若被选中,则取消选中状态
        1. 将当前红球,从所有已选中的球中删除掉
      2. 若未被选中,则先判断当前选中的红球是否小于6个
        1. 若小于6个
          1. 修改当前求的状态
          2. 将当前球保存到所有选中的球中
        2. 若已经等于6个红球了
          1. 提示用户最多只能选择6个红球
    2. 通知父组件,红球选中的数据发生了改变

    注意:我们这里只通知父组件选中球的信息,如["01","03","05","08","09","32"]

        handleRedClick(ball){
                 //1.先判断当前球是否已经被选中
                 if(ball.selected){
                   //如果当前球已经被选中,则取消选中
                   ball.selected = false;
                   //将当前的球从被选中的数组中删除掉
                   let index = this.selectedRedBalls.indexOf(ball.number);
                   //删除元素
                   this.selectedRedBalls.splice(index,1);
                 }else{
                   //判断当前选中的球是否小于6个
                   if(this.selectedRedBalls.length < 6){
                     //选中当前球
                     ball.selected = true;
                     this.selectedRedBalls.push(ball.number);
                   }else{
                     alert('红球最多只能选择6个')
                   }
                 }
                //通知父组件数据发生变化了
                 this.$emit('onRedSelected',this.selectedRedBalls);
               }
    
    <template>
      <div class="clearfix">
        <div v-for="ball in balls" :key="ball.number" class="col-xs-ball">
          <div class="ball-item ball-red" @click="handleRedClick(ball)" :class="{'ball-red-selected':ball.selected}">
            {{ball.number}}
          </div>
        </div>
      </div>
    </template>
    
    <script>
        export default {
            name: "red-ball-picker",
            props:{
              data:{
                type:Array,
                default:null
              }
            },
            data(){
              return {
                balls:[],
                selectedRedBalls:[]
              }
            },
            methods:{
               handleRedClick(ball){
                 //1.先判断当前球是否已经被选中
                 if(ball.selected){
                   //如果当前球已经被选中,则取消选中
                   ball.selected = false;
                   //将当前的球从被选中的数组中删除掉
                   let index = this.selectedRedBalls.indexOf(ball.number);
                   //删除元素
                   this.selectedRedBalls.splice(index,1);
                 }else{
                   //判断当前选中的球是否小于6个
                   if(this.selectedRedBalls.length < 6){
                     //选中当前球
                     ball.selected = true;
                     this.selectedRedBalls.push(ball.number);
                   }else{
                     alert('红球最多只能选择6个')
                   }
                 }
                //通知父组件数据发生变化了
                 this.$emit('onRedSelected',this.selectedRedBalls);
               }
            },
            watch:{
              data(newVal,OldVal){
                //监听data数据的变化
                if(newVal != null && newVal.length == 6){
                  //清空当前已经选择数组的状态
                  this.selectedRedBalls = [];
                  // 将新数据保存到当前选中的球数组中
                  this.selectedRedBalls.push(...newVal);
    
                  //修改页面上球的状态
                  let self = this;
                  this.balls.forEach(function(ball){
                    let index = self.selectedRedBalls.indexOf(ball.number);
    
                    ball.selected = index != -1;
    
                  });
    
                  //通知父组件数据发生变化了
                  this.$emit('onRedSelected',self.selectedRedBalls);
                }
              }
            },
            created(){
              //初始化页面中的球数据
              for(let i = 1; i<=33; i++){
                let red = i;
                if(i < 10){
                  red ="0"+i;
                }
                this.balls.push({number:red.toString(),selected:false});
              }
            }
    
        }
    </script>
    
    <style scoped>
    
    </style>
    复制代码
    

    蓝球选号区域

    初始化16个蓝球

        created(){
              //初始化页面中的球数据
              for(let i = 1; i<=16; i++){
                let blue = i;
                if(i < 10){
                  blue ="0"+i;
                }
                this.balls.push({number:blue.toString(),selected:false});
              }
            }
    复制代码
    

    某个蓝球被选中

    1. 先取消前一次选中的蓝球的状态

    2. 修改当前选中蓝球的状态

    VueX存储购物车

    这里我们定义购物车里面的内容为如下格式:

    {red:"01,03,05,08,09,32",blue:"13",count:2}
    复制代码
    

    示例代码如下

    //从浏览器内置的存储去获取数据
    let jsonStr = localStorage.getItem("carts");
    //将json字符串转成json数组
    let defaultCarts = JSON.parse(jsonStr);
    
    //定义保存数据的地方
    const state={
      carts:defaultCarts // {red:'01,02,03,04,05,06',blue:"16",count:1}
    }
    //对外提供访问数据的方法
    const getters={
      cartSize:(state)=>state.carts.length,
      getCarts:(state)=>state.carts,
      totalMoney:(state)=>{
    
        let totalCount = 0;
        state.carts.forEach((item)=>{
          totalCount+=item.count;
        });
        return totalCount*2;
    
      }
    }
    
    //对外提供获取数据的方法
    const actions={
      // {red:'01,02,03,04,05,06',blue:"16",count:1}
      // 传递过来的数据是 {redBalls:this.redBalls,blueBall:this.blueBall,count:1};
      addToCart(context,data){
        console.log("actions中addToCart被调用");
        console.log("action提交数据给mutations去修改")
        let redBalls = data.redBalls;
    
        let red = "";
        redBalls.forEach((item)=>{
          red +=","+item;
        });
        red = red.substr(1);
    
        //console.log(red);
    
        let cartItem = {red:red,blue:data.blueBall,count:data.count};
    
        context.commit('mAddToCart',cartItem);
      },
      //清空购物车
      clearCarts(context){
        context.commit('mClearCarts');
      },
    
      //删除某一条记录
      deleteItem(context,cartItem){
        //action调用mutations去真的删除
        context.commit('mDeleteItem',cartItem);
      }
    
    }
    //跟踪数据变化的,vue需要的, 真正修改数据
    const mutations = {
      mAddToCart(state,cartItem){
    
        console.log("mutations中修改数据:"+cartItem);
        state.carts.push(cartItem);
    
        //将内存中的数据保存到浏览器本地
        localStorage.setItem("carts",JSON.stringify(state.carts))
      },
    
      //真正清空数组的地方
      mClearCarts(state){
        state.carts=[];
    
        localStorage.clear();
      },
      mDeleteItem(state,cartItem){
        let index = state.carts.indexOf(cartItem);
    
        //删除记录
        state.carts.splice(index,1);
    
        localStorage.setItem("carts",JSON.stringify(state.carts))
      }
    }
    
    //导出文件的所有内容
    export default {
      state,getters,actions,mutations
    }
    复制代码
    

    购物车页面

    购物车组件

    <template>
      <div>
        <!--需要返回按钮的标题栏-->
        <title-bar :needBack="true" title="购物车"></title-bar>
        <!--需要轮播图-->
        <swiper></swiper>
        <!--需要彩票信息-->
        <lottery-info></lottery-info>
    
        <!--三个按钮组-->
        <div class="row" style="margin-bottom: 10px;">
          <div class="col-xs-4">
            <button type="button" class="btn btn-default" @click="handleSelect">+手动选号</button>
          </div>
          <div class="col-xs-4">
            <button type="button" class="btn btn-default" @click="handleRandom">+机选一注</button>
          </div>
          <div class="col-xs-4">
            <button type="button" class="btn btn-default" @click="handleClear">清空列表</button>
          </div>
        </div>
    
        <!--展示购物项条目-->
        <div>
           <shopping-item v-for="item in carts" :key="item.red" :data="item" @onDeleteItem="deleteItem" ></shopping-item>
        </div>
    
        <!--底部的菜单栏-->
       <div style="height: 50px">
         <div class="menu" >
           <div class="menu-item" @click="submitOrder" >
             <p>立即付款 {{totalMoney}}元</p>
           </div>
         </div>
       </div>
    
      </div>
    </template>
    
    <script>
        import TitleBar from '@/pages/common/TitleBar';
        import Swiper from '@/pages/common/Swiper';
        import LotteryInfo from './components/LotteryInfo'
        import ShoppingItem from './components/ShoppingItem'
        import BallUtils from '@/utils/BallUtils'
        import {mapActions,mapGetters} from 'vuex'
    
        export default {
            name: "cart-page",
            components:{
              Swiper,
              TitleBar,
              LotteryInfo,
              ShoppingItem
            },
            methods:{
              ...mapActions({
                 addToCart:"addToCart",
                 clearCart:"clearCart",
                 deleteOne:'deleteOne'
              }),
              handleSelect(){
                //跳转去选号页面
                this.$router.go(-1);
              },
              handleRandom(){
                let redBalls = BallUtils.randomRed();
                let blue = BallUtils.randomBlue();
                this.addToCart({redBalls:redBalls,blue:blue,count:1});
              },
              handleClear(){
                //this.$store.dispatch('clearCart')
                this.clearCart()
              },
              deleteItem(cart){
                this.deleteOne(cart);
              }
            },
            computed:{
              ...mapGetters({
                carts:"carts",
                totalMoney:"totalMoney"
              })
            }
        }
    </script>
    
    <style scoped>
      .menu{
        height: 60px;
      }
      .menu-item{
        width: 100%;
        text-align: center;
        height: 50px;
        line-height: 50px;
      }
    </style>
    复制代码
    

    购物项组件

    <template>
      <div class="row shop-item" >
        <div class="col-xs-1" @click="handleDelete(data)" style="padding-left: 10px;padding-top: 18px;">
          <!--删除的图标-->
          <span v-if="showDelete" class="glyphicon glyphicon-remove-circle"></span>
        </div>
        <div class="col-xs-10" style="padding-right: 0px;padding-left: 5px" >
          <div>
            <div class="ball-item ball-red" v-for="red in data.red.split(',')" :key="red">{{red}}</div>
    
            <div class="ball-item ball-blue" >{{data.blue}}</div>
          </div>
          <div style="margin-top: 5px;">单式{{data.count}}注 {{data.count*2}}元</div>
        </div>
        <div class="col-xs-1" style="padding-left: 5px;padding-top: 18px;">
          <!--小箭头-->
          <span v-if="showRight" class="glyphicon glyphicon-chevron-right"></span>
        </div>
      </div>
    </template>
    
    <script>
        export default {
            name: "shopping-item",
            props:{
              showDelete:{
                type:Boolean,
                default:true
              },
              showRight:{
                type:Boolean,
                default:true
              },
              data:{
                type:Object
              }
            },
            methods:{
              handleDelete(){
                this.$emit('onDeleteItem',this.data)
              }
            }
        }
    </script>
    
    <style scoped>
      .shop-item{
        padding-top: 10px;
        padding-bottom: 10px;
        border: 1px solid #E5E5E5;
      }
    </style>
    复制代码
    

    生产环境打包

    项目中我们编写的vue文件并不能直接丢给服务器。

    vue-cli为我们提供了一键打包的功能,并自动为我们进行了资源压缩,合并,小图进行base64,css编译等很多功能,只需要执行以下命令即可:

    npm run build
    复制代码
    

    将打包出来的dist目录下的内容,丢给服务器人员即可。

    回顾:
    第一天: 基础语法
        v-model
        v-for
        v-if
        props
        $emit 对外发消息
        :class
        :属性名=js代码
        data:{}
        computed:{}
        watch:{}
        methods:{}
        mounted:{} 若有异步请求
        created:{} 同步处理 
    
        单文件组件:局部组件
    第二天:
        网站首页 axios 发起异步请求
            博彩详情页面: this.$router.push  组件之间的跳转
                        this.$router.go() 
         共享数据: Vuex
            登录页面 
            用户页面 
            new Vuex.Store({
                module:{
    
                }
            });
            const state={}    存储数据
            const getters={}  相当于是javabean中Get方法 获取数据方法
            const actions={}  相当于是set方法, 对外提供修改数据的方法
            const mutations={} 内部自己真正去修改数据的地方
     第三天:
        选中球
        机选球
        添加记录去vuex
        购物车去展示数据
    
        localStorage
    
    链接:https://pan.baidu.com/s/1DzCJJtGVYThF4YxwqqxDmw 密码:8uan     
    链接:https://pan.baidu.com/s/1EBJjxH-OObV2r50tXg88DQ 密码:rj4n  
    

    相关文章

      网友评论

        本文标题:Vue搭建的小项目(学习)

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