This commit is contained in:
hhh 2023-01-27 00:31:05 +08:00
parent aad126623c
commit ff71c70611
10 changed files with 124 additions and 82 deletions

View File

@ -1,6 +1,6 @@
<template> <template>
<from-bottom-dialog <from-bottom-dialog
page-id="home-index" :page-id="pageId"
:modelValue="modelValue" :modelValue="modelValue"
@update:modelValue="e=>$emit('update:modelValue',e)" @update:modelValue="e=>$emit('update:modelValue',e)"
@cancel="cancel" @cancel="cancel"
@ -35,7 +35,8 @@
<div class="love" @click="loved(item)"> <div class="love" @click="loved(item)">
<img v-show="item.isLoved" src="../assets/img/icon/components/like-red-small.png" alt="" <img v-show="item.isLoved" src="../assets/img/icon/components/like-red-small.png" alt=""
class="love-image"> class="love-image">
<img v-show="!item.isLoved" src="../assets/img/icon/components/like-gray-small.png" alt="" class="love-image"> <img v-show="!item.isLoved" src="../assets/img/icon/components/like-gray-small.png" alt=""
class="love-image">
<span>{{ formatNumber(item.loveNum) }}</span> <span>{{ formatNumber(item.loveNum) }}</span>
</div> </div>
</div> </div>
@ -136,6 +137,10 @@ export default {
type: String, type: String,
default: null default: null
}, },
pageId: {
type: String,
default: 'home-index'
},
height: { height: {
type: String, type: String,
default: '70vh' default: '70vh'

View File

@ -217,9 +217,12 @@ export default {
// eventTester("durationchange", ''); // // eventTester("durationchange", ''); //
// eventTester("volumechange", ''); // // eventTester("volumechange", ''); //
console.log('mounted')
bus.off('singleClickBroadcast')
bus.on('singleClickBroadcast', this.click) bus.on('singleClickBroadcast', this.click)
}, },
unmounted() { unmounted() {
console.log('unmounted')
bus.off('singleClickBroadcast', this.click) bus.off('singleClickBroadcast', this.click)
}, },
methods: { methods: {

View File

@ -10,7 +10,7 @@ import mixin from "./utils/mixin";
import VueLazyload from '@jambonn/vue-lazyload' import VueLazyload from '@jambonn/vue-lazyload'
import VConsole from 'vconsole'; import VConsole from 'vconsole';
const vConsole = new VConsole(); // const vConsole = new VConsole();
const app = Vue.createApp(App) const app = Vue.createApp(App)
app.config.globalProperties.$api = {...api} app.config.globalProperties.$api = {...api}

View File

@ -12,14 +12,18 @@
<div class="tab-ctn"> <div class="tab-ctn">
<div class="tabs" ref="tabs"> <div class="tabs" ref="tabs">
<div class="tab" :class="tabOneClass" @click.stop="change(0)"> <div class="tab" :class="tabOneClass" @click.stop="change(0)">
<span>同城</span> <span>热点</span>
<img v-show="index === 0" src="../../assets/img/icon/arrow-up-white.png" class="tab1-img"> <img v-show="index === 0" src="../../assets/img/icon/arrow-up-white.png" class="tab1-img">
</div> </div>
<div class="tab" :class="{active:index === 1}" @click.stop="change(1)"> <div class="tab" :class="{active:index === 1}" @click.stop="change(1)">
<span>关注</span> <span>社区</span>
<img src="../../assets/img/icon/live.webp" class="tab2-img"> <img src="../../assets/img/icon/live.webp" class="tab2-img">
</div> </div>
<div class="tab" :class="{active:index === 2}" @click.stop="change(2)"><span>推荐</span> <div class="tab" :class="{active:index === 2}" @click.stop="change(2)"><span>关注</span>
</div>
<div class="tab" :class="{active:index === 3}" @click.stop="change(3)"><span>商城</span>
</div>
<div class="tab" :class="{active:index === 4}" @click.stop="change(4)"><span>推荐</span>
</div> </div>
</div> </div>
<div class="indicator" ref="indicator"></div> <div class="indicator" ref="indicator"></div>
@ -123,7 +127,6 @@ export default {
this.initTabs() this.initTabs()
bus.on(this.name + '-moveX', this.move) bus.on(this.name + '-moveX', this.move)
bus.on(this.name + '-moveY', e => { bus.on(this.name + '-moveY', e => {
// console.log('moveY', e)
this.moveY = e this.moveY = e
}) })
bus.on(this.name + '-end', this.end) bus.on(this.name + '-end', this.end)
@ -162,7 +165,7 @@ export default {
move(e) { move(e) {
this.$setCss(this.indicatorRef, 'transition-duration', `0ms`) this.$setCss(this.indicatorRef, 'transition-duration', `0ms`)
this.$setCss(this.indicatorRef, 'left', this.$setCss(this.indicatorRef, 'left',
this.lefts[this.index] - this.lefts[this.index] +
e / (this.$store.state.bodyWidth / this.indicatorSpace) + 'px') e / (this.$store.state.bodyWidth / this.indicatorSpace) + 'px')
}, },
end(index) { end(index) {
@ -180,11 +183,11 @@ export default {
<style scoped lang="less"> <style scoped lang="less">
@import "@/assets/less/index"; @import "@/assets/less/index";
@height: 6rem; @height: 60rem;
.indicator-home { .indicator-home {
position: fixed; position: fixed;
font-size: 1.6rem; font-size: 16rem;
top: 0; top: 0;
left: 0; left: 0;
z-index: 2; z-index: 2;
@ -206,8 +209,8 @@ export default {
.loading { .loading {
opacity: 0; opacity: 0;
top: 1.3rem; top: 13rem;
right: 1.5rem; right: 15rem;
position: absolute; position: absolute;
} }
@ -218,13 +221,13 @@ export default {
width: 100%; width: 100%;
height: 100%; height: 100%;
box-sizing: border-box; box-sizing: border-box;
padding: 0 1.5rem; padding: 0 15rem;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
.tab-ctn { .tab-ctn {
width: 45%; width: 80%;
position: relative; position: relative;
.tabs { .tabs {
@ -242,16 +245,16 @@ export default {
@width: 1rem; @width: 1rem;
width: @width; width: @width;
height: @width; height: @width;
margin-left: .4rem; margin-left: 4rem;
transition: all .3s; transition: all .3s;
margin-top: .7rem; margin-top: 7rem;
} }
.tab2-img { .tab2-img {
position: absolute; position: absolute;
height: 1.5rem; height: 15rem;
left: 2.4rem; left: 24rem;
top: -.5rem; top: -5rem;
} }
&.open { &.open {
@ -266,38 +269,38 @@ export default {
} }
} }
.indicator { .indicator {
//transition: left .3s; //transition: left .3s;
position: absolute; position: absolute;
bottom: -0.8rem; bottom: -8rem;
height: .2rem; height: 2rem;
width: 2rem; width: 20rem;
//width: calc(100% / 5);
background: #fff; background: #fff;
border-radius: .5rem; border-radius: 5rem;
} }
} }
.search { .search {
width: 2rem; width: 20rem;
} }
} }
.toggle-type { .toggle-type {
@height: 10rem; @height: 100rem;
position: absolute; position: absolute;
height: @height; height: @height;
//padding-top: @height; //padding-top: @height;
padding-left: 1rem; padding-left: 10rem;
padding-right: 1rem; padding-right: 10rem;
padding-bottom: 1rem; padding-bottom: 10rem;
width: 100%; width: 100%;
background: @main-bg; background: @main-bg;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: flex-end; align-items: flex-end;
box-sizing: border-box; box-sizing: border-box;
font-size: 1.2rem; font-size: 12rem;
top: -@height; top: -@height;
transition: all .3s; transition: all .3s;
opacity: 0; opacity: 0;
@ -309,13 +312,13 @@ export default {
.l-button { .l-button {
flex: 1; flex: 1;
margin: 0 .3rem; margin: 0 3rem;
height: 2.8rem; height: 28rem;
background: rgb(33, 36, 45); background: rgb(33, 36, 45);
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
border-radius: 2rem; border-radius: 20rem;
color: rgb(157, 161, 170); color: rgb(157, 161, 170);
transition: all .3s; transition: all .3s;
@ -325,10 +328,10 @@ export default {
} }
img { img {
@width: .9rem; @width: 9rem;
width: @width; width: @width;
height: @width; height: @width;
margin-left: .8rem; margin-left: 8rem;
} }
} }

View File

@ -11,7 +11,7 @@
<SlideHorizontal <SlideHorizontal
name="main" name="main"
v-model:index="baseIndex" v-model:index="baseIndex"
style="height: calc(100% - 5rem);" style="height: calc(100% - 50rem);"
> >
<div class="slide-item"> <div class="slide-item">
<div class="nav-one" :class="{close:closeOne}"> <div class="nav-one" :class="{close:closeOne}">
@ -171,7 +171,7 @@ export default {
<div class="slide-item" data-index={itemIndex}> <div class="slide-item" data-index={itemIndex}>
<BVideo <BVideo
isPlay={play} isPlay={play}
video={item} item={item}
prefix={prefix} prefix={prefix}
index={itemIndex} index={itemIndex}
onShowComments={e => this.isCommenting = true} onShowComments={e => this.isCommenting = true}
@ -293,7 +293,7 @@ export default {
} }
.nav-one { .nav-one {
height: 14rem; height: 140rem;
box-sizing: border-box; box-sizing: border-box;
background: linear-gradient(to right, rgb(36, 34, 84), rgb(7, 5, 16)); background: linear-gradient(to right, rgb(36, 34, 84), rgb(7, 5, 16));
transition: all .3s; transition: all .3s;
@ -303,7 +303,7 @@ export default {
justify-content: space-between; justify-content: space-between;
.nav-item { .nav-item {
@width: 3.5rem; @width: 35rem;
display: flex; display: flex;
align-items: center; align-items: center;
flex-direction: column; flex-direction: column;
@ -311,20 +311,20 @@ export default {
img { img {
width: @width; width: @width;
height: @width; height: @width;
margin-bottom: .5rem; margin-bottom: 5rem;
} }
} }
&.close { &.close {
margin-top: -14rem; margin-top: -140rem;
} }
} }
@space-width: 1.5rem; @space-width: 15rem;
@icon-width: 5.2rem; @icon-width: 52rem;
.nav-two { .nav-two {
height: 18rem; height: 180rem;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: flex-end; justify-content: flex-end;
@ -337,7 +337,7 @@ export default {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
box-sizing: border-box; box-sizing: border-box;
margin-bottom: 1.5rem; margin-bottom: 15rem;
.right { .right {
color: gray; color: gray;
@ -346,9 +346,9 @@ export default {
} }
img { img {
width: 1rem; width: 10rem;
height: 1rem; height: 10rem;
margin-left: .4rem; margin-left: 4rem;
} }
} }
@ -361,7 +361,7 @@ export default {
width: @icon-width; width: @icon-width;
position: relative; position: relative;
margin-right: @space-width; margin-right: @space-width;
font-size: 1rem; font-size: 10rem;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
@ -373,7 +373,7 @@ export default {
} }
span { span {
margin-top: .8rem; margin-top: 8rem;
text-align: center; text-align: center;
width: @icon-width; width: @icon-width;
white-space: nowrap; white-space: nowrap;
@ -383,17 +383,17 @@ export default {
.tag { .tag {
background: rgb(239, 46, 137); background: rgb(239, 46, 137);
border-radius: .2rem; border-radius: 2rem;
padding: 0 .2rem; padding: 0 2rem;
bottom: 1.8rem; bottom: 18rem;
position: absolute; position: absolute;
font-size: 1rem; font-size: 10rem;
} }
} }
} }
&.close { &.close {
margin-top: -18rem; margin-top: -180rem;
} }
} }

View File

@ -65,6 +65,7 @@ export default {
if (this.next) { if (this.next) {
bus.emit(this.name + '-moveX', this.moveX) bus.emit(this.name + '-moveX', this.moveX)
this.$stopPropagation(e) this.$stopPropagation(e)
this.$setCss(this.wrapper, 'transform', this.$setCss(this.wrapper, 'transform',
`translate3d(${this.getDistance() `translate3d(${this.getDistance()

View File

@ -12,13 +12,17 @@ const props = defineProps({
return 0 return 0
} }
}, },
name: {
type: String,
default: () => ''
},
}) })
const emit = defineEmits(['update:index']) const emit = defineEmits(['update:index'])
const judgeValue = 20 const judgeValue = 20
const wrapperEl = ref(null) const wrapperEl = ref(null)
const state = reactive({ const state = reactive({
name: 'SlideHorizontal', name: props.name,
localIndex: props.index, localIndex: props.index,
needCheck: true, needCheck: true,
next: false, next: false,
@ -39,7 +43,7 @@ watch(
) )
onMounted(() => { onMounted(() => {
slideInit(wrapperEl.value,state,SlideType.HORIZONTAL) slideInit(wrapperEl.value, state, SlideType.HORIZONTAL)
}) })
function touchStart(e) { function touchStart(e) {
@ -47,7 +51,7 @@ function touchStart(e) {
} }
function touchMove(e) { function touchMove(e) {
slideTouchMove(e, wrapperEl.value, state, judgeValue, canNext,null, SlideType.HORIZONTAL) slideTouchMove(e, wrapperEl.value, state, judgeValue, canNext, null, SlideType.HORIZONTAL)
} }
function touchEnd(e) { function touchEnd(e) {

View File

@ -1,9 +1,11 @@
<script setup lang="jsx"> <script setup lang="jsx">
import {onMounted, reactive, ref, watch, createApp} from "vue"; import {onMounted, reactive, ref, watch, createApp, computed} from "vue";
import GM from '../../utils' import GM from '../../utils'
import {getSlideDistance, slideInit, slideReset, slideTouchEnd, slideTouchMove, slideTouchStart} from "./common"; import {getSlideDistance, slideInit, slideReset, slideTouchEnd, slideTouchMove, slideTouchStart} from "./common";
import {SlideType} from "../../utils/const_var"; import {SlideType} from "../../utils/const_var";
import SlideItem from './SlideItem' import SlideItem from './SlideItem'
import bus from "../../utils/bus";
import {useStore} from 'vuex'
const props = defineProps({ const props = defineProps({
index: { index: {
@ -34,15 +36,18 @@ const props = defineProps({
type: Number, type: Number,
default: () => 5 default: () => 5
}, },
name: {
type: String,
default: () => ''
},
}) })
const emit = defineEmits(['update:index']) const emit = defineEmits(['update:index'])
const appInsMap = new Map() const appInsMap = new Map()
const judgeValue = 20
const slideItemClassName = 'slide-item2' const slideItemClassName = 'slide-item2'
const wrapperEl = ref(null) const wrapperEl = ref(null)
const state = reactive({ const state = reactive({
name: 'SlideVerticalInfinite', name: props.name,
localIndex: props.index, localIndex: props.index,
needCheck: true, needCheck: true,
next: false, next: false,
@ -50,6 +55,9 @@ const state = reactive({
move: {x: 0, y: 0}, move: {x: 0, y: 0},
wrapper: {width: 0, height: 0, childrenLength: 0} wrapper: {width: 0, height: 0, childrenLength: 0}
}) })
const store = useStore()
const homeRefresh = computed(() => store.state.homeRefresh)
const judgeValue = computed(() => store.state.judgeValue)
watch( watch(
() => props.index, () => props.index,
@ -80,8 +88,6 @@ function insertContent(list = props.list) {
start = end - 5 start = end - 5
} }
if (start < 0) start = 0 if (start < 0) start = 0
console.log('start', start)
console.log('end', end)
list.slice(start, end).map( list.slice(start, end).map(
(item, index) => { (item, index) => {
//0jqtrigger play //0jqtrigger play
@ -125,10 +131,15 @@ function touchStart(e) {
} }
function touchMove(e) { function touchMove(e) {
slideTouchMove(e, wrapperEl.value, state, judgeValue, canNext, null, SlideType.VERTICAL) slideTouchMove(e, wrapperEl.value, state, judgeValue.value, canNext, null, SlideType.VERTICAL)
} }
function touchEnd(e) { function touchEnd(e) {
let isNext = state.move.y < 0
if (state.localIndex === 0 && !isNext && state.move.y > (homeRefresh.value + judgeValue.value)) {
console.log('loading')
// bus.emit(props.prefix + '-loading')
}
slideTouchEnd(e, state, canNext, (isNext) => { slideTouchEnd(e, state, canNext, (isNext) => {
if (isNext) { if (isNext) {
let addItemIndex = state.localIndex + 2 let addItemIndex = state.localIndex + 2

View File

@ -42,11 +42,19 @@ export function slideTouchMove(e, el, state, judgeValue, canNextCb, nextCb, type
let isNext = type === SlideType.HORIZONTAL ? state.move.x < 0 : state.move.y < 0 let isNext = type === SlideType.HORIZONTAL ? state.move.x < 0 : state.move.y < 0
let canSlideRes = canSlide(state, judgeValue, type)
//当
if (canSlideRes && state.localIndex === 0 && !isNext && type === SlideType.VERTICAL) {
bus.emit(state.name + '-moveY', state.move.y)
}
if (!canNextCb?.(isNext, e)) return if (!canNextCb?.(isNext, e)) return
if (canSlide(state, judgeValue, type)) { if (canSlideRes) {
nextCb?.() nextCb?.()
if (type === SlideType.HORIZONTAL) {
bus.emit(state.name + '-moveX', state.move.x) bus.emit(state.name + '-moveX', state.move.x)
}
Utils.$stopPropagation(e) Utils.$stopPropagation(e)
let t = getSlideDistance(state, type) + (isNext ? judgeValue : -judgeValue) let t = getSlideDistance(state, type) + (isNext ? judgeValue : -judgeValue)
let dx1 = 0 let dx1 = 0
@ -82,9 +90,6 @@ export function slideTouchEnd(e, state, canNextCb, nextCb, notNextCb, type = Sli
} else { } else {
state.localIndex-- state.localIndex--
} }
return nextCb?.(isNext) return nextCb?.(isNext)
} }
} }
@ -97,8 +102,10 @@ export function slideReset(el, state, type, emit) {
let dx1 = 0 let dx1 = 0
let dx2 = 0 let dx2 = 0
if (type === SlideType.HORIZONTAL) { if (type === SlideType.HORIZONTAL) {
bus.emit(state.name + '-end', state.localIndex)
dx1 = t dx1 = t
} else { } else {
bus.emit(state.name + '-end',)
dx2 = t dx2 = t
} }
Utils.$setCss(el, 'transform', `translate3d(${dx1}px, ${dx2}px, 0)`) Utils.$setCss(el, 'transform', `translate3d(${dx1}px, ${dx2}px, 0)`)
@ -106,7 +113,6 @@ export function slideReset(el, state, type, emit) {
state.next = false state.next = false
state.needCheck = true state.needCheck = true
emit?.('update:index', state.localIndex) emit?.('update:index', state.localIndex)
bus.emit(state.name + '-end', state.localIndex)
} }
export function getSlideDistance(state, type = SlideType.HORIZONTAL) { export function getSlideDistance(state, type = SlideType.HORIZONTAL) {

View File

@ -1,11 +1,16 @@
<template> <template>
<div class="test-slide-wrapper" id="slideHook" v-love="'slideHook'"> <div class="test-slide-wrapper" id="slideHook" v-love="'slideHook'">
<H v-model:index="state.baseIndex"> <H v-model:index="state.baseIndex">
<SlideItem class=" gray"> <SlideItem>
<H class="h" v-model:index="state.navIndex"> <IndicatorHome
<SlideItem class=" gray"> v-hide="state.isUp"
<div class="big">找红包</div> :loading="state.loading"
</SlideItem> name="main"
v-model:index="state.navIndex"
/>
<H class="h"
name="main"
v-model:index="state.navIndex">
<SlideItem class=" gray"> <SlideItem class=" gray">
<div class="big">热点</div> <div class="big">热点</div>
</SlideItem> </SlideItem>
@ -18,8 +23,9 @@
<SlideItem class=" gray"> <SlideItem class=" gray">
<div class="big">商城</div> <div class="big">商城</div>
</SlideItem> </SlideItem>
<SlideItem class=""> <SlideItem>
<VInfinite <VInfinite
name="main"
v-model:index="state.itemIndex" v-model:index="state.itemIndex"
:render="render" :render="render"
:list="state.recommendVideos" :list="state.recommendVideos"
@ -48,6 +54,7 @@
</SlideItem> </SlideItem>
</H> </H>
</div> </div>
<Comment page-id="slideHook" v-model="state.isCommenting"/>
</template> </template>
<script setup lang="jsx"> <script setup lang="jsx">
@ -56,6 +63,8 @@ import VInfinite from './VInfinite.vue'
import SlideItem from './SlideItem' import SlideItem from './SlideItem'
import SlideImgs from "../../components/slide/SlideAlbum"; import SlideImgs from "../../components/slide/SlideAlbum";
import BVideo from "../../components/slide/BVideo"; import BVideo from "../../components/slide/BVideo";
import Comment from "../../components/Comment";
import IndicatorHome from "../slide/IndicatorHome";
import resource from "../../assets/data/resource.js"; import resource from "../../assets/data/resource.js";
import {onMounted, onUnmounted, reactive} from "vue"; import {onMounted, onUnmounted, reactive} from "vue";
@ -64,7 +73,7 @@ import {useNav} from "../../utils/hooks/useNav";
const nav = useNav() const nav = useNav()
const videos = resource.videos.slice(0,5).map(v => { const videos = resource.videos.slice(0, 6).map(v => {
v.type = 'recommend-video' v.type = 'recommend-video'
return v return v
}) })
@ -72,7 +81,7 @@ const videos = resource.videos.slice(0,5).map(v => {
const state = reactive({ const state = reactive({
baseIndex: 0, baseIndex: 0,
navIndex: 5, navIndex: 4,
itemIndex: 0, itemIndex: 0,
recommendVideos: [ recommendVideos: [
// { // {
@ -89,6 +98,8 @@ const state = reactive({
isCommenting: false, isCommenting: false,
isSharing: false, isSharing: false,
canMove: true, canMove: true,
loading: false,
isUp: false,
shareType: -1, shareType: -1,
@ -118,9 +129,7 @@ onMounted(() => {
state.recommendVideos[itemIndex] = val.item state.recommendVideos[itemIndex] = val.item
} }
}) })
bus.on('nav', path => { bus.on('nav', path => nav(path))
nav(path)
})
}) })
onUnmounted(() => { onUnmounted(() => {
bus.offAll() bus.offAll()
@ -136,7 +145,7 @@ function render(item, itemIndex, play, position) {
} }
if (item.type === 'recommend-video') { if (item.type === 'recommend-video') {
node = <BVideo node = <BVideo
isPlay={play} isPlay={false}
item={item} item={item}
position={{...position, itemIndex}} position={{...position, itemIndex}}
onShowComments={e => state.isCommenting = true} onShowComments={e => state.isCommenting = true}