clone 开源的 Shopping

This commit is contained in:
sin
2019-03-04 15:28:16 +08:00
parent 78945c61a7
commit c9d71726fa
83 changed files with 9774 additions and 0 deletions

View File

@@ -0,0 +1,106 @@
<template>
<van-cell-group class="additional">
<van-card
:title="product.title"
:desc="product.desc"
:num="(iscard?null:product.quantity)"
style="background:#fff"
>
<template slot="thumb">
<img :src="product.imageURL" />
<p v-if="product.imageTag!=null&&product.imageTag!=''" class="image_tag">{{product.imageTag}}</p>
</template>
<template slot="tags">
<p class="price" v-if="product.price!=null&&product.price!=''" >
<span>{{product.price}}</span>
<van-tag v-if="product.tags!=null" v-for="tag in product.tags" :key="tag" plain type="danger">{{tag}}</van-tag>
</p>
<van-stepper v-if="iscard" v-model="product.quantity" :max="product.max" :min="product.min" />
</template>
</van-card>
<van-cell v-for="(gift,j) in product.gift" :key="j" :value="'x'+gift.quantity" >
<template slot="title">
<van-tag type="danger" v-if="j==0" >赠品</van-tag>
<span class="van-cell-text" :style="(j>0?'margin-left: 35px;':'')" >{{gift.title}}</span>
</template>
</van-cell>
<slot />
</van-cell-group>
</template>
<script>
export default {
name:'product-card',
props:{
product:Object,
iscard: {
type: Boolean,
default: false
},
}
}
</script>
<style lang="less">
.additional {
.van-cell {
padding: 0 15px;
font-size: 12px;
}
.van-cell:not(:last-child)::after{
border:0;
}
.van-card__title{
font-size: 14px;
}
.van-cell__title {
flex: 10;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.van-tag {
line-height: 12px;
margin-right: 5px;
}
.price {
color: #e93b3d;
font-size: 10px;
overflow: hidden;
height: 18px;
span {
font-size: 16px;
margin-right: 5px;
}
.van-tag{
font-size: 12px;
}
}
.van-stepper{
position: absolute;
bottom: 5px;
right: 5px;
&__plus{
width: 30px;
}
&__minus{
width: 30px;
}
}
.image_tag{
position: absolute;
bottom: 0;
width: 90px;
height: 20px;
line-height: 20px;
font-size: 10px;
color: #fff;
text-align: center;
background-color: rgba(0,0,0,.7);
}
}
.additional::after{
border-color: #f7f7f7;
}
</style>

View File

@@ -0,0 +1,22 @@
<template>
<div style="height:50px;">
<van-tabbar >
<van-tabbar-item icon="wap-home" to="/home">首页</van-tabbar-item>
<van-tabbar-item icon="wap-nav" to="/category" >分类</van-tabbar-item>
<van-tabbar-item icon="cart" to="/cart" >购物车</van-tabbar-item>
<van-tabbar-item icon="contact" to="/user/index">我的</van-tabbar-item>
</van-tabbar>
</div>
</template>
<script>
import { Tabbar, TabbarItem } from "vant";
export default {
name:'navigate',
components:{
[Tabbar.name]: Tabbar,
[TabbarItem.name]: TabbarItem,
}
}
</script>

View File

@@ -0,0 +1,30 @@
<template>
<van-nav-bar
:title="title"
left-text=""
left-arrow
@click-left="onBack"
/>
</template>
<script>
import { NavBar } from 'vant';
export default {
name:'headerNav',
components:{
[NavBar.name]: NavBar,
},
props:{
title:String,
},
methods: {
onBack() {
history.back();
},
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,183 @@
<template>
<div class="cap-cube" style="font-size:100%;width:100%;">
<div v-for="(item,index) in data.images" :key="index" class="cap-cube__item" :style="'width:'+item.imgwidth+'rem;'+item.style">
<a :href="item.link">
<img :src="item.src+'?w=375'" :style="'width:'+item.imgwidth+'rem;'" />
</a>
</div>
<div style="clear:both;"></div>
</div>
</template>
<script>
export default {
name: "cube",
props: {
data: Object
},
created: function() {
var gap = this.data.imagegap;
var margin = gap / 2;
var width = 375;
var max = 0;
switch (this.data.type) {
case "1":
max = 2;
width = (width - margin * 2) / 2;
break;
case "2":
max = 3;
width = (width - margin * 4) / 3;
break;
case "3":
max = 4;
width = (width - margin * 6) / 4;
break;
case "4":
max = 4;
width = (width - margin * 2) / 2;
break;
case "5":
max = 3;
width = (width - margin * 2) / 2;
break;
case "6":
max = 3;
width = (width - margin * 2) / 2;
break;
case "7":
max = 4;
width = (width - margin * 2) / 2;
break;
}
margin = margin / 50;
width = width / 50;
var imagelist = [];
for (var i = 0; i < max; i++) {
var imgwidth = width;
var item = this.data.imagelist[i];
var style = "";
switch (this.data.type) {
case "1":
{
if (i == 0) {
style = "margin-right:" + margin + "rem;";
} else {
style = "margin-left:" + margin + "rem;";
}
}
break;
case "2":
{
if (i == 0) {
style = "margin-right:" + margin + "rem;";
} else if (i == 1) {
style = "margin:0 " + margin + "rem;";
} else {
style = "margin-left:" + margin + "rem;";
}
}
break;
case "3":
{
if (i == 0) {
style = "margin-right:" + margin + "rem;";
} else if (i == 1 || i == 2) {
style = "margin:0 " + margin + "rem;";
} else {
style = "margin-left:" + margin + "rem;";
}
}
break;
case "4":
{
if (i == 0) {
style =
"margin-right:" +
margin +
"rem;margin-bottom:" +
margin +
"rem;";
} else if (i == 1) {
style =
"margin-left:" +
margin +
"rem;margin-bottom:" +
margin +
"rem;";
} else if (i == 2) {
style =
"margin-right:" + margin + "rem;margin-top:" + margin + "rem;";
} else {
style =
"margin-left:" + margin + "rem;margin-top:" + margin + "rem;";
}
}
break;
case "5":
{
if (i == 0) {
style = "margin-right:" + margin + "rem;";
} else if (i == 1) {
style =
"margin-left:" +
margin +
"rem;margin-bottom:" +
margin +
"rem;";
} else {
style =
"margin-left:" + margin + "rem;margin-top:" + margin + "rem;";
}
}
break;
case "6":
{
if (i == 0) {
imgwidth = width * 2;
style = "margin-bottom:" + margin + "rem;";
} else if (i == 1) {
style =
"margin-right:" + margin + "rem;margin-top:" + margin + "rem;";
} else {
style =
"margin-left:" + margin + "rem;margin-top:" + margin + "rem;";
}
}
break;
case "7":
{
if (i == 0) {
style = "margin-right:" + margin + "rem;";
} else if (i == 1) {
style =
"margin-right:" + margin + "rem;margin-top:" + margin + "rem;";
} else if (i == 2) {
imgwidth = width / 2 - margin;
style =
"margin-left:" +
margin +
"rem;margin-top:" +
margin +
"rem;margin-right:" +
margin +
"rem";
} else {
imgwidth = width / 2 - margin;
style =
"margin-left:" + margin + "rem;margin-top:" + margin + "rem;";
}
}
break;
}
item.style = style;
item.imgwidth = imgwidth;
imagelist.push(item);
}
this.data.images = imagelist;
},
computed: {}
};
</script>

View File

@@ -0,0 +1,64 @@
<template>
<div>
<van-swipe :autoplay="3000" v-if="data.type=='1'" :style="'height:'+height+'px'" >
<van-swipe-item v-for="(image,index) in data.imagelist" :key="index" >
<a :href="image.url">
<img v-lazy="image.src+''" style="width: 100%;" />
</a>
</van-swipe-item>
</van-swipe>
<ul v-if="data.type=='2'">
<li v-for="(image,index) in data.imagelist" :key="index" class="cap-image-ad__content" :style="'margin:'+data.imagegap+'px 0px;'">
<div class="image-wrapper">
<a :href="image.url">
<img alt="" class="cap-image-ad__image" v-lazy="image.src+''" />
</a>
</div>
</li>
</ul>
<div v-if="data.type=='3'||data.type=='4'||data.type=='5'" class='cap-image-ad__image-nav' style='overflow-x:scroll;' >
<div v-for="(item,index) in data.imagelist" :key="index" class="image-wrapper" :style="'width:'+(data.type=='3'?'80':(data.type=='4'?'40':'20'))+'%;margin-right:'+data.imagegap+'px;'">
<a :href="item.link" class="cap-image-ad__link cap-image-ad__link--image-nav" >
<div class="cap-image-ad__image">
<img :src="item.src+'?w=640'" style="width: 100%; " />
</div>
</a>
</div>
</div>
</div>
</template>
<script>
export default {
name:'imageAd',
components:{
},
props:{
data:Object
},
data(){
return{
height:0
}
},
created(){
if(this.data.imagelist.length==0||this.data.type!='1'){
return;
}
var that=this;
var image =this.data.imagelist[0];
let img = new Image()
img.src = image.src;
var width= window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
img.onload = function () {
that.height= Math.ceil(img.height/img.width * width);
}
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,36 @@
<template>
<div :class='(data.type == "1" ? "cap-image-ad__image-nav" : "cap-image-ad__slide cap-image-ad__text-nav")' :style='"overflow-x:"+(data.showtype == "1" ? "hidden" : "scroll")+"; background-color:"+data.backgroundcolor' >
<div v-if="data.type == '1'" v-for="(item,index) in data.imagelist" :key="index" class="image-wrapper" :style="'width:'+ data.width+'%; margin-right: 0px;'">
<a :href="item.link" class="cap-image-ad__link cap-image-ad__link--image-nav" :style="'color:'+data.color">
<div class="cap-image-ad__image">
<img v-lazy="item.src+'?w=320'" style="width: 100%; " />
</div>
<h3 v-if="item.title!=''" class="cap-image-ad__nav-title">{{item.title}}</h3>
</a>
</div>
<a v-if="data.type=='2'" v-for="(item,index) in data.imagelist" :key="index" :href="item.link" class="text-nav-wrapper" :style="'width:'+data.width+'%; color: '+data.color+'; background-color: '+data.backgroundcolor"><h3 class="cap-image-ad__nav-title">{{item.title}}</h3></a>
</div>
</template>
<script>
export default {
name:'imageText',
props:{
data:Object
},
created:function(){
var width = 0;
if (this.data.showtype == "1") {
width = 100 / this.data.imagelist.length;
}
else {
width = (100 * 0.95) / (this.data.shownumber - 1);
}
this.data.width=width;
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,30 @@
<template>
<div :style="divstyle" ><div :style="linestyle"></div></div>
</template>
<script>
export default {
name: 'page-line',
props: {
data: Object,
},
computed:{
divstyle(){
return{
height:"30px",
position:'relative',
margin:'0px '+this.data.margintype+'px'
};
},
linestyle(){
return{
position:'absolute',
top:'14px',
width:'100%',
borderTop:'1px '+(this.data.type==undefined?'solid':this.data.type)+" "+(this.data.color==undefined?'#000':this.data.color),
};
}
}
};
</script>

View File

@@ -0,0 +1,29 @@
<template>
<NoticeBar
:text="data.value"
:background="data.background"
:color="data.color"
/>
</template>
<script>
import { NoticeBar } from "vant";
export default {
name:'notice',
components:{
NoticeBar
},
props:{
data:Object
},
computed:{
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,81 @@
<template>
<div>
<ul :class="'cap-goods-list__container cap-goods-list__container--'+data.classname+' cap-goods-list__container--'+data.ParameterDictionary.showtype+' '+(data.ParameterDictionary.type=='6'?'nowrap':'')" >
<li v-if="productlist.length==0" style="width:100%;height:150px;border:0px;">
<div style="width:100%;height:150px;"></div>
</li>
<li v-for="(item,index) in productlist" :key="index" :class="'cap-goods-list__wrapper '+(data.ParameterDictionary.type=='3'?(index%3==0?'cap-goods-list__wrapper--hybrid-big ':'cap-goods-list__wrapper--hybrid-small '):'')">
<router-link :class="'cap-goods-list__item cap-goods-list__item--'+data.classname+' '+data.ParameterDictionary.showtype+' '+data.aclass" :to="'/product/'+item.id">
<div class="cap-goods-list__photo">
<img class="cap-goods-list__img lazy lazyload" v-lazy="item.imageURL+'?w='+((data.ParameterDictionary.type=='1'||data.ParameterDictionary.type=='3')?'750':'375')" />
</div>
<div :class="'cap-goods-list__info has-title has-price '+(data.ParameterDictionary.showtype == 'card'?'has-btn':'')">
<h3 class="title">{{item.title}}</h3>
<p class="sale-info">
<span class="sale-price">¥ {{item.price}}</span>
</p>
</div>
<div v-if="data.ParameterDictionary.showtype == 'card'" class="cap-goods-list__buy-btn-wrapper cap-goods-list__buy-btn-wrapper--4">
<button class="cap-goods-list__buy-btn-4 van-button van-button--default van-button--small">{{data.ParameterDictionary.buttonvalue}}</button>
</div>
</router-link>
</li>
</ul>
<div style="clear:both;"></div>
</div>
</template>
<script>
import {getProduct} from "../../api/page.js";
export default {
name:'product',
data () {
return {
productlist: []
}
},
props:{
data:Object
},
created:function(){
var id=this.data.PageSectionId;
var data=this.data;
var classname = "big";
var aclass = "";
switch (data.ParameterDictionary.type) {
case "1":
aclass = "cap-goods-list__item--btn1 cap-goods-list__item--ratio-3-2 cap-goods-list__item--whitespace";
break;
case "2":
classname = "small";
aclass = "cap-goods-list__item--btn1 cap-goods-list__item--padding";
break;
case "3":
classname = "hybrid";
aclass = "cap-goods-list__item--big cap-goods-list__item--hybrid-big cap-goods-list__item--btn1 cap-goods-list__item--padding";
break;
case "4":
classname = "list";
aclass = "cap-goods-list__item--btn4 cap-goods-list__item--padding";
break;
case "5":
classname = "three";
aclass = "cap-goods-list__item--btn4 cap-goods-list__item--padding";
break;
case "6":
classname = "three";
break;
}
data.classname=classname;
data.aclass=aclass;
getProduct(id).then(response => {
this.productlist=response;
})
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,60 @@
<template>
<div class="search-box" :style="boxstyle" >
<div class="search-box__view" :style="boxviewstyle">
<div class="search">
<div :class="'search__filed search__filed--'+data.textalign+' search__filed--'+(data.boxtype=='2'?'circle':'rect')" :style="'background-color:'+(data.boxcolor==undefined?'#ffffff':data.boxcolor)+';'">
<van-icon name="search" class="icon-search" size="14px" :color="data.color" />
<div class="cell field" :style="data.textalign=='left'?'':'width: 80px;'">
<div class="cell__value cell__value--alone">
<div class="field__body">
<input type="search" :placeholder="data.keyword==''||data.keyword==undefined?'商品搜索':data.keyword" class="field__control" />
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name:'search',
components:{
},
props:{
data:Object
},
created:function(){
if(this.data.position=='fixed'){
this.$emit('settopheight', 50);
}
},
computed:{
boxstyle(){
if(this.data.position=='fixed'){
return{
position:'fixed',
top: 0,
zIndex: 10,
}
}else{
return{}
}
},
boxviewstyle(){
return{
background: (this.data.backgroundcolor==undefined?"#f9f9f9":this.data.backgroundcolor),
paddingRight: '15px',
top:'0px' ,
}
},
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,25 @@
<template>
<div :style="style">{{data.value}}</div>
</template>
<script>
export default {
name:'page-text',
props:{
data:Object
},
computed:{
style(){
return{
position:'relative',
padding: '10px',
fontSize:(this.data.fontsize==undefined?'10':this.data.fontsize)+'px',
color:(this.data.color==undefined?'#000':this.data.color),
background:this.data.backgroundcolor,
textAlign:this.data.textalign,
}
}
}
}
</script>

View File

@@ -0,0 +1,28 @@
<template>
<a :href="data.link">
<div v-if="data.type == '1'" class="cap-title cap-title--normal" :style="'background-color:'+data.backgroundcolor+'; text-align:'+data.textalign+';color:'+data.color">
<h2 class="cap-title__main">{{data.title}}</h2>
<p v-if="data.subtitle!=undefined&&data.subtitle!=''" class="cap-title__sub"><span class="cap-title__sub-title">{{data.subtitle}}</span></p>
</div>
<div v-if="data.type == '2'" class="title" :style="'background:'+data.backgroundcolor+';text-align:'+data.textalign">
<span :style="data.color==''?'':'border-bottom: 1px solid '+data.color+';color:'+data.color+';'">{{data.title}}</span>
</div>
</a>
</template>
<script>
export default {
name:'page-title',
props:{
data:Object
},
computed:{
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,20 @@
<template>
<div :style="style"></div>
</template>
<script>
export default {
name: 'whitespace',
props: {
data: Object,
},
computed: {
style() {
return {
height: (this.data.height==undefined?'30':this.data.height)+"px",
};
}
}
};
</script>

View File

@@ -0,0 +1,67 @@
<template>
<div>
<van-nav-bar left-arrow class="product-serach"
@click-left="onBack"
>
<van-search
v-model="value"
placeholder="请输入搜索关键词"
background="#fff"
show-action
@search="onSearch"
slot="title"
>
<div slot="action" @click="onSearch">搜索</div>
</van-search>
</van-nav-bar>
</div>
</template>
<script>
import { Search } from "vant";
export default {
name:'searchtop',
components:{
[Search.name]:Search,
},
data(){
return{
value:'',
}
},
methods:{
onSearch() {
console.log(this.value);
},
onBack() {
history.back();
},
}
}
</script>
<style lang="less">
.product-serach{
.van-search{
padding: 7px 0;
background: #fff;
.van-cell{
background: rgb(242, 242, 242);
margin-right: 10px;
}
.van-search__action{
background: #e93b3d;
color: #fff;
}
}
.van-nav-bar__title{
margin: 0;
max-width: 100%;
padding-left: 40px;
padding-right: 20px;
}
}
</style>