Browse Source

优化

pull/29/head
zyronon 2 years ago
parent
commit
cc725a994c
  1. 16
      src/components/slide/BVideo.vue
  2. 48
      src/components/slide/SlideVerticalInfinite.vue
  3. 1
      src/mock/index.js
  4. 123
      src/pages/home/index.vue
  5. 34
      src/pages/home/slide/Slide1.vue
  6. 72
      src/pages/home/slide/SlideList.vue
  7. 4
      src/store/index.js
  8. 1
      src/utils/bus.js
  9. 5
      src/utils/hooks/useSlideListItemRender.jsx
  10. 3
      src/utils/index.jsx

16
src/components/slide/BVideo.vue

@ -94,12 +94,6 @@ export default {
return {} return {}
} }
}, },
index: {
type: Number,
default: () => {
return -1
}
},
position: { position: {
type: Object, type: Object,
default: () => { default: () => {
@ -169,6 +163,7 @@ export default {
} }
}, },
mounted() { mounted() {
console.log('video', this.localItem.id)
// console.log(this.commentVisible) // console.log(this.commentVisible)
this.height = document.body.clientHeight this.height = document.body.clientHeight
this.width = document.body.clientWidth this.width = document.body.clientWidth
@ -282,12 +277,11 @@ export default {
this.commentVisible = false this.commentVisible = false
} }
}, },
click({baseIndex, navIndex, itemIndex, type}) { click({uniqueId, index, type}) {
// console.log(baseIndex, navIndex, itemIndex, this.position) // console.log(this.position)
if ( if (
this.position.baseIndex === baseIndex && this.position.uniqueId === uniqueId &&
this.position.navIndex === navIndex && this.position.index === index
this.position.itemIndex === itemIndex
) { ) {
if (type === EVENT_KEY.ITEM_TOGGLE) { if (type === EVENT_KEY.ITEM_TOGGLE) {
if (this.status === SlideItemPlayStatus.Play) { if (this.status === SlideItemPlayStatus.Play) {

48
src/components/slide/SlideVerticalInfinite.vue

@ -6,6 +6,7 @@ import {SlideType} from "@/utils/const_var";
import SlideItem from '@/components/slide/SlideItem.vue' import SlideItem from '@/components/slide/SlideItem.vue'
import bus, {EVENT_KEY} from "../../utils/bus"; import bus, {EVENT_KEY} from "../../utils/bus";
import {useStore} from 'vuex' import {useStore} from 'vuex'
import Loading from "@/components/Loading.vue";
const props = defineProps({ const props = defineProps({
index: { index: {
@ -14,12 +15,6 @@ const props = defineProps({
return 0 return 0
} }
}, },
position: {
type: Object,
default: () => {
return {}
}
},
render: { render: {
type: Function, type: Function,
default: () => { default: () => {
@ -40,6 +35,18 @@ const props = defineProps({
type: String, type: String,
default: () => '' default: () => ''
}, },
uniqueId: {
type: String,
default: () => ''
},
loading: {
type: Boolean,
default: () => false
},
active: {
type: Boolean,
default: () => false
},
}) })
const emit = defineEmits(['update:index', 'loadMore']) const emit = defineEmits(['update:index', 'loadMore'])
@ -86,26 +93,36 @@ watch(
}) })
} }
} }
} })
)
watch( watch(
() => props.index, () => props.index,
(newVal, oldVal) => { (newVal, oldVal) => {
// console.log('watch-index', newVal, oldVal,props.list, props.list[newVal].id) // console.log('watch-index', newVal, oldVal,props.list, props.list[newVal].id)
bus.emit(EVENT_KEY.SINGLE_CLICK_BROADCAST, { bus.emit(EVENT_KEY.SINGLE_CLICK_BROADCAST, {
...props.position, uniqueId: props.uniqueId,
itemIndex: newVal, index: newVal,
type: EVENT_KEY.ITEM_PLAY type: EVENT_KEY.ITEM_PLAY
}) })
setTimeout(() => { setTimeout(() => {
bus.emit(EVENT_KEY.SINGLE_CLICK_BROADCAST, { bus.emit(EVENT_KEY.SINGLE_CLICK_BROADCAST, {
...props.position, uniqueId: props.uniqueId,
itemIndex: oldVal, index: oldVal,
type: EVENT_KEY.ITEM_STOP type: EVENT_KEY.ITEM_STOP
}) })
}, 200) }, 200)
} })
)
watch(
() => props.active,
(newVal, oldVal) => {
console.log('newVal', newVal, 'oldVal', oldVal)
bus.emit(EVENT_KEY.SINGLE_CLICK_BROADCAST, {
uniqueId: props.uniqueId,
index: state.localIndex,
type: newVal === false ? EVENT_KEY.ITEM_STOP : EVENT_KEY.ITEM_PLAY
})
})
onMounted(() => { onMounted(() => {
slideInit(wrapperEl.value, state, SlideType.VERTICAL) slideInit(wrapperEl.value, state, SlideType.VERTICAL)
@ -157,7 +174,7 @@ defineExpose({dislike})
function getInsEl(item, index, play = false) { function getInsEl(item, index, play = false) {
// console.log('index', index, play) // console.log('index', index, play)
let slideVNode = props.render(item, index, play, props.position) let slideVNode = props.render(item, index, play, props.uniqueId)
const app = createApp({ const app = createApp({
render() { render() {
return <SlideItem data-index={index}>{slideVNode}</SlideItem> return <SlideItem data-index={index}>{slideVNode}</SlideItem>
@ -252,6 +269,7 @@ function canNext(isNext) {
<template> <template>
<div class="slide slide-infinite"> <div class="slide slide-infinite">
<Loading v-if="props.loading && props.list.length === 0"/>
<div class="slide-list flex-direction-column" <div class="slide-list flex-direction-column"
ref="wrapperEl" ref="wrapperEl"
@click="null" @click="null"

1
src/mock/index.js

@ -19,6 +19,7 @@ function getPage(options) {
Mock.setup({ Mock.setup({
timeout: '500-1000' timeout: '500-1000'
// timeout: '5000'
}) })
let allRecommendVideos = resource.videos.map(v => { let allRecommendVideos = resource.videos.map(v => {
v.type = 'recommend-video' v.type = 'recommend-video'

123
src/pages/home/index.vue

@ -158,6 +158,7 @@ const p = {
} }
const store = useStore() const store = useStore()
const loading = computed(() => store.state.loading)
const friends = computed(() => store.state.friends) const friends = computed(() => store.state.friends)
const bodyHeight = computed(() => store.state.bodyHeight) const bodyHeight = computed(() => store.state.bodyHeight)
const bodyWidth = computed(() => store.state.bodyWidth) const bodyWidth = computed(() => store.state.bodyWidth)
@ -168,14 +169,6 @@ const state = reactive({
baseIndex: 0, baseIndex: 0,
navIndex: 0, navIndex: 0,
test: '', test: '',
slide0: {
loading: false,
index: 0,
list: [],
totalSize: 0,
pageSize: 10,
pageNo: 0,
},
slide1: { slide1: {
loading: false, loading: false,
index: 0, index: 0,
@ -225,9 +218,7 @@ const state = reactive({
], ],
isSharing: false, isSharing: false,
canMove: true, canMove: true,
shareType: -1, shareType: -1,
showPlayFeedback: false, showPlayFeedback: false,
showShareDuoshan: false, showShareDuoshan: false,
showShareDialog: false, showShareDialog: false,
@ -247,42 +238,10 @@ const state = reactive({
//zindexslidesubType. //zindexslidesubType.
subTypeIsTop: false, subTypeIsTop: false,
}) })
//
const loading = computed(() => { // const loading = computed(() => {
return state[`slide${state.navIndex}`].loading // return state[`slide${state.navIndex}`].loading
}) // })
watch(
() => state.navIndex,
(newVal, oldValue) => {
if (newVal === 0 && state.slide0.list.length === 0) {
}
if (newVal === 4 && state.slide4.list.length === 0) {
return getSlide4Data()
}
if (newVal === 2) return
if ([0, 2, 4].includes(newVal)) {
let playItemIndex = state[`slide${newVal}`].index
bus.emit(EVENT_KEY.SINGLE_CLICK_BROADCAST, {
baseIndex: state.baseIndex,
navIndex: newVal,
itemIndex: playItemIndex,
type: EVENT_KEY.ITEM_TOGGLE
})
}
if ([0, 2, 4].includes(oldValue)) {
let stopItemIndex = state[`slide${oldValue}`].index
setTimeout(() => {
bus.emit(EVENT_KEY.SINGLE_CLICK_BROADCAST, {
baseIndex: state.baseIndex,
navIndex: oldValue,
itemIndex: stopItemIndex,
type: EVENT_KEY.ITEM_STOP
})
}, 200)
}
})
async function getSlide4Data(refresh = false) { async function getSlide4Data(refresh = false) {
@ -417,78 +376,6 @@ function render(item, itemIndex, play, position) {
height: calc(100vh - @footer-height) !important; height: calc(100vh - @footer-height) !important;
overflow: hidden; overflow: hidden;
#slide0 {
position: relative;
.sub-type {
width: 100%;
position: fixed;
top: 0;
&.top {
z-index: 2;
}
.local {
transition: all .3s;
font-size: 14rem;
color: gray;
background: #f9f9f9;
display: flex;
justify-content: center;
align-items: center;
.card {
margin: 20rem;
margin-top: @header-height;
padding: 20rem;
border-radius: 8rem;
width: 100%;
background: white;
box-sizing: border-box;
display: flex;
align-items: flex-end;
justify-content: space-between;
overflow: auto;
}
.nav-item {
@width: 35rem;
display: flex;
align-items: center;
flex-direction: column;
flex-shrink: 0;
width: 17vw;
img {
width: @width;
height: @width;
margin-bottom: 5rem;
}
}
}
}
.sub-type-notice {
position: fixed;
background: rgba(black, .4);
top: 100rem;
left: 50%;
transform: translateX(-50%);
padding: 3rem 12rem;
border-radius: 10rem;
z-index: 3;
font-size: 12rem;
color: white;
}
#slide0-infinite {
z-index: 1;
margin-top: 0;
transition: height, margin-top .3s;
}
}
} }
</style> </style>

34
src/pages/home/slide/Slide1.vue

@ -44,8 +44,8 @@
v-if="state.subType===-1 && !state.subTypeVisible" v-if="state.subType===-1 && !state.subTypeVisible"
@click="showSubType">附近吃喝玩乐 @click="showSubType">附近吃喝玩乐
</div> </div>
<Loading v-if="state.loading && state.list.length === 0"/>
<SlideList <SlideList
:active="props.active"
:style="{background: 'black',marginTop:state.subTypeVisible?state.subTypeHeight:0}" :style="{background: 'black',marginTop:state.subTypeVisible?state.subTypeHeight:0}"
:api="api.videos.recommended" :api="api.videos.recommended"
@touchstart="pageClick" @touchstart="pageClick"
@ -94,31 +94,10 @@ const p = {
} }
} }
watch(
() => props.active,
(newVal, oldVal) => {
console.log('newVal', newVal, 'oldVal', oldVal)
if (newVal === false) {
bus.emit(EVENT_KEY.SINGLE_CLICK_BROADCAST, {
baseIndex: 0,
navIndex: 0,
itemIndex: state.index,
type: EVENT_KEY.ITEM_STOP
})
} else {
bus.emit(EVENT_KEY.SINGLE_CLICK_BROADCAST, {
baseIndex: 0,
navIndex: 0,
itemIndex: state.index,
type: EVENT_KEY.ITEM_PLAY
})
}
})
const render = useSlideListItemRender({...props.cbs, ...p}) const render = useSlideListItemRender({...props.cbs, ...p})
const subTypeRef = ref(null) const subTypeRef = ref(null)
const listRef = ref(null) const listRef = ref(null)
const state = reactive({ const state = reactive({
loading: false,
index: 0, index: 0,
subType: -1, subType: -1,
subTypeVisible: false, subTypeVisible: false,
@ -146,17 +125,6 @@ function pageClick(e) {
} }
} }
function dislike() {
listRef.value.dislike(state.list[1])
state.list[state.index] = state.list[1]
Utils.$notice('操作成功,将减少此类视频的推荐')
}
function end() {
// this.$notice('')
}
onMounted(() => { onMounted(() => {
// getData() // getData()
}) })

72
src/pages/home/slide/SlideList.vue

@ -1,16 +1,15 @@
<template> <template>
<SlideVerticalInfinite <SlideVerticalInfinite
ref="listRef" ref="listRef"
v-love="htmlId" v-love="state.uniqueId"
:id="state.uniqueId"
:uniqueId="state.uniqueId"
name="main" name="main"
:id="htmlId" :active="props.active"
:loading="loading"
v-model:index="state.index" v-model:index="state.index"
:render="render" :render="render"
:list="state.list" :list="state.list"
:position="{
baseIndex:0,
navIndex:0,
}"
@loadMore="loadMore" @loadMore="loadMore"
@refresh="() => getData(true)" @refresh="() => getData(true)"
/> />
@ -18,11 +17,13 @@
<script setup lang="jsx"> <script setup lang="jsx">
import SlideVerticalInfinite from '@/components/slide/SlideVerticalInfinite.vue' import SlideVerticalInfinite from '@/components/slide/SlideVerticalInfinite.vue'
import {onMounted, onUnmounted, reactive, ref, watch} from "vue"; import {computed, onMounted, onUnmounted, reactive, ref, watch} from "vue";
import bus, {EVENT_KEY} from "@/utils/bus"; import bus, {EVENT_KEY} from "@/utils/bus";
import Utils from "@/utils"; import Utils from "@/utils";
import {useSlideListItemRender} from "@/utils/hooks/useSlideListItemRender"; import {useSlideListItemRender} from "@/utils/hooks/useSlideListItemRender";
import Loading from "@/components/Loading.vue"; import Loading from "@/components/Loading.vue";
import {useStore} from "vuex";
import {uniqueId} from "lodash";
const props = defineProps({ const props = defineProps({
cbs: { cbs: {
@ -39,10 +40,6 @@ const props = defineProps({
type: Function, type: Function,
default: void 0 default: void 0
}, },
htmlId: {
type: String,
default: 'guid'
}
}) })
const emit = defineEmits([ const emit = defineEmits([
'update:item', 'update:item',
@ -52,6 +49,9 @@ const emit = defineEmits([
'goMusic', 'goMusic',
]) ])
const store = useStore()
const loading = computed(() => store.state.loading)
function stop(e) { function stop(e) {
e.stopPropagation() e.stopPropagation()
} }
@ -62,31 +62,9 @@ const p = {
} }
} }
watch(
() => props.active,
(newVal, oldVal) => {
console.log('newVal', newVal, 'oldVal', oldVal)
if (newVal === false) {
bus.emit(EVENT_KEY.SINGLE_CLICK_BROADCAST, {
baseIndex: 0,
navIndex: 0,
itemIndex: state.index,
type: EVENT_KEY.ITEM_STOP
})
} else {
bus.emit(EVENT_KEY.SINGLE_CLICK_BROADCAST, {
baseIndex: 0,
navIndex: 0,
itemIndex: state.index,
type: EVENT_KEY.ITEM_PLAY
})
}
})
const render = useSlideListItemRender({...props.cbs, ...p}) const render = useSlideListItemRender({...props.cbs, ...p})
const subTypeRef = ref(null)
const listRef = ref(null) const listRef = ref(null)
const state = reactive({ const state = reactive({
loading: false,
index: 0, index: 0,
list: [ list: [
// { // {
@ -94,24 +72,25 @@ const state = reactive({
// src: `http://douyin.ttentau.top/0.mp4?vframe/jpg/offset/0/w/${document.body.clientWidth}` // src: `http://douyin.ttentau.top/0.mp4?vframe/jpg/offset/0/w/${document.body.clientWidth}`
// }, // },
], ],
uniqueId: uniqueId('uniqueId_'),
totalSize: 0, totalSize: 0,
pageSize: 10, pageSize: 10,
pageNo: 0, pageNo: 0,
}) })
function loadMore() { function loadMore() {
if (!state.loading) { if (!loading.value) {
state.pageNo++ state.pageNo++
getData() getData()
} }
} }
async function getData(refresh = false) { async function getData(refresh = false) {
if (state.loading) return if (loading.value) return
state.loading = true store.commit('setLoading', true)
let res = await props.api({pageNo: refresh ? 0 : state.pageNo, pageSize: state.pageSize}) let res = await props.api({pageNo: refresh ? 0 : state.pageNo, pageSize: state.pageSize})
console.log('getSlide0Data-', 'refresh', refresh, res) console.log('getSlide0Data-', 'refresh', refresh, res)
state.loading = false store.commit('setLoading', false)
if (res.code === 200) { if (res.code === 200) {
state.totalSize = res.data.total state.totalSize = res.data.total
if (refresh) { if (refresh) {
@ -133,22 +112,29 @@ function end() {
// this.$notice('') // this.$notice('')
} }
function click(htmlId) { function click(uniqueId) {
if (htmlId !== props.htmlId) return if (uniqueId !== state.uniqueId) return
bus.emit(EVENT_KEY.SINGLE_CLICK_BROADCAST, { bus.emit(EVENT_KEY.SINGLE_CLICK_BROADCAST, {
baseIndex: 0, uniqueId,
navIndex: 0, index: state.index,
itemIndex: state.index,
type: EVENT_KEY.ITEM_TOGGLE type: EVENT_KEY.ITEM_TOGGLE
}) })
} }
function updateItem({position, item}) {
console.log('po', position)
if (position.uniqueId === state.uniqueId) {
state.list[position.index] = item
}
}
onMounted(() => { onMounted(() => {
// getData()
getData() getData()
bus.on(EVENT_KEY.SINGLE_CLICK, click) bus.on(EVENT_KEY.SINGLE_CLICK, click)
bus.on(EVENT_KEY.UPDATE_ITEM, updateItem)
}) })
onUnmounted(() => { onUnmounted(() => {
bus.off(EVENT_KEY.SINGLE_CLICK, click) bus.off(EVENT_KEY.SINGLE_CLICK, click)
bus.on(EVENT_KEY.UPDATE_ITEM, updateItem)
}) })
</script> </script>

4
src/store/index.js

@ -45,8 +45,12 @@ const store = Vuex.createStore({
excludeRoutes: [], excludeRoutes: [],
judgeValue: 20, judgeValue: 20,
homeRefresh: 60, homeRefresh: 60,
loading: false,
}, },
mutations: { mutations: {
setLoading(store, val) {
store.loading = val
},
setUserinfo(store, val) { setUserinfo(store, val) {
store.userinfo = val store.userinfo = val
}, },

1
src/utils/bus.js

@ -60,4 +60,5 @@ export const EVENT_KEY = {
NAV: 'NAV', NAV: 'NAV',
GO_USERINFO: 'GO_USERINFO', GO_USERINFO: 'GO_USERINFO',
SHOW_SHARE: 'SHOW_SHARE', SHOW_SHARE: 'SHOW_SHARE',
UPDATE_ITEM: 'UPDATE_ITEM',
} }

5
src/utils/hooks/useSlideListItemRender.jsx

@ -3,7 +3,7 @@ import SlideUser from "@/components/slide/SlideUser.vue";
import BVideo from "@/components/slide/BVideo.vue"; import BVideo from "@/components/slide/BVideo.vue";
export function useSlideListItemRender(props) { export function useSlideListItemRender(props) {
return function render(item, itemIndex, play, position) { return function render(item, index, play, uniqueId) {
// console.log('item', item) // console.log('item', item)
let node let node
if (item.type === 'img') { if (item.type === 'img') {
@ -23,7 +23,8 @@ export function useSlideListItemRender(props) {
node = <BVideo node = <BVideo
isPlay={play} isPlay={play}
item={item} item={item}
position={{...position, itemIndex}} index={index}
position={{uniqueId, index}}
{...props} {...props}
/> />
} }

3
src/utils/index.jsx

@ -8,6 +8,7 @@ import NoticeDialog from "../components/dialog/NoticeDialog";
import dayjs from 'dayjs' import dayjs from 'dayjs'
import bus from "./bus"; import bus from "./bus";
import {cloneDeep} from "lodash"; import {cloneDeep} from "lodash";
import {EVENT_KEY} from "./bus";
export default { export default {
require2(url) { require2(url) {
@ -382,7 +383,7 @@ export default {
let old = cloneDeep(props.item) let old = cloneDeep(props.item)
old[key] = val old[key] = val
emit('update:item', old) emit('update:item', old)
bus.emit('update:item', {position: props.position, item: old}) bus.emit(EVENT_KEY.UPDATE_ITEM, {position: props.position, item: old})
}, },
copy(val) { copy(val) {
const input = document.createElement('input'); const input = document.createElement('input');

Loading…
Cancel
Save