Browse Source

提取通用的indicator成为组件

pull/19/head
zyronon 4 years ago
parent
commit
bd2ff39713
  1. 137
      src/components/Indicator.vue
  2. 84
      src/components/slide/SlideRowList.vue
  3. 20
      src/pages/me/Me.vue
  4. 65
      src/pages/people/FindAcquaintance.vue
  5. 18
      src/utils/bus.js
  6. 1
      src/utils/global-methods.js

137
src/components/Indicator.vue

@ -0,0 +1,137 @@ @@ -0,0 +1,137 @@
<template>
<div class="indicator-ctn" :class="fixed?'fixed':''">
<div class="tabs" ref="tabs">
<div class="tab"
:style="{width : tabStyleWidth}"
v-for="(item,index) in tabTexts"
:class="currentSlideItemIndex === index?'active':''"
@click="changeIndex(index)">
<span>{{ item }}</span></div>
</div>
<div class="indicator"
ref="indicator"
:style="{width : tabStyleWidth}"
></div>
</div>
</template>
<script>
import bus from "../utils/bus";
export default {
name: "Indicator",
props: {
fixed: {
type: Boolean,
default: () => false
},
activeIndex: {
type: Number,
default: () => 0
},
tabStyleWidth: {
type: String,
default: () => '50%'
},
tabTexts: {
type: Array,
default: () => []
},
},
data() {
return {
indicatorFixed: false,
currentSlideItemIndex: this.activeIndex,
tabIndicatorRelationActiveIndexLefts: [],//slideItemindexleft,
indicatorSpace: 0,//indicator
}
},
computed: {},
mounted() {
this.initTabs()
bus.on('move', this.move)
bus.on('end', this.end)
},
methods: {
changeIndex(index) {
this.currentSlideItemIndex = index
this.$attrs['onUpdate:active-index'] && this.$emit('update:active-index', this.currentSlideItemIndex)
this.$setCss(this.indicatorRef, 'transition-duration', `300ms`)
this.$setCss(this.indicatorRef, 'left', this.tabIndicatorRelationActiveIndexLefts[this.currentSlideItemIndex] + 'px')
},
initTabs() {
let tabs = this.$refs.tabs
this.indicatorRef = this.$refs.indicator
for (let i = 0; i < tabs.children.length; i++) {
let item = tabs.children[i]
this.tabWidth = this.$getCss(item, 'width')
this.tabIndicatorRelationActiveIndexLefts.push(
item.getBoundingClientRect().x - tabs.children[0].getBoundingClientRect().x + (this.indicatorType === 'home' ? this.tabWidth * 0.15 : 0))
}
this.indicatorSpace = this.tabIndicatorRelationActiveIndexLefts[1] - this.tabIndicatorRelationActiveIndexLefts[0]
this.$setCss(this.indicatorRef, 'transition-duration', `0ms`)
this.$setCss(this.indicatorRef, 'left', this.tabIndicatorRelationActiveIndexLefts[this.currentSlideItemIndex] + 'px')
},
move(e) {
this.$setCss(this.indicatorRef, 'left',
this.tabIndicatorRelationActiveIndexLefts[this.currentSlideItemIndex] -
e.x.distance / (this.$store.state.bodyWidth / this.indicatorSpace) + 'px')
},
end(index) {
console.log(index)
this.currentSlideItemIndex = index
this.$setCss(this.indicatorRef, 'transition-duration', `300ms`)
this.$setCss(this.indicatorRef, 'left',
this.tabIndicatorRelationActiveIndexLefts[this.currentSlideItemIndex] + 'px')
setTimeout(() => {
this.$setCss(this.indicatorRef, 'transition-duration', `0ms`)
}, 300)
}
}
}
</script>
<style scoped lang="scss">
@import "../assets/scss/index";
.indicator-ctn {
width: 100%;
top: 0;
left: 0;
right: 0;
z-index: 999;
background: $main-bg;
.tabs {
display: flex;
justify-content: space-between;
font-weight: bold;
.tab {
height: 40px;
width: 45%;
display: flex;
justify-content: center;
align-items: center;
color: gray;
transition: color .3s;
&.active {
color: white;
}
}
}
.indicator {
height: 2px;
background: gold;
width: 45%;
position: relative;
transition: all .3s;
}
}
.indicator-ctn.fixed {
position: fixed;
}
</style>

84
src/components/slide/SlideRowList.vue

