vue03
Posted xiaocongcong888
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue03相关的知识,希望对你有一定的参考价值。
选号组件
选号页面示例代码
<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});
}
}
某个红球被选中
- 先判断当前球是否已经被选中
- 若被选中,则取消选中状态
- 将当前红球,从所有已选中的球中删除掉
- 若未被选中,则先判断当前选中的红球是否小于6个
- 若小于6个
- 修改当前求的状态
- 将当前球保存到所有选中的球中
- 若已经等于6个红球了
- 提示用户最多只能选择6个红球
- 若小于6个
- 若被选中,则取消选中状态
- 通知父组件,红球选中的数据发生了改变
注意:我们这里只通知父组件选中球的信息,如["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});
}
}
某个蓝球被选中
- 先取消前一次选中的蓝球的状态
- 修改当前选中蓝球的状态
<template>
<div class="blue-containner">
<div v-for="ball in balls" :key="ball.number" class="col-xs-ball">
<div class="ball-item ball-blue" @click="handleBlueClick(ball)" :class="{‘ball-blue-selected‘:ball.selected}">
{{ball.number}}
</div>
</div>
</div>
</template>
<script>
export default {
name: "blue-ball-picker",
props:{
data:{
type:String,
default:null
}
},
data(){
return {
balls:[],
selectedBall:null
}
},
methods:{
handleBlueClick(ball){
//取消上一次选中的蓝球的选中状态
if (this.selectedBall) {
this.selectedBall.selected = false;
}
//将当前球的状态改为true
ball.selected = true
// 记录当前选中的球
this.selectedBall = ball;
//通知父组件数据发生变化了
this.$emit(‘onBlueSelected‘, this.selectedBall.number);
}
},
watch:{
data(newVal,OldVal){
//监听data数据的变化
if(newVal != null){
//修改页面上球的状态
let self = this;
this.balls.forEach(function(ball){
if(ball.number === newVal){
ball.selected = true;
//清空上一次选中的状态
if(self.selectedBall != null){
self.selectedBall.selected = false;
}
self.selectedBall = ball;
}
});
//通知父组件数据发生变化了
this.$emit(‘onBlueSelected‘,this.selectedBall.number);
}
}
},
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});
}
}
}
</script>
<style scoped>
.red-containner{
clear: both;
}
</style>
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
以上是关于vue03的主要内容,如果未能解决你的问题,请参考以下文章