shopList - mingliao/nuxt_elm GitHub Wiki
组件封装好比函数封装,哪些属性可以暴露,那些需要在内部使用,都需要思考,组件便于重复利用。
- 入场动画
- 触底滚动加载数据
- Number
- 待办事项
入场动画代码主要在这里
<transition name="loading">
<loading v-show="showLoading"></loading>
</transition>
transition参考进入/离开 & 列表过渡
在文档中介绍了
当插入或删除包含在 transition 组件中的元素时,Vue 将会做以下处理
说明,transition是对dom,创建或者删除的时候进行样式操作的。
例如
<transition name="fade">
<p v-if="show">hello</p>
</transition>
<style>
.fade-enter-active, .fade-leave-active {
transition: opacity .5s;
}
.fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
opacity: 0;
}
</style>
在文档中有介绍 过渡的类名 这里比如:
v-enter:定义进入过渡的开始状态。在元素被插入时生效,在下一个帧移除。
这是说在dom插入的时候应用样式,如果本来没有dom元素,如上面show=false
元素不显示, 把show=true,就会应用样式了。这个时候应用的是从v-enter--》v-enter-to的样式了。
这里设置的是
.fade-enter/* .fade-leave-active below version 2.1.8 */ {
opacity: 0;
}
所以从.fade-enter
-->.fade-enter-to
opacity:0
---->opacity:1
自己根据文档写的demo(其实是抄的) 戳这里codepen 可以f12 看下样式变化。
shoplist的 动画封装在loading组件中:
动画运行
- mounted钩子函数运行,属性positionY一直变化,背景样式也一直变化,使用雪碧图icon_loading.png来显示动画场景中的图片
<div class="load_img" :style="{backgroundPositionY: -(positionY%7)*2.5 + 'rem'}">
</div>
....
mounted () {
this.timer = setInterval(() => {
//一直循环运行
this.positionY++
}, 600)
},
....
@keyframes load{
0% {transform: translateY(0px);}
50% {transform: translateY(-50px);}
100% {transform: translateY(0px);}
}
.load_img{
@include wh(100%, 100%);
background: url('~/assets/images/icon_loading.png') no-repeat 0 0;
background-size: 2.5rem auto;
transform: translateY(0px);
animation: load .6s infinite ease-in-out; //使用load动画
position: relative;
z-index: 11;
}
- 动画下面的椭圆形背景随之变化
<svg class="load_ellipse" xmlns="http://www.w3.org/2000/svg" version="1.1">
<ellipse cx="26" cy="10" rx="26" ry="10" style="fill:#ddd;stroke:none;"></ellipse>
</svg>
....
@keyframes ellipse{
0% {transform: scale(1);}
50% {transform: scale(0.3);}
100% {transform: scale(1);}
}
.load_ellipse{
position: absolute;
@include wh(2.6rem, 2rem);
top: 2.2rem;
left: 0.2rem;
z-index: 10;
animation: ellipse .6s infinite ease-in-out;
}
- beforeDestroy beforeDestroy在组件被卸载,如页面跳转之后,就会被调用,清理掉timer,防止内存占用。
beforeDestroy () {
console.log('beforeDestroy in ')
clearInterval(this.timer)
}
这里使用到指令:
有的情况下,你仍然需要对普通 DOM 元素进行底层操作,这时候就会用到自定义指令。
触底加载数据作为一个指令来处理在mixin.js里面
export const loadMore = {
directives: {
'load-more': {
bind: (el, binding) => {
let windowHeight = window.screen.height
let height
let setTop
let paddingBottom
let marginBottom
let requestFram
let oldScrollTop
let scrollEl
let heightEl
let scrollType = el.attributes.type && el.attributes.type.value // 取得元素自定义属性
let scrollReduce = 2
if (scrollType === 2) {
scrollEl = el
heightEl = el.children[0]
} else {
scrollEl = document.body
heightEl = el
}
el.addEventListener('touchstart', () => {
height = heightEl.clientHeight
setTop = el.offsetTop
paddingBottom = getStyle(el, 'paddingBottom')
marginBottom = getStyle(el, 'marginBottom')
}, false)
el.addEventListener('touchmove', () => {
loadMore()
}, false)
el.addEventListener('touchend', () => {
oldScrollTop = scrollEl.scrollTop
moveEnd()
}, false)
const moveEnd = () => {
requestFram = requestAnimationFrame(() => {
if (scrollEl.scrollTop !== oldScrollTop) {
oldScrollTop = scrollEl.scrollTop
moveEnd()
} else {
cancelAnimationFrame(requestFram)
height = heightEl.clientHeight
loadMore()
}
})
}
const loadMore = () => {
if (scrollEl.scrollTop + windowHeight >= height + setTop + paddingBottom + marginBottom - scrollReduce) {
binding.value()// 这里就是v-load-more="xx",这里的xx就是对外暴露的接口了,可以调用外部的命令
}
}
}
}
}
}
在shopList中,代码使用mixins配置项,所以,这个组件就作为配置项(局部指令)融合如shopplist中了。注意,这里mixins.js是可以不是一个vue文件,可以只是一个模块化文件。 在shoplist 就可以使用v-xxx来使用指令了。
<ul v-load-more="loaderMore" v-if="shopListArr.length" type="1">
....
</ul>
<span v-if="Number(item.distance)">
这里Number()
可以参考MDN Number是一个全局对象,类似java的基本类型的包装类。
Number也有一些全局方法,比如Number.NaN()
类推也有Boolean
Boolean有助于条件判断。
- 入场动画
- 基础用法
- 触底加载数据