商品列表布局

左侧宽度固定,右边自适应
flex: 0 0 80px
第一个是等分,第二个是缩放,第三个是占位空间

<div class="goods">
  <div class="menu-wrapper"></div>
  <div class="foods-wrapper"></div>
</div>
--------------------css------------------------
.goods
  display: flex
  position: absolute
  top: 174px
  bottom: 46px
  width: 100%
  .menu-wrapper
    flex: 0 0 80px
    width: 80px
    background: #ccc
   .foods-wrapper
      flex: 1
--------------------js获取数据------------------
const ERR_OK = 0
export default {
  props: {
    seller: {
      type: Object
    }
  },
  data() {
    return {
      goods: []
    }
  },
  created: {
    this.$http.get('/api/goods').then((res) => {
      res = res.body
      if(res.errno === ERR_OK){
        this.goods = res.data
    }
  })
  }
}

左侧布局

可能有多行垂直居中,适合用display:table

<ul>
<li class="menu-item" v-for="item in goods" >
  <span class="text border-1px">
    <span v-show="item.type>0" class="icon" :class="classMap[item.type]"></span>
    {{ item. name}}
  </span>
</li>
</ul>
-------------js----------------------------------------------
export default {
  created:() {
    this.classMap = ['decrease','discount','special','invoice','guarantee'];
  }
}
-------------css----------------------------------------------
bg-image($url)
    background-image: url($url + "@2x.png")
    @media (-webkit-min-device-pixel-ratio: 3),(min-device-pixel-ratio: 3)
        background-image: url($url + "@3x.png")
            .menu-item
                display: table
                width: 56px
                height: 54px
                padding: 0 12px
                line-height: 14px
                .icon
                    display: inline-block
                    vertical-align: top
                    width: 12px
                    height: 12px
                    margin-right: 2px
                    background-size: 12px 12px
                    background-repeat: no-repeat
                    &.decrease
                        bg-image('decrease_3')
                    &.discount
                        bg-image('discount_3')
                    &.guarantee
                        bg-image('guarantee_3')
                    &.invoice
                        bg-image('invoice_3')
                    &.special
                        bg-image('special_3')
                .text
                    display: table-cell
                    width: 56px
                    vertical-align: middle
                    border-1px(rgba(7,17,27,0.2)) 
                    font-size: 12px

右侧布局

       <div class="foods-wrapper">
           <ul>
               <li v-for="item in goods" class="food-list">
                   <h1 class="title">{{ item.name }}</h1>
                   <ul>
                       <li v-for="food in item.foods" class="food-item">
                           <div class="icon">
                               <img :src="food.icon">
                           </div>
                           <div class="content">
                               <h2 class="name">{{ food.name}}</h2>
                               <p class="desc">{{food.description}}</p>
                               <div class="extra">
                                   <span>月售{{ food.sellCount }}份</span>
                                   <span>好评率{{ food.rating }}%</span>
                               </div>
                               <div class="price">
                                   <span>¥{{ food.price }}</span>
                                   <span v-show="food.oldPrice">¥{{ food.oldPrice }}</span>
                               </div>
                           </div>
                       </li>
                   </ul>
               </li>
           </ul>
       </div>
--------------------------css-------------------------------

   .foods-wrapper
           flex: 1
           .title
               padding-left: 14px
               height: 26px
               line-height: 26px
               border-left: 2px solid #d9dde1
               font-size: 12px
               color: rgb(147,153,159)
               background: #f3f5f7
           .food-item
               display: flex
               margin: 18px
               padding-bottom: 18px
               border-1px(rgba(7,17,27,0.1))
               &.last-child
                   border-none()
                   margin-bottom: 0
               .icon
                   flex: 0 0 57px
                   margin-right: 10px
               .content
                   flex: 1
                   .name
                       margin: 2px 0 8px 0
                       height: 14px
                       line-height: 14px
                       font-size: 14px
                       color: rgb(7,17,27)
                   .desc, .extra
                       line-height: 10px
                       font-size: 10px
                       color: rgb(147,153,159)
                   .desc
                       margin-bottom: 8px
                   .extra
                       &.count
                           margin-right: 12px
                   .price
                       font-weight: 700
                       line-height: 24px
                       .now
                           margin-right: 8px
                           font-size: 14px
                           color: rgb(240,20,20)
                       .old
                           text-decoration: line-through
                           font-size: 10px
                           color: rgb(147,153,159)

怎么把1像素的边去掉?
在mixin.styl中写:

border-none()
    &:after
        display: none

