最后
总的来说,面试官要是考察思路就会从你实际做过的项目入手,考察你实际编码能力,就会让你在电脑敲代码,看你用什么编辑器、插件、编码习惯等。所以我们在回答面试官问题时,有一个清晰的逻辑思路,清楚知道自己在和面试官说项目说技术时的话就好了
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
toggleList() {
if (this.listFold) {
if (!this.totalCount) {
return
}
this.listFold = false
this._showShopCartList()
this._showShopCartSticky()
} else {
this.listFold = true
this._hideShopCartList()
}
},
并且实现这两个私有方法,使用api调用组件(由于每次都是单例,因此做缓存)
_showShopCartList() {
this.shopCartListComp = this.shopCartListComp || this.$createShopCartList({
$props: {
selectFoods: ‘selectFoods’
},
$events: {
hide: () => {
this.listFold = true
},
leave: () => {
this._hideShopCartSticky()
},
add: (el) => {
this.shopCartStickyComp.drop(el)
}
}
})
this.shopCartListComp.show()
},
_hideShopCartList() {
const comp = this.sticky ? this.$parent.list : this.shopCartListComp
comp.hide && comp.hide()
},
(6)存在的问题
但是有个问题就是,shop-cart-list是API组件,会动态的向body中挂载结点,因此层级较高,高过内层组件层级。但是购物车组件是一个子组件,因此会遮盖到原来的购物车组件。但是无法调整层级,
因此解决方法就是:使用shop-cart-sticky组件。动态向body中挂载一个购物车组件的副本。 shop-cart-sticky组件。
(7)商品购买时小球飞入动画
购物车小球,在shop-cat-list的cart-control点击需要向其父组件shop-cart组件派发onAdd()方法
<cart-control @add=“onAdd” :food=“food”>
onAdd(target) {
this.$emit(EVENT_ADD, target)
},
在shop-cart组件中监听该事件,在add中调用shop-cart-sticky组件的drop()方法,(其中需要在shop-cart-sticky中添加drop方法,并调用shop-cart的drop方法。)
_showShopCartList() {
this.shopCartListComp = this.shopCartListComp || this.$createShopCartList({
$props: {
selectFoods: ‘selectFoods’
},
$events: {
hide: () => {
this.listFold = true
},
leave: () => {
this._hideShopCartSticky()
},
add: (el) => {
this.shopCartStickyComp.drop(el)
}
}
})
this.shopCartListComp.show()
},
(8)清空购物车
点击清空按钮,添加click事件empty(), 调用cube-ui的dialog,遍历food将所有的count设置为0
empty() {
this.$createDialog({
type: ‘confirm’,
content: ‘确认清空购物车吗?’,
$events: {
confirm: () => {
this.selectFoods.forEach((food) => {
food.count = 0
})
this.hide()
}
}
}).show()
}
}
当商品数量为0时,也要收回list,因此在shop-cart组件中添加watch,对于totalcount,当展开情况,并且值为0,将其关闭。
watch: {
fold(newVal) {
this.listFold = newVal
},
totalCount(newVal) {
if (!this.listFold && !newVal) {
this._hideShopCartList()
}
}
},
(9)结算按钮
对于去结算按钮,添加点击事件pay(),使用cube-ui提供的dialog,当价格大于起送价,计算价格并显示
pay(e) {
if (this.totalPrice < this.minPrice) {
return
}
this.$createDialog({
title: ‘支付’,
content: 您需要支付${this.totalPrice}元
}).show()
e.stopPropagation()
},
(10)公共部分mixin抽离
所有我们使用的弹层组件都包含了show() hide() 主要用途是修改visible的true false,因此可以抽象出这部分代码,在common中添加mixins文件夹popup.js,在shop-cart-list等中添加引用mixin:[popupMixin]
const EVENT_SHOW = ‘show’
const EVENT_HIDE = ‘hide’
export default {
data() {
return {
visible: false
}
},
methods: {
show() {
this.visible = true
this.$emit(EVENT_SHOW)
},
hide() {
this.visible = false
this.$emit(EVENT_HIDE)
}
}
}
(11)滑动页面购物车关联
对于滑动页面也可以实现购物车的联动问题:在tab组件中我们定义了一个onChange()方法
onChange(current) {
this.index = current
const component = this.$refs.component[current]
component.fetch && component.fetch()
},
其中会执行组件的fetch方法,在goods组件中定义了这样一个fetch方法,每次都会getGoods,因此添加一个标记,只有当没有定义过时才会getGoods,如果已经获取过一次时就不用再次获取了。
fetch() {
if (!this.fetched) {
this.fetched = true
getGoods().then((goods) => {
this.goods = goods
})
}
},
二、购物车详情shopcart-list区块(一期)
==============================
1. 概述
一期实现没有很复杂的部分就是需要添加计算属性listShow,判断totalCount没有商品时将fold = true,否则为true。点击触发togglelist方法控制该部分显示。
2. 布局
组件部分没有抽离出来,而是直接在shop-cart组件中写入,放在整个组件的最下部。
购物车
<span class=“empty” @click=“empty”>清空
{{food.name}}
¥{{food.price*food.count}}3. 实现
(1)实现组件显示隐藏
添加一个fold默认值为true,添加计算属性listShow。判断this.totalCount没有商品fold = true,否则为true。
listShow() {
if (!this.totalCount) {
this.fold = true;
return false;
}
let show = !this.fold;
if (show) {
this.$nextTick(() => {
if (!this.scroll) {
this.scroll = new BScroll(this.$els.listContent, {
click: true
});
} else {
this.scroll.refresh();
}
});
}
return show;
}
},
在点击content时触发事件togglelist,并实现方法,当点击list-mask可以收回shop-cart,添加事件listShow事件
toggleList() {
if (!this.totalCount) {
return;
}
this.fold = !this.fold;
},
(2)实现动画
动画:向上滑动,添加transition=fold,此处点击事件是better-scroll组件派发的事件。
&.fold-transition
transition: all 0.5s
transform: translate3d(0, -100%, 0)
&.fold-enter, &.fold-leave
transform: translate3d(0, 0, 0)
(3)蒙层的实现
该组件出现时背后是一个蒙层,因此在shop-cart组件同级下定义list-mask
并添加渐变效果和样式。模糊效果使用 backdrop-filter: blur(10px)
.list-mask
position: fixed
top: 0
left: 0
width: 100%
height: 100%
z-index: 40
backdrop-filter: blur(10px)
&.fade-transition
transition: all 0.5s
opacity: 1
background: rgba(7, 17, 27, 0.6)
&.fade-enter, &.fade-leave
opacity: 0
background: rgba(7, 17, 27, 0)
三、shop-cart-sticky组件
========================
1. 概括
shop-cart-list是API组件,会动态的向body中挂载结点,因此层级较高,高过内层组件层级。但是购物车组件是一个子组件,因此会遮盖到原来的购物车组件。但是无法调整层级,因此解决方法就是:使用shop-cart-sticky组件。动态向body中挂载一个购物车组件的副本。而Sticky组件就是对chop-cart组件的简单包装。
2. 布局
Sticky组件就是对chop-cart组件的包装,把它需要的数据通过props传入,因此可以把sticky组件作为API调用就可以了。并且也包含hide() show()函数控制visible显隐。
<shop-cart
ref=“shopCart”
:selectFoods=“selectFoods”
:deliveryPrice=“deliveryPrice”
:minPrice=“minPrice”
:fold=“fold”
:sticky=true>
3. 实现
sticky组件要可以跟着页面的切换而保存,因此调用要添加在shop-cart组件的toggleList函数中(如上代码)并实现该私有函数,并接收props
_showShopCartSticky() {
this.shopCartStickyComp = this.shopCartStickyComp || this.$createShopCartSticky({
$props: {
selectFoods: ‘selectFoods’,
deliveryPrice: ‘deliveryPrice’,
minPrice: ‘minPrice’,
fold: ‘listFold’,
list: this.shopCartListComp
分享
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
3. 实现
sticky组件要可以跟着页面的切换而保存,因此调用要添加在shop-cart组件的toggleList函数中(如上代码)并实现该私有函数,并接收props
_showShopCartSticky() {
this.shopCartStickyComp = this.shopCartStickyComp || this.$createShopCartSticky({
$props: {
selectFoods: ‘selectFoods’,
deliveryPrice: ‘deliveryPrice’,
minPrice: ‘minPrice’,
fold: ‘listFold’,
list: this.shopCartListComp
分享
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】