Vue入门-1购物车

此项目并非原创,仅记录一下,适合刚入门的小伙伴

Cart-Demo

  1. 项目截图
    这里写图片描述
  2. .简单介绍几个主要的文件

    components:项目页面构成的文件
    -store.js:项目主要使用的js处理文件
    -router/index.js:项目页面跳转配置路由
    -App.vue:总组件,默认页面
    -main.js:入口文件

  3. 详细介绍每个文件的内容
    Index.vue
<template>
    <div class="container">
        <div class="row">
            <div class="product col-md-offset-2 col-sm-offset-2 col-md-8 col-sm-8">
                <div class="row">
                    <div class="gallery col-md-6 col-sm-6">
                        <img :src="iPhone6S.activeStyleUrl" class="img-responsive" alt="">
                    </div>
                    <div class="detail col-md-6 col-sm-6">
                        <h3 class="name"><span v-text="iPhone6S.name"></span></h3>
                        <hr>
                        <div class="options">
                            <dl class="dl-horizontal">
                                <dt>描述:</dt>
                                <dd><span v-text="iPhone6S.desc"></span></dd>
                            </dl>
                            <dl class="dl-horizontal">
                                <dt>价格:</dt>
                                <dd class="pomegrange"><strong><span v-text="iPhone6S.price"></span></strong></dd>
                            </dl>
                            <dl class="option dl-horizontal">
                                <dt>外观:</dt>
                                <dd>
                                    <ul>
                                        <li v-for="(key,value) in iPhone6S.style" @click="changeStyle(value,key)" :class="{active:iPhone6S.activeStyleUrl==key}">
                                            <span v-text="value"></span>
                                        </li>
                                    </ul>
                                </dd>
                            </dl>
                            <dl class="option dl-horizontal">
                                <dt>存储容量:</dt>
                                <dd>
                                    <ul>
                                        <li v-for="(key,value) in iPhone6S.storage" @click="changePrice(value,key)" :class="{active:iPhone6S.price==key}">
                                            <span v-text="value"></span>
                                        </li>
                                    </ul>
                                </dd>
                            </dl>
                        </div>
                        <hr>
                        <button class="btn btn-danger btn-block" @click="addItem()" :disabled="iPhone6S.isSelected">
                            <span class="glyphicon glyphicon-shopping-cart"></span>加入购物车
                        </button>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
export default {
    name:'Index',
    data(){
        return{
            activeStyle:'',
            type:''
        } 
    },
    computed:{
        iPhone6S(){
            return this.$store.getters.iPhone6S;
        }
    },
    methods:{
        changeStyle(styleName,styleUrl){
            console.log(styleName+"-----"+styleUrl);
            var item={
                styleName:styleName,
                styleUrl:styleUrl
            }
            return this.$store.dispatch('change_style',item)
        },
        changePrice(storage,price){
            var item={
                storage:storage,
                price:price
            }
            return this.$store.dispatch('change_price',item)
        },
        addItem(){
            return this.$store.dispatch('add_item')
        }
    }

}
</script>

<style>
.pomegranage {
  color: #c0392b;
}
.detail dt {
  color: #95a5a6;
  width: 64px;
  padding: 4px 0;
}
.detail dd {
  margin-left: 64px;
  padding: 4px;
}
.option ul {
  padding: 0;
}
.option ul > li {
  float: left;
  list-style: none;
  margin-right: 4px;
  padding: 0 8px;
  border: 2px solid #eee;
}
.option ul > li:hover {
  border: 2px solid #c0392b;
}
.option ul .active {
  border: 2px solid #c0392b;
}
</style>

Nav.vue

<template>
    <nav class="navbar navbar-default">
        <div class="container-fluid">
            <div class="navbar-header">
                <router-link :to="{path:'/'}">Shopping Cart</router-link>
            </div>
            <div class="collapse navbar-collapse">
                <ul class="nav navbar-collapse">
                    <router-link :to="{path:'/index',activeClass:'active'}">
                    <a href="#!">iPhone 6S<span class="sr-only">(current)</span></a>
                    </router-link>                                            
                    /   
                    <router-link :to="{path:'/cart',activeClass:'active'}">
                    <a href="#!">购物车<span class="badge text-danger" v-text="totalItem" v-if="totalItem">(current)</span></a>
                    </router-link>
                </ul>
            </div>
        </div>
    </nav>
</template>

<script>
export default {
    name:'Nav',
    computed:{
        totalItem(){
            return this.$store.getters.cart.length
        }
    }
}
</script>

<style>
.text-danger {
    color: #fff;
    background-color: #d9534f;
  }
</style>

Cart.vue

<template>
    <div id="cart" class="cart col-md-offset-2 col-sm-offset-2 col-md-8 col-sm-8">
        <div class="panel panel-danger" v-if="cart.length">
            <div class="panel-heading">
                <span class="glyphicon glyphicon-shopping-cart"></span>购物车
                <span class="pull-right"><strong>总计:{{totalPrice}}</strong></span>
            </div>
            <div class="panel-body cart-detail">
                <ul>
                    <li v-for="item in cart">
                        <span class="pomegranage glyphicon glyphicon-remove-circle" @click="removeItem(item)"></span>
                        <span>Apple/苹果 iPhone6S</span>
                        <span class="label label-success" v-text="item.type"></span>
                        <span class="badge text-danger" v-text="item.count"></span>
                        <span class="cart-price pomegrange pull-right"><strong>{{item.price}}</strong></span>
                    </li>
                </ul>
                <div class="panel-footer">
                    <button class="btn btn-danger btn-block">结算
                        <span class="glyphicon glyphicon-circle-arrow-right"></span>
                    </button>
                </div>
            </div>
        </div>
        <div class="cart-empty" v-else>
            <div id="content"><span class="pomegrange"><strong>购物车空空如也</strong></span></div>
        </div>
    </div>
