原图
要求
- 请修改下面的test.html来完成,仅依赖 https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js 和 https://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>
|
- 在test.html里实现两个组件: 商品组件和购物车组件。主页面里引用这两个组件。
- 商品数据可以从https://test.aleph-lop.com/test/query-sku-result.json 获取(get请求),数据结构如下
- 页面详细说明 购物篮默认不显示,当有商品加入之后再显示
- 颜色
实现
实际上还可以把 上面的 综合 销量 价格 封装成一个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: 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>
|
效果