better-scroll应用

  • 安装
    cnpm install better-scroll --save
  • 使用
    import BScroll from 'better-scroll'
    vue取dom
    <div class="menu-wrapper" ref="menuWrapper"></div>
      created() {
            this.classMap = ['decrease','discount','special','invoice','guarantee'];
            this.$http.get('/api/goods').then((res) => {
                res = res.body
                if(res.errno === ERR_OK){
                    this.goods = res.data
                    this.$nextTick(() => {
//this.$nextTick() => 在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。
//数据发生变化后,不能直接更新在dom上,需要在回调函数中刷新DOM,即异步加载DOM
                        this._initScroll()
                    })
                    
                }
            })
        },
        methods: {
            _initScroll() {
                //this.$refs:取得DOM对象
                this.menuScroll = new BScroll(this.$refs.menuWrapper, {})
                this.foodsScroll = new BScroll(this.$refs.foodsWrapper, {})

            }
        }

如果报错
Error in nextTick: "TypeError: Cannot read property 'children' of undefined"
那么就是因为
<div class="menu-wrapper" ref="menuWrapper"></div>
menuWrapper要用驼峰写,不要用-

实现左右联动

右边纵坐标落到哪个 区间,计算每个区间的高度
然后返回右边的索引 与 左边的索引相等时,给左侧Li高亮

在`$nextTick`拿到数据,dom更新后
data() {
  return {
    listHeight: [],
    scrollY: 0
 }
},
computed: {
  currentIndex() {
    for(let i = 0; i < listHeight.length; i++){
      let height1 = listHeight[i];
      let height2 = listHeight[i + 1]
      if(!height2 || this.scrollY >= height1 && this.scrollY < height2){
        return i
      }
     }
    return 0
}
},
created: {
this.$nextTick(function(){
  this._initScroll();
  this._calculateHeight();
})
},
methods: {
  _initScroll() {
     this.menuScroll = new BScroll(this.$refs.menuWrapper, {
      click: true //取消默认阻止事件    
     });
     this.foodsScroll = new BScroll(this.$refs.foodsWrapper, {
      click: true,
      probeType: 3 //监听事件的触发时间,1为即时触发,3为延迟触发
    });
     this.foodsScroll.on('scroll', () => {
        this.scrollY = Math.abs(Math.round(pos.y))
     })
},
  _calculateHeight(){
    var foodList = this.$refs.foodsWrapper.getElementsByClassName('food-list-hook')
    let height = 0
    for(var i = 0; i < foodList.length; i++){
      let item = foodList[i]//获取每个li的高度
      height += item.clientHeight;
      this.listHeight.push(height);
}
}
}

把右边当前的索引关联到左侧导航的索引
<li v-for="(item,index) in goods" class="menu-item" :class="{'current':currentIndex === index}"></li>
  • 点击左侧菜单 实现右侧联动
index:当前索引值
$event://当pc浏览器会触发两次,解决方法传入event
<li v-for="(item,index) in goods" class="menu-item" :class="{'current':currentIndex === index}" @click="selectMenu(index,$event)"></li>

methods: {
  selectMenu(index,event) {
    if(!event._constructed){//阻止非vue事件
      return
    }
    var foodList = this.$refs.foodsWrapper.getElementsByClassName('food-list-hook');
    let el = foodList[index]//获取右侧当前位置
    this.foodsScroll.scrollToElement(el, 300)//右侧内容指向右侧当前位置
  }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,039评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,426评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,417评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,868评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,892评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,692评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,416评论 3 419
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,326评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,782评论 1 316
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,957评论 3 337
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,102评论 1 350
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,790评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,442评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,996评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,113评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,332评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,044评论 2 355

推荐阅读更多精彩内容

  • 常见的页面布局 作为一个像我这样的切图仔前端而言,拿到设计图的第一步就是要分析设计图大致地划分区域,然后选择一种最...
    自度君阅读 1,152评论 0 1
  • 现在,对于微信公众号,大家都不陌生。谁微信没关注几个自己感兴趣的公众号呢。随着微信公众号的普及,不再是13,14年...
    8976d908eb13阅读 5,701评论 0 1
  • 由于小时候我家住在一条大马路旁边,又靠近一个集市,我每天早上都会看到从灰蒙蒙的晨雾中从四面八方涌来的人群,人们提着...
    南城半世阅读 759评论 3 7
  • 初萌的日光 自微翘起的檐角 缓缓淌下 秋风的落叶 泥静的小路 带走了依依不舍的嬉戏 母亲远处呼喊的声音 院里说故事...
    小刘少爷阅读 197评论 0 4