Vue 仿淘寶購物車
阿新 • • 發佈:2019-01-20
效果圖:
我們只是做演示,其中的資料應該從後臺來取得,這裡我們模擬幾條資料來顯示。
頁面佈局:
<div id="shop_car">
<section class="car_main">
<!--頂部列表-->
<div class="car_head">
<ul class="car_top">
<li class="car_check_all">
<input type="checkbox" id="check_all" v-model="checked_all" @click="all_products_checked"/>
<label for="check_all">全選</label>
</li>
<li class="car_information">商品資訊</li>
<li class="car_price">單價</li>
<li class="car_number">數量</li>
<li class="car_amount">金額</li>
<li class="car_operation">操作</li>
</ul>
</div>
<!--購物車為空時展示頁面-->
<template v-if="goods.length == 0">
<div class="cart_empty">
您的購物車還是空的哦,快去挑選您喜歡的東西吧.
</div>
</template >
<!--購物車詳情展示-->
<template v-else>
<div v-for="(shop,shop_index) in goods">
<!--當店鋪下面有已購買商品的時候顯示該店鋪和商品資訊-->
<div v-if="shop.list.length != 0">
<!--商品詳細標題-->
<div class="shop_info">
<ul>
<li class="shop_info_check_all">
<input type="checkbox" v-model="shop.all_checked" @click="shop_all_check(shop_index)">
</li>
<li>
<img :src="shop.url" class="shop_icon"/>
</li>
<li>
<span style="margin-left: 10px;">店鋪:</span>
</li>
<li>
<a :href="shop.href">{{shop.shop_name}}</a>
</li>
<li>
<img src="../../static/ShopCar/wangxin.jpg" class="shop_icon"/>
</li>
<li>
<img src="../../static/ShopCar/youhui.png" v-if="shop.discount.length != 0" class="shop_discount"/>
</li>
</ul>
</div>
<div v-for="(product,product_index) in shop.list" class="product"
v-bind:class="[product.product_checked ? 'selected_styles' : '']">
<div class="product_description" v-if="product.product_description != ''">
<div class="product_description_bg">{{product.product_description}}</div>
</div>
<div class="product_details">
<!--商品是否選中-->
<div class="product_check">
<input type="checkbox" v-model="product.product_checked"
@click="product_checked_click(shop_index,product_index)"/>
</div>
<!--商品圖片-->
<div class="product_img">
<img :src="product.url" style="width: 100px;height: 100px"/>
</div>
<!--商品名稱-->
<div class="product_shop_info">
<div class="product_shop_name">
<a :href="product.href">{{product.product_name}}</a>
</div>
<div class="product_shop_icon">
<img src="../../static/ShopCar/xcard.png" title="銀聯支付"/>
<img src="../../static/ShopCar/7day.png" title="7天內無條件退換"/>
<img src="../../static/ShopCar/wuyou.png" title="消費者保障服務,商家承若如實描述"/>
</div>
</div>
<!--商品尺寸顏色等屬性-->
<div class="product_type_select" @mouseenter="enter(shop_index,product_index)"
@mouseleave="leave(shop_index,product_index)">
<div class="product_type_all">
<div v-for="type in product.product_type" class="product_type">
{{type.key}}: {{type.value}}
</div>
</div>
<div class="product_edit" id="product_edit"
v-bind:class="[product.edit_type? 'product_edit_type_true':'product_edit_type_false']">
<button class="product_edit_button">編輯</button>
</div>
</div>
<!--商品價格-->
<div class="product_price">
<div v-if="product.origin_price" class="product_price_origin">
¥{{product.origin_price | priceFilter}}
</div>
<div class="product_price_current">
¥{{product.current_price | priceFilter}}
</div>
</div>
<!--商品數量-->
<div class="product_number">
<div class="product_number_content">
<div class="product_number_button">
<button v-if="product.number > 1" @click="product_reduce(shop_index,product_index)">-</button>
</div>
<div class="product_number_input">
<input type="number" v-model="product.number" readonly/>
</div>
<div class="product_number_button" @click="product_add(shop_index,product_index)">
<button>+</button>
</div>
</div>
</div>
<!--金額統計-->
<div class="product_amount">
<div class="product_total_price">¥{{ product_total_price(shop_index,product_index) | priceFilter}}
</div>
</div>
<!--操作選項-->
<div class="product_operation">
<div>
<button>移入收藏夾</button>
</div>
<div>
<button @click="product_del(shop_index,product_index)">刪除</button>
</div>
<div>
<button>相似寶貝</button>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<!--底部頁面-->
<div class="car_foot_bar">
<div class="car_foot_settle">
<div class="piece">已選商品 <strong class="piece_num">{{selected_products}}</strong> 件</div>
<div class="totalMoney">合計 (不含運費) : <strong class="total_text">{{total_amount | priceFilter}}</strong> 元</div>
<div class="settle_accounts">
<button class="settle_button" :disabled="selected_products == 0 ? true : false" @click="shop_settle">
買單
</button>
</div>
</div>
</div>
</section>
</div>
Vue例項:
export default {
name: 'VShopCar',
data() {
return {
goods: [
{
shop_name: 'cocoessence旗艦店',
url: '../../static/ShopCar/shop.png',
href: 'https://cocoessence.tmall.com',
discount: ['2件9.8折'],
all_checked: false,
list: [
{
product_name: '酒店空氣清新劑家用臥室持久留香衛生間除味劑除臭香薰噴香機香水',
product_description: '空噴買2送',
url: '../../static/ShopCar/shop1.jpg',
href: 'https://detail.tmall.com/item.htm?spm=a1z0d.6639537.1997196601.4.ff9a7484vD2sXY&id=527905990976',
edit_type: false,
product_type: [
{
id: 1,
key: '顏色分類',
value: '祖馬long·小蒼蘭(2瓶)'
},
{
id: 2,
key: '顏色分類',
value: '寶石藍綠;小蒼蘭(2瓶)'
}
],
current_price: 32.80,
origin_price: 68.00,
number: 1,
product_checked: false,
},
{
product_name: '遇見香芬COCO沐浴露持久留香72小時男女學生香水補水家庭裝非美白',
product_description: '普通商品',
url: '../../static/ShopCar/shop2.jpg',
href: 'https://detail.tmall.com/item.htm?spm=a1z0d.6639537.1997196601.13.6e517484kyYSnq&id=39252128018',
edit_type: false,
product_type: [
{
id: 1,
key: '淨含量',
value: '750ML【持久留香】',
}
],
current_price: 36.80,
origin_price: 98.00,
number: 1,
product_checked: false,
}
]
},
{
shop_name: 'HermanMiller旗艦',
url: '../../static/ShopCar/shop.png',
href: 'https://hermanmiller.tmall.com/',
discount: [],
all_checked: false,
list: [
{
product_name: 'Herman Miller Embody 座椅 標準配置【Rhythm織物】',
product_description: '空噴買2送',
url: '../../static/ShopCar/shop3.jpg',
href: 'https://detail.tmall.com/item.htm?spm=a1z0d.6639537.1997196601.4.ff9a7484vD2sXY&id=527905990976',
edit_type: false,
product_type: [
{
id: 1,
key: '扶手型別',
value: '升降扶手'
},
{
id: 2,
key: '顏色分類',
value: '藍莓色'
},
{
id: 3,
key: '五星腳材質',
value: '鋼製腳'
}
],
current_price: 9992.00,
origin_price: 0,
number: 1,
product_checked: false,
}
]
},
{
shop_name: '佳士優電器專營店',
url: '../../static/ShopCar/shop.png',
href: 'https://jiashiyoudq.tmall.com/',
discount: [],
all_checked: false,
list: [
{
product_name: 'Panasonic松下音響 無線話筒 便攜擴音器WS-X66教學會議演講培訓',
product_description: '空噴買2送',
url: '../../static/ShopCar/shop4.jpg',
href: 'https://jiashiyoudq.tmall.com/',
edit_type: false,
product_type: [
{
id: 1,
key: '顏色分類',
value: '最佳套餐WS-X66音響+wx4800話筒'
}
],
current_price: 2950.00,
origin_price: 3050.00,
number: 1,
product_checked: false,
}
]
},
{
shop_name: '天貓超市',
url: '../../static/ShopCar/shoptao.png',
href: 'https://chaoshi.tmall.com',
discount: ['全場大促銷'],
all_checked: false,
list: [
{
product_name: '韓伊橄欖Olive潤膚清爽沐浴露去油沐浴乳 滋潤清香洗澡液500ml\n',
product_description: '超值換購活動',
url: '../../static/ShopCar/shop5.jpg',
href: 'https://chaoshi.tmall.com',
edit_type: false,
product_type: [
{
id: 1,
key: '顏色分類',
value: '500ml'
}
],
current_price: 25.90,
origin_price: 0,
number: 1,
product_checked: false,
}
]
}
],
// 其他屬性資料
checked_all: false
}
},
methods: {
// 結算
shop_settle() {
alert('大哥微信支付吧,快來掃我!')
},
// 滑鼠移入分類資訊顯示編輯按鈕
enter(shop_index, product_index) {
this.goods[shop_index].list[product_index].edit_type = true;
},
// 滑鼠移出分類資訊隱藏編輯按鈕
leave(shop_index, product_index) {
this.goods[shop_index].list[product_index].edit_type = false;
},
// 商品總價
product_total_price(shop_index, product_index) {
var product = this.goods[shop_index].list[product_index]
return product.number * product.current_price
},
// 減購商品,每次減少1
product_reduce(shop_index, product_index) {
var product = this.goods[shop_index].list[product_index]
if ((product.number - 1)) {
product.number--
}
},
// 加購,每次加1
product_add(shop_index, product_index) {
var product = this.goods[shop_index].list[product_index]
if ((product.number + 1) < 100) {
product.number++
}
},
// 刪除購買商品
product_del(shop_index, product_index) {
this.goods[shop_index].list.splice(product_index, 1)
},
// 店鋪下屬商品全部選擇時
shop_all_check(shop_index) {
var shop = this.goods[shop_index]
shop.all_checked = !shop.all_checked
for (var i = 0; i < shop.list.length; i++) {
shop.list[i].product_checked = shop.all_checked;
}
},
// 商品選擇時
product_checked_click(shop_index, product_index) {
var product = this.goods[shop_index].list[product_index]
product.product_checked = !product.product_checked
// 檢測是否該店鋪內的商品全選
for (var i = 0; i < this.goods[shop_index].list.length; i++) {
if (!this.goods[shop_index].list[i].product_checked) {
this.goods[shop_index].all_checked = false
this.checked_all = false
return;
}
}
this.goods[shop_index].all_checked = true
// 檢測購物車內的商品是否全部選中
for (var i = 0; i < this.goods.length; i++) {
if (!this.goods[i].all_checked) {
this.checked_all = false
return
}
}
this.checked_all = true
},
// 檢測購物車內的商品全部
all_products_checked() {
this.checked_all = !this.checked_all
for (var i = 0; i < this.goods.length; i++) {
this.goods[i].all_checked = this.checked_all
for (var j = 0; j < this.goods[i].list.length; j++) {
this.goods[i].list[j].product_checked = this.checked_all
}
}
},
},
filters: {
// 金額顯示過濾 兩位小數點,不足補0
priceFilter(value) {
var value = Math.round(parseFloat(value) * 100) / 100;
var xsd = value.toString().split(".");
if (xsd.length == 1) {
value = value.toString() + ".00";
return value;
}
if (xsd.length > 1) {
if (xsd[1].length < 2) {
value = value.toString() + "0";
}
return value;
}
}
},
computed: {
// 已選擇商品數目
selected_products() {
var selected_products = 0
for (var i = 0; i < this.goods.length; i++) {
var product = this.goods[i].list
for (var j = 0; j < product.length; j++) {
if (product[j].product_checked) {
selected_products++
}
}
}
return selected_products
},
// 購買商品總金額
total_amount() {
var total_price = 0.00
for (var i = 0; i < this.goods.length; i++) {
var product = this.goods[i].list
for (var j = 0; j < product.length; j++)
if (product[j].product_checked) {
total_price += product[j].number * product[j].current_price
}
}
return total_price
},
// 購物車全選
all_checked() {
for (var i = 0; i < this.goods.length; i++) {
if (!this.goods[i].all_checked) {
return false
}
}
return true
}
}
}
樣式:
<style scoped>
.car_main {
position: relative;
width: 980px;
margin: 0px auto;
padding: 0px 0px;
min-height: 250px;
}
.car_head {
width: 100%;
height: 45px;
line-height: 45px;
color: #3c3c3c;
font-size: 14px;
padding: 0px;
border-bottom: 1px solid #DCDCDC;
}
.car_top {
width: 100%;
height: 50px;
}
ul {
list-style: none;
}
li {
float: left;
text-align: left;
}
.car_check_all {
position: relative;
width: 10%;
left: -20px;
}
.car_check_all input[type="checkbox"] {
}
.car_check_all label {
}
.car_information {
width: 45%;
}
.car_price {
width: 11%;
}
.car_number {
width: 10%;
}
.car_amount {
width: 11%;
}
.cart_empty {
position: absolute;
width: 100%;
top: 50%;
text-align: center;
}
.car_foot_bar {
position: absolute;
width: 100%;
height: 45px;
font-size: 14px;
color: #3c3c3c;
margin-top: 15px;
}
.car_foot_settle {
float: right;
}
.piece {
float: left;
height: 45px;
line-height: 45px;
}
.totalMoney {
float: left;
margin-left: 20px;
height: 45px;
line-height: 45px;
}
.settle_accounts {
float: left;
margin-left: 20px;
height: 45px;
line-height: 45px;
}
.piece_num {
color: red;
}
.total_text {
color: red;
font-size: 18px;
}
.settle_button {
width: 100px;
height: 45px;
line-height: 45px;
border: none;
outline: none;
background-color: red;
}
.settle_button:disabled {
background-color: #eeefff;
}
.shop_info {
width: 100%;
height: 20px;
margin-top: 20px;
margin-bottom: 10px;
font-size: 12px;
align-items: center;
display: flex;
}
.shop_info_check_all {
position: relative;
width: 10px;
left: -20px;
}
.shop_info li a {
text-decoration: none;
margin-right: 10px;
color: #3c3c3c;
}
.shop_info li a:hover {
color: red;
text-decoration: underline;
}
.shop_icon {
width: 16px;
height: 16px;
}
.shop_discount {
width: 60px;
height: 20px;
margin-left: 10px;
}
.product {
width: 100%;
border: 1px solid #DCDCDC;
background: #F5F5F5;
}
.selected_styles {
background: lightgoldenrodyellow;
}
.product_details {
width: 100%;
height: 145px;
padding-left: 20px;
}
.product_description {
width: 100%;
height: 25px;
background: white;
font-size: 12px;
padding-left: 50px;
align-items: center;
display: flex;
}
.product_description_bg {
width: fit-content;
background: #eee;
height: 20px;
line-height: 20px;
}
.product_check {
float: left;
margin-top: -8px;
padding-top: 20px;
}
.product_img {
float: left;
padding-top: 20px;
}
.product_shop_info {
height: 100px;
float: left;
padding-left: 10px;
position: relative;
width: 220px;
padding-right: 20px;
padding-top: 20px;
}
.product_shop_name {
font-size: 12px;
text-align: left;
}
.product_shop_name a {
text-decoration: none;
letter-spacing: 2px;
color: #3c3c3c;
align-content: left;
}
.product_shop_name <