export function showBookDetail(vue, book) {
vue.$router.push({
path: '/book-store/detail',
query: {
fileName: book.fileName,
category: book.categoryText
}
})
}
search-bar由标题和搜索框和返回图标三部分组成,title高度0.42rem绝对定位top为0,back高度0.42rem绝对定位top为0;input搜索框绝对定位top0.42rem,并且中间包含一个blank块级元素,一开始宽度初始为0
一开始search-bar的高度设定为0.94rem,当鼠标聚焦到搜索框或发生滚动事件(hide-title
样式),search-bar的高度就会变成0.52rem,并且back的高度也会变成0.52rem(视觉上会有下移效果),搜索框中的top会变成0,占据标题监控机,而且其中的blank元素这时会变为{flex: 0 0 .31rem;width: 0.31rem;},视觉上为back腾出空间。
titleVisible
变量控制hide-title
样式,'hide-title': !titleVisible
, titleVisible初始为true,watch监听Scroll的top值(newY),当newY大于0滑动则隐藏标题栏时,titleVisible为false,小于或者等于0则为true;当input的点击事件触发titleVisible也会为false,这时候滚动条也要滚到初始位置<input v-model="searchText" @keyup.13.exact="search">
search(){
this.$router.push({
path: '/store/list',
query: {
keyword: this.searchText
}
})
},
到StoreList.vue页面之后,在created钩子函数中会首先请求后端接口/book/list
得到所有按照目录名字为key的图书列表,然后遍历所有的key,过滤掉key中不包含keyword
的图书,将得到的list数据传递给featured组件
Object.keys(this.list).filter(key => {
this.list[key] = this.list[key].filter(book => book.fileName.indexOf(keyword) >= 0)
return this.list[key].length > 0
})
StoreList.vue中封装了detail-title和scroll、featured这三个组件,detail-title组件中传递一个计算属性title,接收list的数量
featured组件中接收三个父组件传递过来的变量
首先定义了flapCardList数组,存储小圆信息,如下
{
r: 255,
g: 102,
_g: 102,
b: 159,
imgLeft: 'url(' + require('@/assets/images/gift-left.png') + ')',
imgRight: 'url(' + require('@/assets/images/gift-right.png') + ')',
backgroundSize: '50% 50%',
zIndex: 100,
rotateDegree: 0
},
//左半圆
.flap-card-semi-circle-left{
border-radius: .24rem 0 0 .24rem;
background-position: center right;
transform-origin: right;
}
//右半圆
.flap-card-semi-circle-right{
border-radius: 0 .24rem .24rem 0;
background-position: center left;
transform-origin: left;
}
烟花的动画
//1.首先定义小球开始和结束坐标,以及小球的宽高和背景颜色
$moves: (
(startX: 0, startY: 0, endX: 0, endY: 55, width: 6, height: 6, background: $color-green),
(startX: 0, startY: 0, endX: 15, endY: 60, width: 4, height: 4, background: $color-pink-transparent),
(startX: 0, startY: 0, endX: 35, endY: 45, width: 4, height: 4,
);
//2.定义动画
@mixin move($index) {
$item: nth($moves, $index);
$keyframesName: "move" + $index;
$animationTime: $pointShowTime;
$animationType: linear;
$animationIterator: 1;
$width: map-get($item, width);
$height: map-get($item, height);
$backgroud: map-get($item, background);
$startX: map-get($item, startX);
$startY: map-get($item, startY);
$endX: map-get($item, endX);
$endY: map-get($item, endY);
// width: px2rem($width);
// height: px2rem($height);
width: $width/100 + rem;
height: $height/100 + rem;
background: $backgroud;
animation: #{$keyframesName} $animationTime $animationType $animationIterator;
@keyframes #{$keyframesName} {
0% {
// transform: translate3d(px2rem($startX), px2rem($startY), 0) scale(0);
transform: translate3d($startX/100 + rem, $startY/100+rem, 0) scale(0);
opacity: 0;
}
50% {
// transform: translate3d(px2rem($endX * 0.5), px2rem($endY * 0.5), 0) scale(.5);
transform: translate3d($endX * 0.5/100+rem, $endY * 0.5/100+rem, 0) scale(.5);
opacity: 1;
}
90% {
// transform: translate3d(px2rem($endX), px2rem($endY), 0) scale(1);
transform: translate3d($endX/100+rem, $endY/100+rem, 0) scale(1);
opacity: 1;
}
100% {
transform: translate3d($endX * 1.05/100+rem, $endY * 1.05/100+rem, 0) scale(1);
opacity: 0;
}
}
}
//3.scss语法遍历$moves,给每个小球加上动画
&.animation {
@for $i from 1 to length($moves) {
&:nth-child(#{$i}) {
@include move($i);
}
}
}
prepare() {
//让背面的左侧半圆和右侧半圆重叠
const backFlapCard = this.flapCardList[this.back]
backFlapCard.rotateDegree = 180
//(不要了)因为后续和正面圆一起转动到90度时转动了9次,并且颜色也不断在变浅所以到90度时无法显示初始颜色
//需要先减去5*9,让它先加深,以便到90°后不断变浅
backFlapCard._g = backFlapCard.g - 5 * 9
this.rotate(this.back, 'back')
},
flapCardRotate(){
const frontFlapCard = this.flapCardList[this.front]
const backFlapCard = this.flapCardList[this.back]
//加深
frontFlapCard.rotateDegree += 10
frontFlapCard._g -= 5
//变浅
backFlapCard.rotateDegree -= 10
if (backFlapCard.rotateDegree < 90) {
//还未转到90°时无法看到,不让它有颜色变化,
//到90°时就能显示了,这时候就不断变浅到平面时到初始位置
backFlapCard._g += 5
}
//第一个临界点,让背面圆覆盖正面圆,如果是初始状态正面圆转动9次到达90°,但是
//背面圆此时是转动到-90°,无法执行下列逻辑,因此需要先让背面左侧圆和右侧圆重叠,一起翻转,
//要先执行prepare让背面圆到180°,此时正面圆转到90°,背面圆也会转到(180-90)°
if (frontFlapCard.rotateDegree === 90 && backFlapCard.rotateDegree === 90){
backFlapCard.zIndex += 2
}
this.rotate(this.front, 'front')
this.rotate(this.back, 'back')
//这时正面圆(90+90)和背面圆(90-90)都到了左侧位置
if (frontFlapCard.rotateDegree === 180 && backFlapCard.rotateDegree === 0){
this.next()
}
},
next(){
//让正面圆和背面圆归位
const frontFlapCard = this.flapCardList[this.front]
const backFlapCard = this.flapCardList[this.back]
frontFlapCard.rotateDegree = 0
backFlapCard.rotateDegree = 0
frontFlapCard._g = frontFlapCard.g
backFlapCard._g = backFlapCard.g
this.rotate(this.front, 'front')
this.rotate(this.back, 'back')
//开始下一组的翻转
this.front++
this.back++
const len = this.flapCardList.length
//判断溢出
if (this.front >= len){
this.front = 0
}
if (this.back >= len){
this.back = 0
}
// 开始下一组的翻转之前要先改变zIndex
// 100 -> 96
// 99 -> 100
// 98 -> 99
// 97 -> 98
// 96 -> 97
// 当前这一组的front和back因为已经自加1了,所以现在其各自下标是1和2
//front:100 -> 100 - ((0-1+5)%5=4)=96
//back: 99 -> 100 - (1-2+5)%5=97
this.flapCardList.forEach((item, index) => {
item.zIndex = 100 - ((index - this.front + len) % len)
})
this.prepare()
},