1.header组件开发总结
1)使用classMap设置优惠活动项
2)设置了公共样式自定义属性:border-1px($color)解决移动端1px问题
bg-image($url) 解决背景图片在不同设备像素比之下的大小
2.header弹出层组件开发
弹出层的内容部分采用css sticky footer布局:
。最外层容器负责该弹出层的整体位置 背景以及控制浮层的展示和隐藏
。外层两个容器一个内容层(清除浮动),一个定在底部的底部层
。内容层里面再建立一个内容层装主要内容
布局如下:
关于样式:
。外层容器 detail-wrapper设置min-height:100%(最小高度有视口那么高)
。detail-close为底部固定层,相对定位,设置-margin值来使它保留在底部
。注意:内容层detail-main设置margin-bottom来为使其不会遮盖住底部固定层
样式如下:
。加入文字进行测试发现文字短的时候close在底部,文字长的时候,close在内容层最底部
控制浮层展示和隐藏:
。dom上使用v-show="变量名"进行控制
。实例中设置data函数返回变量名的值为false(默认不展示)
。需要控制点击展示的dom上使用@click=“方法名”
。在实例methods中定义方法使变量名的值为相反
2.星星组件开发
公共部分抽离成公共组件
。建立组件star接受两个参数星星数和大小,数据类型为Number
。使用计算属性来改变star 类名达到改变大小的目的
。
实现原理:建立一个数组result,声明变量 hasDecimal代表有小数点的情况,integer代表整数的部分。遍历整数部分,将类名on放入数组result中,如果有半星的情况就就放置类名off,剩下的放off。由于半星只会放置一个,所以不需循环。
。在header组件中引用star组件,使用star标签测试成功就可以了
3.商品组建开发总结
布局方面:
效果:页面左右两边没有滚动条,页面长度超过视口,页面可以上下滑动
解决:定义视口的高度。将视口盒子绝对定位
首先 将商品goods数据mock到页面中,同header中seller数据请求
实现垂直居中使用table
实现页面垂直滚动:
。实现视口里的内容能够滚动,使用better-scroll库https://github.com/ustbhuangyi/better-scroll/blob/master/README_zh-CN.md
使用:
better-scroll的使用方法就是:引入batter-scroll插件,然后初始化插件(方法是第二个篮圈处,创建变量实例化BScroll并且将dom节点传入。要注意的是第一个篮圈处,vue在数据更改的时候,dom会跟着数据映射,但是vue在跟新dom时其实是异步的,所以初始化时,数据更新但dom并没有变化,计算高度时会有问题,使用this.$nextTick接口可以解决dom更新的问题,可以计算到dom高度,实现滚动效果)
在我们的实际工作中,列表的数据往往都是异步获取的,因此我们初始化 better-scroll 的时机需要在数据获取后https://cn.vuejs.org/v2/api/#vm-nextTick
better-scroll布局技巧:两层容器 外层容器固定视口高度并overflow:hidden,内容容器装内容,内层超过外层就会滚动
如果需要高度百分百,可以使用绝对定位技巧:
自动生成一个固定高度,宽度百分之百的盒子
。获取dom元素,使用vue提供的API ref
html使用ref="dom名" 函数中使用this.$refs = "dom名" 注:dom名要一致
3.实现左右联动效果
计算坐标Y值,右边的Y值在哪个区间,左边就显示相应区间
建立数组记录每个区块的最大高度,计算高度方法也在nextTick中执行,
细节:在类名中加入hook如:list-hick-hook,表示单纯被js选择所用,没有其他实际用途
右侧Y值与左侧所引值做对比
监听滚动位置:使用probeType: 3.(是better-scroll的API)然后在scroll事件中传参pos,获取Y轴位置就是pos.y
判断scroll时,Y轴区间是否在右侧某两个高度区间之间,如果是,则匹配左侧对应的index 值
4.购物车组件开发
。建立,引入,注册组件
。父组件绑定属性传值到子组件
子组件在props中接受值
。做状态绑定计算
先考虑到,将会从父组件传过来一个数组,里面包含被选中的商品的所有信息,这个数组定义为selectedFoods,所有关联的状态变化都依赖于selectedFoods
养成好习惯接收数据时,将数据类型写上,默认值写好,return里面是暂时用来看效果的模拟数据
。通过计算属性计算总价和商品被选择的次数
totalPrice函数返回商品的总价,计算方式是通过选择的商品组成的数组selectedFoods中,遍历每一个被选择的商品以获得价格和被选中的次数,总价等于上次的价格加上商品价格乘以被选择的次数
totalCount函数返回选择的商品总次数(总共选了几件商品),计算方式同上,每个商品的被选择次数相加
。在dom中渲染
由于视图伴随着样式改变,所以这里做一个判断,当价格和次数都大于0时,会加入一个class类名为highlight
。写入highlight样式
最后渲染为
当将count改为0时
。接下来开始完善描述部分和价格部分,他们的状态变化都依赖于selectedFoods
当数据变化时,dom状态会跟着改变。
绑定class时,这里有两种状态,所以绑定的是一个计算属性
computed中:
然后定义好enough和not-enough的样式
状态更新总结:父组件传过来数组selectedFoods,所有状态更新都是依赖于selectedFoods里面的数据。利用数据通过计算属性制定当前状态。
。实现选择商品按钮
将按钮的数值变化与购物车联动起来
按钮会被多次复用,所以分离为一个组件
。按钮组件依赖于count属性,这个属性是原数据没有的
。在写好点击事件之后,发现没有效果,经过验证发现并没有触发点击事件,原因是,右侧的商品版面使用了better-scroll插件,better-scroll在移动端实现点击需要通过在dom节点配置参数(click: true)来初始化点击事件。
。当为dom元素注册点击事件时,发现在PC端点击会出现两次点击事件,所以需要防止触发两次点击事件
descreaseCart(event){ //传入event参数
if(!event._constructed){ //阻止出发两次点击事件
return;
}
}
。 当 click事件可以正确触发之后,发现内部方法没有起作用,原因是vue的特性,这两个方法依赖于count属性,count属性其实并不存在,当我们为观测对象添加一个它不存在的字段的时候,直接赋值是检测不到变化的,如果需要达到检测目的,需要使用到vue接口(vue.set)来添加属性
。商品增减按钮动画同时需要滚动和平移所以需要两个层分别完成此动画
。实现选择商品与结算界面联动
通过计算属性来得到selecteFoods数组,然后将它传入子组件,子组件接受即可(之前已经部署好状态关联方法)
。实现选择商品小球抛出动画
难点,知道起始点位置也就是商品后面的+小球的位置,是不固定的,需要动态计算
怎样在父组件获取cartcontrol组件下的小球的dom呢?
原理:
1判断当前点的是哪个小球:再点击事件中使用event.target可以获取当前点击事件发生的dom
2将当前小球作为参数传递给父组件:用$emit订阅模式定义一个事件,将小球位置作为参数传递进去。记住:父组件要绑定这个事件来创建一个事件接收此参数。
3将此参数传递到shopcart子组件:在shopcart中定义一个事件drop,在父组件事件中,使用$.refs.shopcart.drop获取自组建的事件并把参数传给子组件
4.这样就完成了,子组件cartcontrol将小球位置作为参数传给父组件,父组件将此参数传递给另一个子组件shopcart的过程。
动画原理:
遍历数组balls,拿到其中的一个false小球将他的状态设置为true,然后将当前小球赋值给ball.el,然后将状态为true的ball放置到数组dropball里面。
5.详情页组件开发
。css技巧:详情页的顶图宽高一样,可是在加载页面时,在图片还没有加载出来时,会造成内容跳动(图片没加载出来,下面内容在上面,加载出来后,内容被挤到下面去)。
优化技巧:图片外部容器设置相对定位,高度为0,宽度100%,再设置padding-top:100%(默认paddingtop和宽度一样。)这样就形成了一个正方形可以先占据图片位置。再为图片设置绝对定位并且top和left为0,即可使图片加载出来后,出现在padding方块的位置。
优化点:keep-alive可以使已经加载过的组件和已经选择的商品不再因为vue-router切换tab而重新渲染。可以保持之前的状态