07、Vue-Goods组件(商品列表)《饿了吗》
- Goods组件 -- 左侧菜单列表布局
- Goods组件 -- 右侧具体商品列表布局
- Goods组件 -- better-scrll运用
- Goods组件 -- 购物车组件
- Goods组件 -- 购物个数组件
- Goods组件 -- 购物车详情页
- Goods组件 -- 购物车背景效果
一、flex布局
Flex 布局,可以简便、完整、响应式地实现各种页面布局,Flex 是 Flexible Box 的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性。任何一个容器都可以指定为 Flex 布局。
// 指定为 Flex 布局
display: flex;
// 主要属性
flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
flex属性是flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto。后两个属性可选。
flex-grow属性定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大
flex-shrink属性定义项目的缩小比例,默认为1,即如果空间不足,该项目将缩小,flex-shrink属性为0,其他项目都为1,则空间不足时,前者不缩小
flex-basis属性定义了在分配多余空间之前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即项目的本来大小,设为跟width或height属性一样的值(比如350px),则项目将占据固定空间
二、display:table-cell的应用
display:table-cell属性指让标签元素以表格单元格的形式呈现,类似于td标签。单元格有一些比较特别的属性,例如元素的垂直居中对齐,与其他一些display属性类似,table-cell同样会被其他一些CSS属性破坏,例如float, position:absolute,所以,在使用display:table-cell与float:left或是position:absolute属性尽量不用同用。设置了display:table-cell的元素对宽度高度敏感,对margin值无反应,响应padding属性,基本上就是活脱脱的一个td标签元素了。
- 图片大小不一水平垂直居中设置
在之前HTML&CSS元素样式中有涉及到关于图片的水平垂直居中设置,也是可以解决图片大小不一致的居中,但是相对这种方法就是比较复杂
// html
<div class="box">
![](Snip20160614_3.png)
</div>
// css
.box{
width: 600px;
height: 600px;
border: 1px solid gray;
display: table-cell;
vertical-align: middle;
text-align: center;
}
图片水平垂直居中示例
- 多行文字水平垂直居中
如果只是单纯行设置直接用行高会更为快捷,但如果文字内容是不确定的情况下使用该方法就是更为简单
// html
<div class="view">
<span>
你好?
</span>
</div>
// css
.view{
width: 200px;
height: 100px;
border: 1px solid gray;
text-align: center;
// 设置为类似 <table>
display: table;
// 注意要添加垂直对齐方式
vertical-align: middle;
}
.view span{
display: table-cell;
// 注意要添加垂直对齐方式
vertical-align: middle;
}
文字水平垂直居中示例
文字水平垂直居中示例
大小不固定的图片、多行文字的水平垂直居中让行数不固定的文字在高度固定的容器内垂直居中
display: table-cell的其他用法
三、 better-scroll运用
类似于iscroll,实现滚动效果
-
安装
$ npm install better-scroll -
导入
那个组件需要使用,就在哪里导入即可;
import BScroll from 'better-scroll' -
使用
// ref属性为menuScroll (可以使用驼峰命名)
<div class="menu-wrapper" ref='menuScroll'></div>
// 获取到对应元素 this.$refs.menuScroll
// 创建实例,即可以实现滚动
new BScroll(this.$refs.menuScroll, {});
ref
属性就是用来绑定某个dom元素,或者来说用来绑定某个组件,然后在this.$refs
里面调用
四、菜单以及分类联动效果
确定主体内容中每个分组对应的高度,在滚动时通过滚动的距离确定滚动的位置,之后改变菜单栏的选项;即菜单选项和分组有个数组与之对应;
- better-scroll中
probeType
滚动事件监听类型选择
probeType: 1 会截流,只有在滚动结束的时候派发一个 scroll 事件。2在手指 move 的时候也会实时派发 scroll 事件,不会截流。 3除了手指 move 的时候派发scroll事件,在 swipe(手指迅速滑动一小段距离)的情况下,列表会有一个长距离的滚动动画,这个滚动的动画过程中也会实时派发滚动事件
// 在创建滚动实例时,传递参数
this.foodsScroll = new BScroll(this.$refs.foodsScroll, {
probeType: 3
});
// 滚动事件的处理
this.foodsScroll.on('srcoll', (pos) => {
this.srcollY = pos.y;
});
- 菜单选项和滚动距离映射
通过vue中的计算属性,可以快速实现映射
<ul>
// vue1.0: v-for="item in goods" 获取对应元素下标是直接$index
// vue2.0: v-for="(item,index) in goods" 已经废弃$index
<li v-for="(item,index) in goods" :class="{'current':currentIndex===index}">
{{item}}
</li>
</ul>
- better-scroll事件操作
移动端中,默认点击事件是不会被派发的,所以要在创建BScroll
实例时,要将点击事件操作打开
this.menuScroll = new BScroll(this.$refs.menuScroll, {
// click: true 是否派发click事件
click: true
});
如果
click: true
,pc端点击事件会触发两次,移动端点击事件会触发一次,为了保持一致,即可以通过event
事件源来判断处理
// 点击事件,并将$event事件传递过去
<li @click="selectMune(index,$event)">
// 点击事件处理方法
selectMune(index, event){
if(!event._constructed){ // pc端的不做任何处理
return
}
console.log(index);
}
- better-scroll方法
scrollToElement(el, time, offsetX, offsetY, easing)
滚动到某个元素,el(必填)表示 dom 元素,time 表示动画时间,offsetX 和 offsetY 表示坐标偏移量,easing 表示缓动函数
// 跳转到对应的分组中
let foodList = this.$refs.foodListHook;
this.foodsScroll.scrollToElement(foodList[index], 200);
五、购物车组件
- 配送费和起送费,是在商家seller数据中,该数据是在App.vue获取,即需要将数据传递到Goods,再从Goods传递到Shopcart
- 添加商品功能,添加操作是在Goods组件中,需要将选择的内容(food数组形式)传递到Shopcart组件中
六、购物个数组件
- 商品个数选择肯定也是和对应商品对应的,即需要将对应商品信息传递Cartcontrol组件
- Goods将food商品信息传递过来后,food中是没有
count
字段的,如果直接添加,是不会监听该字段变化的;如果想要达到效果,需要通过vue.set()
方法
import Vue from 'vue';
// 通过该方法添加新的字段
Vue.set(this.food, 'count', 1);
注: Goods组件将food
传到Cartcontrol组件中,在Cartcontrol修改了food
内容,Goods中对应的内容也会相对应改变,即不需要再传回到Goods中;
- 当
food.count
改变,对应的需要Goods组件,将所有添加的商品添加到数组中,之后将该数组传入到Shopcart组件