面板滑动效果,父组件是resultPanel,子组件是resultOption,仿照了iview中,Select组件的写法。
<template>
<div v-if="visiable">
<div class="transparent" :class="{active:resultPanelStatus==='top'}"></div>
<div class="mapbox-result"
ref="resultPanel"
style="z-index: 101;"
@touchstart="onTouchStart"
@touchmove="onTouchMove"
@touchend="onTouchEnd"
:style="slideEffect"
>
<div class="mapbox-result-content">
<a class="mapbox-result-close" v-if="closable" @click="close"></a>
<div class="mapbox-result-header">
<slot name="header">
<div class="mapbox-result-header-title">共找到【{
{header}}】相关{
{total}}结果</div>
</slot>
</div>
<div
class="mapbox-result-body"
ref="resultBody"
>
<result-option
ref="option"
v-for="(item, index) in data"
:index="index+1"
:name="item.name"
:meter="item.meter?item.meter:0"
:floor-name="item.floorName"
:key="index"
v-show="visiable"
@on-click-gohere="handleNavigate(index)"
@on-click-item="focusResultOnMap(index)"
></result-option>
</div>
</div>
</div>
</div>
</template>
<script>
import resultOption from './resultOption';
export default {
name: 'result-panel',
components: {resultOption},
props: {
header: {
type: String
},
// value: {
// type: Boolean,
// default: true
// },
closable: {
type: Boolean,
default: true
},
data: {
type: Array,
default: []
}
},
data() {
return {
// visiable: true,
resultPanelStatus: 'normal', //'normal'、'top'
cloneData: this.deepCopy(this.data),
startY: 0, // 开始触摸屏幕的点
endY: 0, // 离开屏幕的点
moveY: 0, // 滑动时的距离
disY: 0, // 移动距离
slideEffect: '' //滑动效果
}
},
mounted() {
// this.$refs.resultBody.style.height = `${this.defaultHeight - 60}px`;
// this.$refs.resultBody.style.overflowY = 'hidden';
},
computed: {
total() {
return this.data.length;
},
defaultHeight() {
return this.data.length > 3 ? 240 : this.data.length * 60 + 60 //当结果大于3时,默认只显示三个
},
visiable() {
this.resultPanelStatus = 'normal';
this.slideEffect = `transform: translateY(-${this.defaultHeight}px); transition: all .5s`;
return this.$store.state.resultPanel.show;
}
},
methods: {
/**
* 手指接触屏幕
*/
onTouchStart(ev) {