原图

图片 1

要求

  1. 请修改下面的test.html来完成,仅依赖 https://cdn.jsdelivr.net/npm/vue@2/dist/vue.jshttps://unpkg.com/axios/dist/axios.min.js 不引入新的三方依赖。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>测试</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<style>
* {
box-sizing: border-box;
margin: 0;
}

body {
background-color: #f0f0f0;
font-size: 14px;
}

/**
* 其它样式
*/
</style>
</head>

<body>
<div id="root">
<!-- 页面实现 -->
<div v-for="sku in skuList">
<sku :data="sku"></sku>
</div>
<cart :data="cartData">
</cart>
</div>

<script>
/**
* 商品组件实现
*/
Vue.component('sku', {
props: ['data'],
methods: {},
template: '<div></div>'
})

/**
* 购物篮组件实现
*/
Vue.component('cart', {
props: ['data'],
methods: {},
template: '<div></div>'
})

new Vue({
el: '#root',
data: {
skuList: [],
cartData: {}
},
mounted() {},
methods: {}
})
</script>
</body>
</html>
  1. 在test.html里实现两个组件: 商品组件和购物车组件。主页面里引用这两个组件。

image-20220812141248446

  1. 商品数据可以从https://test.aleph-lop.com/test/query-sku-result.json 获取(get请求),数据结构如下

image-20220812141356320

  1. 页面详细说明 购物篮默认不显示,当有商品加入之后再显示

image-20220812141441299

  1. 颜色

image-20220812141539955

实现

实际上还可以把 上面的 综合 销量 价格 封装成一个tabs组件 , 如果有更好的方法请再下面评论!

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<style>
* {
box-sizing: border-box;
margin: 0;
}

body {
background-color: #F0F0F0;
font-size: 14px;
}

.tabstitls {
display: flex;
}

.tabstitls div {
padding: 20px;
}

.active {
color: red;
}

.tabs {
border-bottom: 1px solid #D7D7D7;
}

.goodsleftimg {
display: flex;
flex: 2;
justify-content: center;
align-items: center;
}

.goodsleftimg img {
/* width: 100px;
height: 110px; */
width: 100%;
height: 100%;
margin-right: 20px;
border-radius: 10px 0px 0px 10px;
}

.goodsitem {
display: flex;
margin-top: 15px;
border: 1px solid white;
height: 110px;
border-radius: 15px;
margin-left: 20px;
margin-right: 20px;
background-color: #FFFFFF;
}

.goodsname {
font-size: 14px;
font-weight: bold;
overflow: hidden;
word-break: break-all;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}

.goodsright {
display: flex;
flex: 3;
flex-direction: column;
justify-content: space-around;
}

.goodsprice {
color: red;
font-weight: bold;
}

.sp {
font-weight: bold;
font-size: 10px;
}

.cartotal {
position: fixed;
left: 0;
bottom: 0;
width: 100%;
height: 60px;
background-color: #fff;
display: flex;
border-radius: 15px 15px 0px 0px;
}

.ct {
margin-top: 80px;
}

.check {
display: flex;
flex: 2;
justify-content: center;
align-items: center;
}

.goodgtod {
display: flex;
flex-direction: column;
font-size: 12px;
flex: 5;
justify-content: center;
align-items: flex-end;
}

.totap span {
font-size: 12px;
}

.goodxd {
display: flex;
flex: 2;
justify-content: center;
align-items: center;
}

button {
background-color: #ED8135;
height: 25px;
border-radius: 15px;
color: white;
border-color: #ED8135;
}

.js {
color: #FF7B0D;
}

.bd {
line-height: 16px;
border: 1px solid #FF2b2c;
border-radius: 3px;
float: left;
height: auto;
}

.fire {
display: inline-block;
width: 17px;
height: 17px;
border-radius: 2px 0px 0px 2px;
line-height: 17px;
text-align: center;
background-color: #FF2b2c;
font-size: 12px;
}

.pm {
font-size: 10px;
padding-left: 5px;
padding-right: 5px;
}

.btm {
display: flex;
}

.zhr {
display: flex;
flex-direction: column;
font-size: 12px;
justify-content: center;
align-items: flex-end;
padding-right: 70px;
}

.con {
background: white;
border: 1px solid #0c9949;
padding: 3px;
position: relative;
border-radius: 3px;
font-size: 10px;
font-weight: bold;
width: fit-content;
width: -webkit-fit-content;
width: -moz-fit-content;
color: #0c9949;
}

