vue从创建到完整的饿了么(12)miste.vue

说明

1.上一章–组件的使用(svg及watch的简单使用)
2.苍渡大神的项目源码–项目源码地址
3.UI框架–MintUI
4.数据接口地址–API地址
5.下一章–饿了么loading图

开始

1.UI图
《vue从创建到完整的饿了么(12)miste.vue》

2.miste.vue 修改如下

<template>
  <div>
    <mt-header fixed  class="fs1-2" title="标题过长会隐藏后面的内容啊哈哈哈哈">
      <router-link to="/" slot="left">
        <div><icon class="search2" name="search2" ></icon></div>
      </router-link>
      <mt-button class="fs0-8" slot="right">登录|注册</mt-button>
    </mt-header>

    <div class="padtop40">
      <mt-swipe class="myswipe" :auto="0">
        <mt-swipe-item v-for="items in category" :key="items.id" class="myitem">
          <div v-for="item in items">
            <div class="imgbox"><img :src="imgBaseUrl+item.image_url"></div>
            <div class="fs0-8 col9f mgtop5">{{item.title}}</div>
          </div>
        </mt-swipe-item>
      </mt-swipe>

      <div class="mgtop10 bgfff maindiv">
        <div class="ih30 pad10">
          <div class="svgbox left">
            <icon name="shop" class="shopicon"></icon>
          </div>
          <div class="fs0-8 left col9f mgleft10">
            附近商家
          </div>
        </div>

        <div class="shoplist after">
            <div class="shopimgbox">
                <img >
            </div>
            <div class="rightbox">
                <div class="shoptop">
                  <span class="pinpai fs10 mgl">品牌</span>
                  <span class="shopname">周哈黑鸭</span>
                  <span class="rightspan right fs10 mgr"><span class="">保</span><span class="">准</span><span class="">票</span></span>
                </div>
                <div class="xxdiv">
                  <div class="xxbox fs10 mgl">
                    <span><icon name="xx" class="xx"></icon></span>
                    <span><icon name="xx" class="xx"></icon></span>
                    <span><icon name="xx" class="xx"></icon></span>
                    <span class="xxspan1"><icon name="xx2" class="xx"></icon><span class="xxspan2 w5"><icon name="xx" class="xx"></icon></span></span>
                    <span><icon name="xx2" class="xx"></icon></span>
                  </div>
                  <span class="colred fs10 mgl mgleft8">4.4</span>
                  <span class="fs10 mgl">月售125单</span>
                  <span class="rightspan fs10 right mgr">
                      <span class="fn ">蜂鸟专送</span>
                      <span class="zs ">准时达</span>
                  </span>
                </div>
                <div class="shopfoot">
                    <div><span class="fs10 mgl">¥20起送/配送费约¥5</span></div>
                    <div><span class="right fs10 mgr"><span class="">102.3公里/</span><span class="col">15小时21分钟</span></span></div>
                </div>
            </div>
        </div>

        <div class="shoplist after">
            <div class="shopimgbox">
                <img >
            </div>
            <div class="rightbox">
                <div class="shoptop">
                  <span class="pinpai fs10 mgl">品牌</span>
                  <span class="shopname">周哈黑鸭</span>
                  <span class="rightspan right fs10 mgr"><span class="">保</span><span class="">准</span><span class="">票</span></span>
                </div>
                <div class="xxdiv">
                  <div class="xxbox fs10 mgl">
                    <span><icon name="xx" class="xx"></icon></span>
                    <span><icon name="xx" class="xx"></icon></span>
                    <span><icon name="xx" class="xx"></icon></span>
                    <span class="xxspan1"><icon name="xx2" class="xx"></icon><span class="xxspan2 w5"><icon name="xx" class="xx"></icon></span></span>
                    <span><icon name="xx2" class="xx"></icon></span>
                  </div>
                  <span class="colred fs10 mgl mgleft8">4.4</span>
                  <span class="fs10 mgl">月售125单</span>
                  <span class="rightspan fs10 right mgr">
                      <span class="fn ">蜂鸟专送</span>
                      <span class="zs ">准时达</span>
                  </span>
                </div>
                <div class="shopfoot">
                    <div><span class="fs10 mgl">¥20起送/配送费约¥5</span></div>
                    <div><span class="right fs10 mgr"><span class="">102.3公里/</span><span class="col">15小时21分钟</span></span></div>
                </div>
            </div>
        </div>

        <div class="shoplist after">
            <div class="shopimgbox">
                <img >
            </div>
            <div class="rightbox">
                <div class="shoptop">
                  <span class="pinpai fs10 mgl">品牌</span>
                  <span class="shopname">周哈黑鸭</span>
                  <span class="rightspan right fs10 mgr"><span class="">保</span><span class="">准</span><span class="">票</span></span>
                </div>
                <div class="xxdiv">
                  <div class="xxbox fs10 mgl">
                    <span><icon name="xx" class="xx"></icon></span>
                    <span><icon name="xx" class="xx"></icon></span>
                    <span><icon name="xx" class="xx"></icon></span>
                    <span class="xxspan1"><icon name="xx2" class="xx"></icon><span class="xxspan2 w5"><icon name="xx" class="xx"></icon></span></span>
                    <span><icon name="xx2" class="xx"></icon></span>
                  </div>
                  <span class="colred fs10 mgl mgleft8">4.4</span>
                  <span class="fs10 mgl">月售125单</span>
                  <span class="rightspan fs10 right mgr">
                      <span class="fn ">蜂鸟专送</span>
                      <span class="zs ">准时达</span>
                  </span>
                </div>
                <div class="shopfoot">
                    <div><span class="fs10 mgl">¥20起送/配送费约¥5</span></div>
                    <div><span class="right fs10 mgr"><span class="">102.3公里/</span><span class="col">15小时21分钟</span></span></div>
                </div>
            </div>
        </div>



      </div>
    </div>

    <foot></foot>
  </div>