@ -20,25 +20,7 @@ @@ -20,25 +20,7 @@
</div>
<div class="loading" :style="loadingStyle">AA</div>
</div>
<div class="indicator-me" :class="indicatorFixed?'fixed':''" v-if="showIndicator && indicatorType === 'me'">
<div class="tabs" ref="tabs">
<div class="tab"
:class="currentSlideItemIndex === 0?'active':''"
@click="changeIndex(false,0)">
<span>作品</span></div>
<div class="tab"
:class="currentSlideItemIndex === 1?'active':''"
@click.stop="changeIndex(false,1)">
<span>私密</span>
</div>
<div class="tab"
:class="currentSlideItemIndex === 2?'active':''"
@click="changeIndex(false,2,$event)">
<span>喜欢</span>
</div>
</div>
<div class="indicator" ref="indicator"></div>
</div>
<slot name="indicator"></slot>
<div id="base-slide-list" ref="slideList"
:style="{'flex-direction':'row',marginTop:indicatorFixed?'42px':'0'}"
@touchstart="touchStart($event)"
@ -50,7 +32,7 @@ @@ -50,7 +32,7 @@
</template>
<script>
import {nextTick} from 'vue'
import bus from "../../utils/bus";
export default {
name: "BaseSlideList",
@ -155,6 +137,7 @@ export default { @@ -155,6 +137,7 @@ export default {
await this.checkChildren(true)
this.showIndicator && this.initTabs()
this.changeIndex(true)
console.log(this.$slots.indicator)
},
methods: {
changeIndex(init = false, index = null, e) {
@ -218,7 +201,6 @@ export default { @@ -218,7 +201,6 @@ export default {
//todo js
// this.$attrs['onMove'] && this.$emit('move', {
// x: {distance: this.moveXDistance, isDrawRight: this.isDrawRight},
// y: {distance: this.moveYDistance, isDrawDown: this.isDrawDown},
// })
//this.isCanDownWiping toolbar
@ -233,6 +215,10 @@ export default { @@ -233,6 +215,10 @@ export default {
//
if (this.currentSlideItemIndex === this.slideItems.length - 1 && this.isDrawRight) return
bus.emit('move', {
x: {distance: this.moveXDistance, isDrawRight: this.isDrawRight},
})
this.$stopPropagation(e)
this.$setCss(this.slideList, 'transform', `translate3d(${-this.getWidth(this.currentSlideItemIndex) +
this.moveXDistance +
@ -242,14 +228,7 @@ export default { @@ -242,14 +228,7 @@ export default {
this.moveXDistance / (this.$store.state.bodyWidth / this.indicatorSpace) + 'px')
}
},
getData() {
this.loading = true
setTimeout(() => {
this.loading = false
}, 1500)
},
touchEnd(e) {
this.$attrs['onEnd'] && this.$emit('end')
if (this.useHomeLoading) {
if (this.homeLoadingMoveYDistance > 60) {
this.getData()
@ -289,6 +268,8 @@ export default { @@ -289,6 +268,8 @@ export default {
}
this.resetConfig()
this.$attrs['onUpdate:active-index'] && this.$emit('update:active-index', this.currentSlideItemIndex)
this.$attrs['onEnd'] && this.$emit('end')
bus.emit('end', this.currentSlideItemIndex)
},
resetConfig() {
this.isCanRightWiping = false
@ -296,6 +277,12 @@ export default { @@ -296,6 +277,12 @@ export default {
this.moveXDistance = 0
this.moveYDistance = 0
},
getData() {
this.loading = true
setTimeout(() => {
this.loading = false
}, 1500)
},
getWidth(index) {
return this.slideItemsWidths.reduce((p, c, i) => {
if (i < index) {
@ -417,47 +404,6 @@ export default { @@ -417,47 +404,6 @@ export default {
}
}
}
.indicator-me {
top: 0;
left: 0;
right: 0;
z-index: 999;
background: $main-bg;
.tabs {
display: flex;
justify-content: space-between;
font-weight: bold;
.tab {
height: 40px;
width: 33%;
display: flex;
justify-content: center;
align-items: center;
color: gray;
transition: color .3s;
&.active {
color: white;
}
}
}
.indicator {
height: 2px;
background: gold;
width: 33%;
position: relative;
transition: all .3s;
}
}
.indicator-me.fixed {
position: fixed;
}
}
</style>

20
src/pages/me/Me.vue

@ -1,9 +1,9 @@ @@ -1,9 +1,9 @@
<template>
<div class="Me">
<SlideRowList style="width: 100vw;"
@first="first"
@end="end"
v-model:active-index="baseActiveIndex"
@first="first"
@end="end"
v-model:active-index="baseActiveIndex"
>
<SlideItem style="overflow:auto;" :style="contentStyle" @scroll="scroll" @click="click">
<div ref="desc" class="desc">
@ -58,11 +58,15 @@ @@ -58,11 +58,15 @@
</div>
</div>
<div ref="content" style="margin-bottom: 60px;">
<Indicator
:fixed="indicatorFixed"
tabStyleWidth="33%"
:tabTexts="['作品','私密','喜欢']"
v-model:active-index="contentIndex">
</Indicator>
<SlideRowList
:show-indicator="true"
:indicator-fixed="indicatorFixed"
indicator-type="me"
@end="end"
:indicator-fixed="indicatorFixed"
v-model:active-index="contentIndex">
<SlideItem>
<div ref="tab-content1">
@ -198,10 +202,11 @@ @@ -198,10 +202,11 @@
<script>
import Posters from '../../components/Posters'
import Footer from "../../components/Footer";
import Indicator from '../../components/Indicator'
export default {
name: "Me",
components: { Posters, Footer},
components: {Posters, Footer, Indicator},
data() {
return {
serviceEl: {},
@ -459,6 +464,7 @@ export default { @@ -459,6 +464,7 @@ export default {
}
ul {
width: 100%;
height: 100%;
overflow: auto;
padding: 0;

65
src/pages/people/FindAcquaintance.vue

@ -1,6 +1,15 @@ @@ -1,6 +1,15 @@
<template>
<div class="FindAcquaintance">
<SlideRowList>
<div class="header">
<img src="../../assets/img/icon/back.png" alt="" class="back">
<Indicator
tabStyleWidth="40%"
:tabTexts="['熟人列表','发现熟人']"
v-model:active-index="currentSlideItemIndex">
</Indicator>
<img src="../../assets/img/icon/back.png" alt="" class="option">
</div>
<SlideRowList v-model:active-index="currentSlideItemIndex">
<SlideItem>
<Search class="vue"></Search>
<People v-for="item in list " :people="item"></People>
@ -10,7 +19,6 @@ @@ -10,7 +19,6 @@
<Search class="vue" @click="findAddressListDialog = true"></Search>
</SlideItem>
</SlideRowList>
<div v-if="findAddressListDialog" class="dialog find-address-list">
<div class="content">
<div class="body">
@ -34,16 +42,20 @@ @@ -34,16 +42,20 @@
<script>
import People from './components/People'
import Search from '../../components/Search'
import Indicator from '../../components/Indicator'
export default {
name: "FindAcquaintance",
components: {
People,
Search
Search,
Indicator
},
data() {
return {
findAddressListDialog: false,
indicatorFixed: false,
currentSlideItemIndex: 1,
list: [
{
type: 1,
@ -60,11 +72,11 @@ export default { @@ -60,11 +72,11 @@ export default {
{
type: 5,
},
]
],
}
},
computed: {},
created() {
mounted() {
},
methods: {}
}
@ -85,6 +97,49 @@ export default { @@ -85,6 +97,49 @@ export default {
}
.header {
display: flex;
justify-content: space-between;
}
.indicator-ctn {
width: 50%;
top: 0;
left: 0;
right: 0;
z-index: 999;
background: $main-bg;
.tabs {
display: flex;
justify-content: space-between;
font-weight: bold;
.tab {
height: 40px;
width: 45%;
display: flex;
justify-content: center;
align-items: center;
color: gray;
transition: color .3s;
&.active {
color: white;
}
}
}
.indicator {
height: 2px;
background: gold;
width: 45%;
position: relative;
transition: all .3s;
}
}
.dialog {
z-index: 10;
position: absolute;

18
src/utils/bus.js

@ -0,0 +1,18 @@ @@ -0,0 +1,18 @@
export default {
eventMap: new Map(),
on(eventType, cb) {
let cbs = this.eventMap.get(eventType)
if (cbs) {
cbs.push(cb)
} else {
cbs = [cb]
}
this.eventMap.set(eventType, cbs)
},
emit(eventType, val) {
let cbs = this.eventMap.get(eventType)
if (cbs) {
cbs.map(cb => cb(val))
}
}
}

1
src/utils/global-methods.js

@ -103,6 +103,7 @@ export default { @@ -103,6 +103,7 @@ export default {
return parseFloat(val)
},
$setCss(el, key, value) {
// console.log(value)
if (key === 'transform') {
//直接设置不生效
el.style.webkitTransform = el.style.MsTransform = el.style.msTransform = el.style.MozTransform = el.style.OTransform = el.style.transform = value;

Loading…
Cancel
Save