此项目并非原创,仅记录一下,适合刚入门的小伙伴
Cart-Demo
.简单介绍几个主要的文件
components:项目页面构成的文件
-store.js:项目主要使用的js处理文件
-router/index.js:项目页面跳转配置路由
-App.vue:总组件,默认页面
-main.js:入口文件
<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 Cartrouter-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/苹果 iPhone6Sspan>
<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: ' '
})
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,里面的原理还有待深入研究,此文章仅仅记录一下我的入门学习。欢迎一起讨论