</template>

<script>
import foot from '../../components/foot/foot'

export default {
  data () {
    return {
      category:[],
      imgBaseUrl:'https://fuss10.elemecdn.com', //图片域名地址
      shoplist:""
    }
  },
  components:{
  //注册组件
    foot
  },
  mounted:function(){
  //生命周期
      //分类
      this.$http.get('http://cangdu.org:8001/v2/index_entry').then(response => {
        console.log(response);
        var mybody=response.body;
        var num=parseInt(mybody.length/8);
        var category=[];
        var arr=[];
        for(var i=0;i<num;i++){
           arr=[];
          for(var h= 0;h<8;h++){
            arr.push(mybody[i*8+h]);
          }
          category.push(arr);
        }
        arr=[];
        if(num*8<mybody.length){
          for(var k=num*8;k<mybody.length;k++){
              arr.push(mybody[num*8+k]) 
          }
          category.push(arr);
        }
        this.category=category;
        console.log(this.category);
      }, response => {
        console.log(response);
        
      });
      
  },
  computed:{
  //计算属性
    
  },
    methods:{
  //函数

  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.fs10{
  font-size: 12px;
  transform: scale(.8);
  display:inline-block;
}
.mgr{
  transform-origin:100% 50% 0;/*改变缩放基点*/
}
.mgl{
  transform-origin:0 50% 0;/*改变缩放基点*/
}
.myswipe{
  height:210px;
  box-sizing:border-box;
  padding-bottom:30px;
  padding-top:10px;
  background-color:#ffffff;
  border-bottom:1px solid #E4E4E4;
}
.myswipe .mint-swipe-indicators .is-active{
  background-color:#26a2ff;
}

.myitem>div{
  width:25%;
  height:50%;
  box-sizing:border-box;
  float:left;
  text-align:center;
}
.imgbox{
  height:60%;
}
.imgbox img{
  height:100%;
}
.shopicon{
  width:100%;
  height:100%;
  margin-bottom:-2px;
}
.svgbox{
  width:15px;
  height:15px;
}
.mgleft10{
  margin-left:10px;
}
.shoplist{
  padding:10px;
  overflow: hidden;
  display:flex;
}
.shoplist>div{
  float:left;
}
.shopimgbox{
  width:60px;
  height:60px;
  margin-right:5px;
}
.shopimgbox>img{
  height:100%;
  width:100%;
  background-color:red;
}
.maindiv{
  border-top:1px solid #E4E4E4;
}

.search2{
  width:20px;
  height:20px;
}
.rightbox{
  font-size:0.8rem;
  flex:1;
}
.shoptop,.xxdiv{
  height:25px;
  line-height:25px;
}
.pinpai{
  display:inline-block;
  width:30px;
  text-align:center;
  font-weight:bold;
  height:20px;
  line-height:20px;
  background-color:#ffd930;
  border-radius:3px;
}
.shopname{
  font-weight:bold;
  font-size:0.8rem;
}
.rightspan>span{
  display:inline-block;
  height:14px;
  border:1px solid #A3ACB7;
  margin-left:3px;
  padding:1px;
  color:#A3ACB7;
  line-height:14px;
  font-size:12px;
}

.xx{
  width:10px;
  height:10px;
  
}
.xxbox{
  display:inline-block;
  height:25px;
  box-sizing:border-box;
}
.xxbox>span{
    margin-right:-2px;
}
.xxspan1{
  position:relative;
  display:inline-block;
}
.xxspan2{
  display:inline-block;
  position:absolute;
  left:0px;
  overflow: hidden;
}
.w1{
  width:10%;
}
.w2{
  width:20%;
}
.w3{
  width:30%;
}
.w4{
  width:40%;
}
.w5{
  width:50%;
}
.w6{
  width:60%;
}
.w7{
  width:70%;
}
.w8{
  width:80%;
}
.w9{
  width:90%;
}
.fn{
  background-color:#3190E8;
  color:white !important;
  border-color:#3190E8 !important;
}
.zs{
  color:#3190E8 !important;
   border-color:#3190E8 !important;
}
.mgleft8{
  margin-left:-8px;
}
.shopfoot>div{
  width:50%;
  float:left;
}
</style>

页面效果如下
《vue从创建到完整的饿了么(12)miste.vue》

商品分类是从API请求出来的,其他的都只是死样式。这里有几个要注意的地方

猴子吃香蕉

商品分类一页显示八条,共16条数据,显示两页,但是如果是18条数据呢?那就要前两页8条,第三页两条数据。
这就是FCC社区里大名鼎鼎的猴子吃香蕉问题
一个数组,有n条数据,每隔m条数据分成一个新数组,若有剩余数据,则也加入一个新数组里,最后将所有的新数组以数组形式输出。如数组=[1,2,3,4],则n=4,m=2,结果为[[1,2],[3,4]];数组=[1,2,3,4,5],则n=5,m=2,结果为[[1,2],[3,4],[5]]

解决思路

        var mybody=response.body;     //mybody为要处理的数组,每隔8个分为一个新数组
        var num=parseInt(mybody.length/8);    //num为mybody里含有几个长度为8的数组
        var category=[];           //最后要输出的数组
        var arr=[];            //将mybody分为若干个arr,最终将所有的arr加入category
        for(var i=0;i<num;i++){
           arr=[];
          for(var h= 0;h<8;h++){
            arr.push(mybody[i*8+h]);
          }
          category.push(arr);
        }
        arr=[];
        if(num*8<mybody.length){        //如果mybody不是8的倍数,循环剩下的个数
          for(var k=num*8;k<mybody.length;k++){
              arr.push(mybody[num*8+k]) 
          }
          category.push(arr);
        }
        this.category=category;

评价为0.1-0.9的星星

评价为4.0,就显示四颗彩色的星星,一颗灰色的星星。
但是如果评分为4.3或者4.8呢?

<span class="xxspan1"><icon name="xx2" class="xx"></icon><span class="xxspan2 w5"><icon name="xx" class="xx"></icon></span></span>

xxspan1为容器,相对定位

.xxspan1{
  position:relative;
  display:inline-block;
}

xx2为灰色的星星,xx为彩色的星星。
xxspan2 为存放彩色星星的容器,绝对定位,left为0,与xxspan1重叠,覆盖灰色的星星。

.xxspan2{
  display:inline-block;
  position:absolute;
  left:0px;
  overflow: hidden;
}

w5来控制xxspan2的长度

.w1{
  width:10%;
}
.w2{
  width:20%;
}
.w3{
  width:30%;
}
.w4{
  width:40%;
}
.w5{
  width:50%;
}
.w6{
  width:60%;
}
.w7{
  width:70%;
}
.w8{
  width:80%;
}
.w9{
  width:90%;
}

这样就可以通过class来控制彩色星星显示的宽度。而灰色的星星则作为彩色星星的背景。(这是下下策,哪位老铁有更好的方法?)

字体小于12px

当将字体设置小于12px时,谷歌会默认把字体设置为12px。可能有老铁说把这个默认事件阻止了不就行了?但这对安卓兼容性并不好,所以咱们这里用css的属性来控制。

.fs10{
  font-size: 10px;
  transform: scale(.8);
  display:inline-block;
}

transform: scale(.8)是缩放,把原来的元素缩放成原来的0.8,注意,这里长度宽度也会缩放。可以改变基点来让元素重新回到最左端或者最右端

.mgl{
  transform-origin:0 50% 0;/*改变缩放基点*/
}

第一个参数为x轴,第二个参数是Y轴,第三个参数是z轴。

请求商家列表

1.API
《vue从创建到完整的饿了么(12)miste.vue》

2.发送请求,在mounted中写

//商品列表
      this.$http.get('http://cangdu.org:8001/shopping/restaurants?latitude=31.22967&longitude=121.4762').then(response => {
        console.log(response);
        this.shoplist=response.body;
      }, response => {
        console.log(response);
        
      });

这里传了两个参数经纬度,应该是咱们选择的地点的经纬度,咱们这里先用死的数据。别忘了在data里声明shoplist变量
《vue从创建到完整的饿了么(12)miste.vue》

可以看到,数据已经请求回来了。共20条。
如果你的console出现了大量的svg图标的打印,像下面这样
《vue从创建到完整的饿了么(12)miste.vue》

node_modules下的vue-svg-icon下的Icon.vue里面第79行代码

 console.info(`src/svg/${this.name}.svg has been loaded`);

注销掉即可
《vue从创建到完整的饿了么(12)miste.vue》

现在就是把数据加载到页面里,商家列表的代码修改如下

        <div v-for="item in shoplist" class="shoplist after">
            <div class="shopimgbox">
                <img :src="imgshopUrl+item.image_path">
            </div>
            <div class="rightbox">
                <div class="shoptop">
                  <span class="pinpai fs10 mgl">品牌</span>
                  <span class="shopname">{{item.name}}</span>
                  <span class="rightspan right fs10 mgr"><span v-for="itemsupports in item.supports" class="">{{itemsupports.icon_name}}</span></span>
                </div>
                <div class="xxdiv">
                  <div class="xxbox fs10 mgl">
                    <span v-for="(itemxx,index) in 5" class="xxspan1"><icon v-if="index+1<=item.rating" name="xx" class="xx"></icon><icon v-if="index+1>item.rating" name="xx2" class="xx"></icon><span v-if="item.rating-(index)>0&&item.rating-(index)<1" :class="xxclass+(item.rating*10-index*10)"><icon name="xx" class="xx"></icon></span></span>
                  </div>
                  <span class="colred fs10 mgl mgleft8">{{item.rating}}</span>
                  <span class="fs10 mgl">月售{{item.recent_order_num}}单</span>
                  <span class="rightspan fs10 right mgr">
                      <span v-if="item.delivery_mode" class="fn">{{item.delivery_mode.text}}</span>
                      <span class="zs ">准时达</span>
                  </span>
                </div>
                <div class="shopfoot">
                    <div><span class="fs10 mgl">¥{{item.float_minimum_order_amount}}起送/{{item.piecewise_agent_fee.tips}}</span></div>
                    <div><span class="right fs10 mgr"><span class="">{{item.distance}}/</span><span class="col">{{item.order_lead_time}}</span></span></div>
                </div>
            </div>
        </div>

这里唯一需要注意的地方就是星星的展示。数据只会给我们返回4.7分,那我们怎么展示相应的星星
呢?

<span v-for="(itemxx,index) in 5" class="xxspan1"><icon v-if="index+1<=item.rating" name="xx" class="xx"></icon><icon v-if="index+1>item.rating" name="xx2" class="xx"></icon><span v-if="item.rating-(index)>0&&item.rating-(index)<1" :class="xxclass+(item.rating*10-index*10)"><icon name="xx" class="xx"></icon></span></span>

不管返回多少分,都会是5颗星星,所以我们直接循环五次。然后我们再根据当前的星星的索引index与评分的比较来判断展示哪一种星星。
页面效果如下
《vue从创建到完整的饿了么(12)miste.vue》

ok!展示成功!

重写head

这里不得不注意,Mint ui 的header组件中间文字并没有点击效果。。所以这里咱们要自己写一个,

<div class="myhead">
        <icon class="search2" name="search2" ></icon>
        <div class="headmain nowarp fs1-2">标题过程机会隐藏啊啊啊啊啊啊</div>
        <div class="headright fs0-8">登录|注册</div>
</div>

css如下

.myhead{
  height:40px;
  box-sizing:border-box;
  line-height:40px;
  position:fixed;
  background-color:#26a2ff;
  width:100%;
  color:white;
  padding:0px 10px;
  text-align:center;
  z-index:1;
}
.myhead>div{
  display:inline-block;
}
.headright{
  position:absolute;
  right:10px;
}
.headmain{
  max-width:55%;
  margin:0px auto;
}
.search2{
  width:20px;
  height:20px;
  position:absolute;
  top:10px;
  left:10px;
}

补充

1.imgshopUrl

http://cangdu.org:8001/img/

2.xxclass

 xxclass:"xxspan2 w",     //星星的class
    原文作者:你的前端
    原文地址: https://segmentfault.com/a/1190000011106939
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