.con::after {
display: block;
content: "◆";
position: absolute;
font-size: 20px;
left: 10px;
bottom: -10px;
color: white;
}

.con::before {
display: block;
content: "◆";
position: absolute;
font-size: 20px;
left: 10px;
bottom: -11px;
color: #0c9949;
}

.xhx {
text-decoration: line-through;
color: #D7D7D7;
}
</style>
</head>
<body>
<div id="root">
<div class="tabs">
<div class="tabstitls">
<div @click="no(1)" :class="item==1 ? 'active':''">综合</div>
<div @click="no(2)" :class="item==2 ? 'active':''">销量</div>
<div @click="no(3)" :class="item==3 ? 'active':''">价格</div>
</div>
</div>
<div v-for="sku in skuList">
<sku :data="sku" @mk="getgoods"></sku>
</div>
<div class="ct">
<cart :data="cartData" v-if="cartData.coun>=1"></cart>
</div>
</div>
</body>
<script>
/**
* 商品组件实现
*/
Vue.component('sku', {
props: ['data'],
methods: {
addcar(goods){
this.$emit('mk',goods);
}
},
template: `
<div class="goodsitem">
<div class="goodsleftimg">
<img :src="data.bigPicUrl"/>
</div>
<div class="goodsright">
<div class="goodsname">{{ data.itemName }}</div>
<div v-if="data.rank!==undefined" class="pbd">
<div class="bd">
<span class="fire">🔥</span><span class="pm">{{ data.categoryName }}榜单第
{{ data.rank }}</span>
</div>
</div>
<span v-show="data.discountPrice!=undefined" class="con">{{ data.discountPrice }}
折优惠 | 限购10件</span>
<div class="btm">
<div class="zhr">
<div v-if="data.discountPrice!=undefined" class="goodsprice">
<span>{{ (data.discountPrice * 10 / data.price).toFixed(2) }}</span>
</div>
<div :class="data.discountPrice!=undefined ? 'goodsprice xhx':'goodsprice'"><span
class="sp"></span>{{ data.price }}
</div>
</div>
<div class="goodboot">
<button @click="addcar(data)">加入购物车</button>
</div>
</div>
</div>
</div>
`
})

/**
* 购物篮组件实现
*/
Vue.component('cart', {
props:['data'],
methods: {},
template: `
<div class="cartotal">
<div class="check">
已选{{data.coun}}
</div>
<div class="goodgtod">
<div class="totap">
合计 <span>{{data.cprice}}</span>
</div>
<div class="js">节省 <span>{{data.spr}}</span></div>
</div>
<div class="goodxd">
<button>去下单</button>
</div>
</div>
`
})
new Vue({
el: '#root',
data: {
skuList: [],
cartData: {},
item:1,
goodcar:[]
},
mounted() {
//获取列表数据
axios.get('https://test.aleph-lop.com/test/query-sku-result.json').then((res) => {
if (res.data.success === true) {
let goods = res.data.model;
goods.sort(function (a, b) {
return a.id - b.id
});
//处理是否有折扣
for(let i=0;i<res.data.model.length;i++){
if(res.data.model[i].discountPrice!==undefined){
res.data.model[i].zprice=(res.data.model[i].discountPrice*10 / res.data.model[i].price).toFixed(2);
}else{
res.data.model[i].zprice=res.data.model[i].price;
}
}
this.skuList = goods;
} else {
console.log('请求错误!');
}
});
},
methods: {
//切换
no(e){
this.item=e;
if(e===1){
this.skuList.sort(function (a,b){return a.id-b.id})
}else if(e===2){
this.skuList.sort(function (a,b){return b.id-a.id})
}else if(e===3){
this.skuList.sort(function(a,b){return a.zprice-b.zprice})
}
},
getgoods(e){
this.goodcar.push(e);
let price=0;
let zp=0;
for (let i=0;i<this.goodcar.length;i++){
price+=this.goodcar[i].price;
zp+=parseFloat(this.goodcar[i].zprice);
}
let pl=Math.floor(price-zp);
this.cartData={
coun: this.goodcar.length,
cprice: (price).toFixed(2),
spr: pl
}
}
}
})
</script>
</html>

效果

image-20220812141727296