</template>

<script>
export default {
    name:'Cart',
    computed:{
        cart(){
            return this.$store.getters.cart;
        },
        'totalPrice':function(){
            let totalPrice = 0;
            let cart = this.$store.getters.cart;
            for(let i in cart){
                totalPrice += cart[i].price;
            }
            return totalPrice;
        }
    },
    methods:{
        removeItem(item){
            return this.$store.dispatch('remove_item',item)
        }
    }

}
</script>

<style>
 .cart ul {
    padding: 0;
  }
  .cart ul> li {
    list-style: none;
    padding: 4px 8px;
  }
  .popover {
    min-width: 320px;
  }
  .cart-empty {
    padding: 100px;
    border-radius: 4px;
    border: 2px dashed rgb(170, 170, 170);
  }
  #content {
    top: 50%;
    width: 100%;
    text-align: center;
    left: 0;
  }
</style>

router/index.js

import Vue from 'vue'
import Router from 'vue-router'
import Index from '@/components/Index'
import Cart from '@/components/Cart'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      name: 'Index',
      component: Index
    },
    {
      path: '/index',
      name: 'Index',
      component: Index
    },
    {
      path: '/cart',
      name: 'Cart',
      component: Cart
    }
  ]
})

App.vue

<template>
  <div id="app">
    <cart-nav></cart-nav>
    <router-view></router-view>
  </div>
</template>

<script>
import Nav from './components/Nav.vue'
import store from './action/store'

export default {
  name: 'App',
  store,
  data(){
    return{

    }
  },
  components:{
    'cart-nav':Nav
  }
}
</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

main,js

// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
import VueRouter from 'vue-router';

Vue.config.devtools=true
Vue.use(VueRouter)

/* eslint-disable no-new */
new Vue({
  el: '#root',
  router,
  components: { App },
  template: '<App/>'
})

action/store.js

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)

const state = {
    iPhone6S:{
        name:'Apple/苹果 iPhone 6S',
        desc:'3D Touch、1200万像素、4k视频,强大功能于一身。',
        price:'5288 - 6888',
        isSelected:true,
        style:{
            '银色': 'http://o8yu724qs.bkt.clouddn.com/iphone6s-silver-select-2015.png',
            '深空灰色': 'http://o8yu724qs.bkt.clouddn.com/iphone6s-gray-select-2015.png',
            '金色': 'http://o8yu724qs.bkt.clouddn.com/iphone6s-gold-select-2015.png',
            '玫瑰金色': 'http://o8yu724qs.bkt.clouddn.com/iphone6s-rosegold-select-2015.png'
        }, 
        activeStyleUrl:'http://o8yu724qs.bkt.clouddn.com/iphone6s-silver-select-2015.png',
        storage:{
            '16GB':5288,
            '64GB':6088,
            '128GB':6888
        }
    },
    cart:[]
}

const mutations={
    CHANGE_STYLE(state,item){
        state.iPhone6S.activeStyle = item.styleName;
        state.iPhone6S.activeStyleUrl = item.styleUrl;
    },
    CHANGE_PRICE(state,item){
        state.iPhone6S.activeStorage = item.storage;
        state.iPhone6S.price = item.price;
        state.iPhone6S.isSelected = false;
    }, 
    ADD_ITEM(state){
        const activeStyle = state.iPhone6S.activeStyle === undefined?'银色':state.iPhone6S.activeStyle;
        const type = activeStyle+','+state.iPhone6S.activeStorage;
        const cartInfo = {
            type:type,
            count:1,
            price:state.iPhone6S.price
        };
        state.cart.push(cartInfo)
    },
    REMOVE_ITEM(state,cartInfo){
        for(var i=0; i<state.cart.length; i++) {
            if(state.cart[i] == cartInfo) {
                state.cart.splice(i, 1);
              break;
            }
        }
    }
}

const actions={
    change_style({commit},item){
        console.info("change_style")
        commit('CHANGE_STYLE',item)
    },
    change_price({commit},item){
        commit('CHANGE_PRICE',item)
    },
    add_item({commit}){
        commit('ADD_ITEM')
    },
    remove_item({commit},cartInfo){
        commit('REMOVE_ITEM',cartInfo)
    }
}

const getters={
    iPhone6S:state=>{
        return state.iPhone6S
    },
    cart:state=>{
        return state.cart
    }
}

export default new Vuex.Store({
    state,
    mutations,
    actions,
    getters
})

这里使用的是vue2.0,store.js里的mutations,actions,getters的用法是vuex,里面的原理还有待深入研究,此文章仅仅记录一下我的入门学习。欢迎一起讨论

扫描二维码关注公众号,回复: 2341093 查看本文章

猜你喜欢

转载自blog.csdn.net/jason_ss/article/details/81076904