6 changed files with 189 additions and 389 deletions
@ -1,29 +0,0 @@
@@ -1,29 +0,0 @@
|
||||
<template> |
||||
<div class="big">{{ props.item.desc }}</div> |
||||
</template> |
||||
|
||||
<script setup> |
||||
import {onMounted, onUnmounted} from "vue"; |
||||
|
||||
const props = defineProps({ |
||||
item: { |
||||
type: Object, |
||||
default: () => { |
||||
return {} |
||||
} |
||||
}, |
||||
}) |
||||
|
||||
onMounted(()=>{ |
||||
console.log('onMounted',props.item.desc) |
||||
}) |
||||
|
||||
onUnmounted(()=>{ |
||||
console.log('onUnmounted',props.item.desc) |
||||
}) |
||||
|
||||
</script> |
||||
|
||||
<style scoped> |
||||
|
||||
</style> |
@ -1,168 +0,0 @@
@@ -1,168 +0,0 @@
|
||||
<script setup lang="jsx"> |
||||
import {computed, onMounted, reactive, ref, watch} from "vue"; |
||||
import GM from '../../utils' |
||||
import { |
||||
getSlideDistance, |
||||
slideInit, |
||||
slideReset, |
||||
slideTouchEnd, |
||||
slideTouchMove, |
||||
slideTouchStart |
||||
} from "../slideHooks/common"; |
||||
import {SlideType} from "../../utils/const_var"; |
||||
import SlideItem from "@/pages/slideHooks/SlideItem.vue"; |
||||
import TestItem from "@/pages/slideComponent/TestItem.vue"; |
||||
|
||||
const props = defineProps({ |
||||
index: { |
||||
type: Number, |
||||
default: () => { |
||||
return 0 |
||||
} |
||||
}, |
||||
position: { |
||||
type: Object, |
||||
default: () => { |
||||
return {} |
||||
} |
||||
}, |
||||
render: { |
||||
type: Function, |
||||
default: () => { |
||||
return null |
||||
} |
||||
}, |
||||
list: { |
||||
type: Array, |
||||
default: () => { |
||||
return [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] |
||||
} |
||||
}, |
||||
virtualTotal: { |
||||
type: Number, |
||||
default: () => 5 |
||||
}, |
||||
name: { |
||||
type: String, |
||||
default: () => '' |
||||
}, |
||||
}) |
||||
const emit = defineEmits(['update:index', 'loadMore']) |
||||
|
||||
const judgeValue = 20 |
||||
const wrapperEl = ref(null) |
||||
const state = reactive({ |
||||
name: 'SlideVertical', |
||||
localIndex: props.index, |
||||
needCheck: true, |
||||
next: false, |
||||
start: {x: 0, y: 0, time: 0}, |
||||
move: {x: 0, y: 0}, |
||||
wrapper: {width: 0, height: 0, childrenLength: 0}, |
||||
cs: [], |
||||
styleTop: 0, |
||||
components: { |
||||
one: <SlideItem class=" gray"> |
||||
<div class="big">热点0</div> |
||||
</SlideItem>, |
||||
two: <SlideItem class=" gray"> |
||||
<div class="big">热点1</div> |
||||
</SlideItem>, |
||||
three: <SlideItem class=" gray"> |
||||
<div class="big">热点2</div> |
||||
</SlideItem>, |
||||
four: <SlideItem class=" gray"> |
||||
<div class="big">热点3</div> |
||||
</SlideItem>, |
||||
five: <SlideItem class=" gray"> |
||||
<div class="big">热点4</div> |
||||
</SlideItem>, |
||||
} |
||||
}) |
||||
|
||||
function r(item) { |
||||
let node = props.render(item, state.localIndex, true, props.position) |
||||
return <SlideItem class="slideItemClassName"> |
||||
{node} |
||||
</SlideItem> |
||||
} |
||||
|
||||
watch( |
||||
() => props.index, |
||||
(newVal) => { |
||||
if (state.localIndex !== newVal) { |
||||
state.localIndex = newVal |
||||
GM.$setCss(wrapperEl.value, 'transition-duration', `300ms`) |
||||
GM.$setCss(wrapperEl.value, 'transform', `translate3d(0,${getSlideDistance(state, SlideType.VERTICAL)}px, 0)`) |
||||
} |
||||
} |
||||
) |
||||
|
||||
onMounted(() => { |
||||
slideInit(wrapperEl.value, state, SlideType.VERTICAL) |
||||
state.cs = props.list.slice(0, props.virtualTotal).map((v, i) => r(v)) |
||||
}) |
||||
|
||||
function touchStart(e) { |
||||
slideTouchStart(e, wrapperEl.value, state) |
||||
} |
||||
|
||||
function touchMove(e) { |
||||
slideTouchMove(e, wrapperEl.value, state, judgeValue, canNext, null, SlideType.VERTICAL) |
||||
} |
||||
|
||||
function touchEnd(e) { |
||||
slideTouchEnd(e, state, canNext, (isNext) => { |
||||
console.log('state.localIndex', state.localIndex) |
||||
let half = (props.virtualTotal + 1) / 2 |
||||
if (props.list.length > props.virtualTotal) { |
||||
if (isNext) { |
||||
if (state.localIndex > props.list.length - props.virtualTotal && state.localIndex > half) { |
||||
console.log('loadMore') |
||||
emit('loadMore') |
||||
} |
||||
if (state.localIndex >= half && state.localIndex <= props.list.length - half) { |
||||
console.log('push') |
||||
// state.cs = props.list.slice(state.localIndex - 2, state.localIndex + 3).map((v, i) => r(v)) |
||||
state.cs.shift() |
||||
state.cs.push(r(props.list[state.localIndex + (half - 1)])) |
||||
state.styleTop = (state.localIndex - 2) * state.wrapper.height |
||||
} |
||||
} else { |
||||
//这里先加个1,保持if表达式一致 |
||||
let judgeIndex = state.localIndex + 1 |
||||
if (judgeIndex >= half && judgeIndex <= props.list.length - half) { |
||||
console.log('unshift') |
||||
state.cs.unshift(r(props.list[state.localIndex - (half - 1)])) |
||||
state.cs.pop() |
||||
state.styleTop = (state.localIndex - 2) * state.wrapper.height |
||||
} |
||||
} |
||||
} |
||||
if (state.localIndex < half) { |
||||
console.log('--') |
||||
state.styleTop = 0 |
||||
} |
||||
|
||||
}, null, SlideType.VERTICAL) |
||||
slideReset(wrapperEl.value, state, SlideType.VERTICAL, emit) |
||||
} |
||||
|
||||
|
||||
function canNext(isNext) { |
||||
return !((state.localIndex === 0 && !isNext) || (state.localIndex === props.list.length - 1 && isNext)); |
||||
} |
||||
</script> |
||||
|
||||
<template> |
||||
<div class="slide v"> |
||||
<div class="slide-list flex-direction-column" |
||||
ref="wrapperEl" |
||||
@touchstart="touchStart" |
||||
@touchmove="touchMove" |
||||
@touchend="touchEnd" |
||||
> |
||||
<component :style='{top: state.styleTop + "px"}' :is="v" v-for="(v,i) in state.cs" :key="v.id"/> |
||||
</div> |
||||
</div> |
||||
</template> |
@ -1,180 +0,0 @@
@@ -1,180 +0,0 @@
|
||||
<template> |
||||
<div class="test-slide-wrapper" id="slideHook" v-love="'slideHook'"> |
||||
<V |
||||
name="main" |
||||
v-model:index="state.itemIndex" |
||||
:render="render" |
||||
@loadMore="loadMore" |
||||
:list="state.recommendVideos" |
||||
:position="{ |
||||
baseIndex:0, |
||||
navIndex:5, |
||||
}" |
||||
> |
||||
</V> |
||||
</div> |
||||
</template> |
||||
|
||||
<script setup lang="jsx"> |
||||
import V from './V.vue' |
||||
import SlideImgs from "../../components/slide/SlideAlbum"; |
||||
import BVideo from "../../components/slide/BVideo"; |
||||
import Comment from "../../components/Comment"; |
||||
|
||||
import resource from "../../assets/data/resource.js"; |
||||
import {onMounted, onUnmounted, provide, reactive} from "vue"; |
||||
import bus, {EVENT_KEY} from "../../utils/bus"; |
||||
import {useNav} from "../../utils/hooks/useNav"; |
||||
|
||||
const nav = useNav() |
||||
|
||||
const videos = resource.videos.slice(0, 7).map((v, i) => { |
||||
v.type = 'recommend-video' |
||||
// v.desc = i + v.desc |
||||
return v |
||||
}) |
||||
|
||||
const state = reactive({ |
||||
baseIndex: 0, |
||||
navIndex: 4, |
||||
itemIndex: 0, |
||||
recommendVideos: [ |
||||
// { |
||||
// type: 'img', |
||||
// src: `http://douyin.ttentau.top/0.mp4?vframe/jpg/offset/0/w/${document.body.clientWidth}` |
||||
// }, |
||||
// { |
||||
// type: 'imgs', |
||||
// src: `http://douyin.ttentau.top/0.mp4?vframe/jpg/offset/0/w/${document.body.clientWidth}` |
||||
// }, |
||||
...videos |
||||
], |
||||
|
||||
isCommenting: false, |
||||
isSharing: false, |
||||
canMove: true, |
||||
loading: false, |
||||
isUp: false, |
||||
|
||||
shareType: -1, |
||||
|
||||
showPlayFeedback: false, |
||||
showShareDuoshan: false, |
||||
showShareDialog: false, |
||||
showShare2WeChatZone: false, |
||||
showDouyinCode: false, |
||||
showFollowSetting: false, |
||||
showFollowSetting2: false, |
||||
showBlockDialog: false, |
||||
showChangeNote: false, |
||||
shareToFriend: false, |
||||
|
||||
commentVisible: false, |
||||
}) |
||||
provide('commentVisible', () => state.commentVisible) |
||||
|
||||
onMounted(() => { |
||||
bus.on('singleClick', () => { |
||||
let id = '' |
||||
// if (state.navIndex === 5) { |
||||
if (true) { |
||||
id = state.recommendVideos[state.itemIndex].id |
||||
} |
||||
bus.emit('singleClickBroadcast', id) |
||||
}) |
||||
bus.on('update:item', val => { |
||||
const {baseIndex, navIndex, itemIndex} = val.position |
||||
if (navIndex === 5) { |
||||
state.recommendVideos[itemIndex] = val.item |
||||
} |
||||
}) |
||||
bus.on('nav', path => nav(path)) |
||||
}) |
||||
onUnmounted(() => { |
||||
bus.offAll() |
||||
}) |
||||
|
||||
function loadMore() { |
||||
return |
||||
state.recommendVideos = state.recommendVideos.concat(resource.videos.slice(0, 10).map((v, i) => { |
||||
v.type = 'recommend-video' |
||||
return v |
||||
})) |
||||
} |
||||
|
||||
function test() { |
||||
state.commentVisible = true |
||||
bus.emit(EVENT_KEY.TOGGLE_COMMENT,) |
||||
} |
||||
|
||||
function render(item, itemIndex, play, position) { |
||||
let node |
||||
if (item.type === 'img') { |
||||
node = <img src={item.src} style="height:100%;"/> |
||||
} |
||||
if (item.type === 'imgs') { |
||||
node = <SlideImgs/> |
||||
} |
||||
if (item.type === 'recommend-video') { |
||||
node = <BVideo |
||||
isPlay={false} |
||||
item={item} |
||||
position={{...position, itemIndex}} |
||||
onShowComments={test} |
||||
onShowShare={e => state.isSharing = true} |
||||
onGoUserInfo={e => state.baseIndex = 1} |
||||
/> |
||||
} |
||||
return node |
||||
|
||||
return <SlideItem class="slideItemClassName"> |
||||
{node} |
||||
</SlideItem> |
||||
} |
||||
|
||||
</script> |
||||
|
||||
<style scoped lang="less"> |
||||
@import "@/assets/less/index"; |
||||
|
||||
.test-slide-wrapper { |
||||
font-size: 24rem; |
||||
width: 100%; |
||||
height: 100%; |
||||
color: white; |
||||
|
||||
span { |
||||
color: white; |
||||
font-size: 24rem; |
||||
} |
||||
|
||||
.big { |
||||
font-weight: bold; |
||||
font-size: 100rem; |
||||
} |
||||
} |
||||
|
||||
.h { |
||||
width: 90vw; |
||||
height: 80vh; |
||||
//height: calc(100vh - @footer-height); |
||||
overflow: hidden; |
||||
|
||||
.red { |
||||
background-color: red; |
||||
} |
||||
|
||||
.yellow { |
||||
background-color: yellow; |
||||
} |
||||
|
||||
.blue { |
||||
background-color: blue; |
||||
} |
||||
|
||||
.gray { |
||||
background-color: gray; |
||||
} |
||||
} |
||||
|
||||
</style> |
@ -0,0 +1,186 @@
@@ -0,0 +1,186 @@
|
||||
<!--<script setup lang="jsx">--> |
||||
<!--import {computed, onMounted, reactive, ref, watch} from "vue";--> |
||||
<!--import GM from '../../utils'--> |
||||
<!--import {--> |
||||
<!-- getSlideDistance,--> |
||||
<!-- slideInit,--> |
||||
<!-- slideReset,--> |
||||
<!-- slideTouchEnd,--> |
||||
<!-- slideTouchMove,--> |
||||
<!-- slideTouchStart--> |
||||
<!--} from "./common";--> |
||||
<!--import {SlideType} from "../../utils/const_var";--> |
||||
<!--import SlideItem from "@/pages/slideHooks/SlideItem.vue";--> |
||||
<!--import TestItem from "@/pages/slideComponent/TestItem.vue";--> |
||||
|
||||
<!--const props = defineProps({--> |
||||
<!-- index: {--> |
||||
<!-- type: Number,--> |
||||
<!-- default: () => {--> |
||||
<!-- return 0--> |
||||
<!-- }--> |
||||
<!-- },--> |
||||
<!-- position: {--> |
||||
<!-- type: Object,--> |
||||
<!-- default: () => {--> |
||||
<!-- return {}--> |
||||
<!-- }--> |
||||
<!-- },--> |
||||
<!-- render: {--> |
||||
<!-- type: Function,--> |
||||
<!-- default: () => {--> |
||||
<!-- return null--> |
||||
<!-- }--> |
||||
<!-- },--> |
||||
<!-- list: {--> |
||||
<!-- type: Array,--> |
||||
<!-- default: () => {--> |
||||
<!-- return [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]--> |
||||
<!-- }--> |
||||
<!-- },--> |
||||
<!-- virtualTotal: {--> |
||||
<!-- type: Number,--> |
||||
<!-- default: () => 5--> |
||||
<!-- },--> |
||||
<!-- name: {--> |
||||
<!-- type: String,--> |
||||
<!-- default: () => ''--> |
||||
<!-- },--> |
||||
<!--})--> |
||||
<!--const emit = defineEmits(['update:index', 'loadMore'])--> |
||||
|
||||
<!--const judgeValue = 20--> |
||||
<!--const wrapperEl = ref(null)--> |
||||
<!--const state = reactive({--> |
||||
<!-- name: 'SlideVertical',--> |
||||
<!-- localIndex: props.index,--> |
||||
<!-- needCheck: true,--> |
||||
<!-- next: false,--> |
||||
<!-- start: {x: 0, y: 0, time: 0},--> |
||||
<!-- move: {x: 0, y: 0},--> |
||||
<!-- wrapper: {width: 0, height: 0, childrenLength: 0},--> |
||||
<!-- cs: [],--> |
||||
<!-- styleTop: 0,--> |
||||
<!-- components: {--> |
||||
<!-- one: <SlideItem class=" gray">--> |
||||
<!-- <div class="big">热点0</div>--> |
||||
<!-- </SlideItem>,--> |
||||
<!-- two: <SlideItem class=" gray">--> |
||||
<!-- <div class="big">热点1</div>--> |
||||
<!-- </SlideItem>,--> |
||||
<!-- three: <SlideItem class=" gray">--> |
||||
<!-- <div class="big">热点2</div>--> |
||||
<!-- </SlideItem>,--> |
||||
<!-- four: <SlideItem class=" gray">--> |
||||
<!-- <div class="big">热点3</div>--> |
||||
<!-- </SlideItem>,--> |
||||
<!-- five: <SlideItem class=" gray">--> |
||||
<!-- <div class="big">热点4</div>--> |
||||
<!-- </SlideItem>,--> |
||||
<!-- }--> |
||||
<!--})--> |
||||
|
||||
<!--function r(item, index = -1) {--> |
||||
<!-- let node = props.render(item, state.localIndex, index === 0, props.position)--> |
||||
<!-- return <SlideItem class="slideItemClassName">--> |
||||
<!-- {node}--> |
||||
<!-- </SlideItem>--> |
||||
<!--}--> |
||||
|
||||
<!--watch(--> |
||||
<!-- () => props.index,--> |
||||
<!-- (newVal) => {--> |
||||
<!-- if (state.localIndex !== newVal) {--> |
||||
<!-- state.localIndex = newVal--> |
||||
<!-- GM.$setCss(wrapperEl.value, 'transition-duration', `300ms`)--> |
||||
<!-- GM.$setCss(wrapperEl.value, 'transform', `translate3d(0,${getSlideDistance(state, SlideType.VERTICAL)}px, 0)`)--> |
||||
<!-- }--> |
||||
<!-- }--> |
||||
<!--)--> |
||||
|
||||
<!--watch(--> |
||||
<!-- () => props.list,--> |
||||
<!-- (newVal) => {--> |
||||
<!-- console.log('list', newVal)--> |
||||
<!-- let half = (props.virtualTotal + 1) / 2--> |
||||
<!-- if (state.localIndex >= half) {--> |
||||
<!-- state.cs = newVal.slice(state.localIndex - 2, state.localIndex + 3).map((v, i) => r(v))--> |
||||
<!-- state.styleTop = (state.localIndex - 2) * state.wrapper.height--> |
||||
<!-- }--> |
||||
<!-- }--> |
||||
<!--)--> |
||||
|
||||
<!--onMounted(() => {--> |
||||
<!-- slideInit(wrapperEl.value, state, SlideType.VERTICAL)--> |
||||
<!-- state.cs = props.list.slice(0, props.virtualTotal).map((v, i) => r(v, i))--> |
||||
<!--})--> |
||||
|
||||
<!--function touchStart(e) {--> |
||||
<!-- slideTouchStart(e, wrapperEl.value, state)--> |
||||
<!--}--> |
||||
|
||||
<!--function touchMove(e) {--> |
||||
<!-- slideTouchMove(e, wrapperEl.value, state, judgeValue, canNext, null, SlideType.VERTICAL)--> |
||||
<!--}--> |
||||
|
||||
<!--function touchEnd(e) {--> |
||||
<!-- slideTouchEnd(e, state, canNext, (isNext) => {--> |
||||
<!-- console.log('state.localIndex', state.localIndex)--> |
||||
<!-- let half = (props.virtualTotal + 1) / 2--> |
||||
<!-- if (props.list.length > props.virtualTotal) {--> |
||||
<!-- if (isNext) {--> |
||||
<!-- if (state.localIndex > props.list.length - props.virtualTotal && state.localIndex > half) {--> |
||||
<!-- console.log('loadMore')--> |
||||
<!-- emit('loadMore')--> |
||||
<!-- }--> |
||||
<!-- if (state.localIndex >= half && state.localIndex <= props.list.length - half) {--> |
||||
<!-- console.log('push')--> |
||||
<!-- // state.cs = props.list.slice(state.localIndex - 2, state.localIndex + 3).map((v, i) => r(v))--> |
||||
<!-- state.cs.shift()--> |
||||
<!-- state.cs.push(r(props.list[state.localIndex + (half - 1)]))--> |
||||
<!-- state.styleTop = (state.localIndex - 2) * state.wrapper.height--> |
||||
<!-- }--> |
||||
<!-- } else {--> |
||||
<!-- //这里先加个1,保持if表达式一致--> |
||||
<!-- let judgeIndex = state.localIndex + 1--> |
||||
<!-- if (judgeIndex >= half && judgeIndex <= props.list.length - half) {--> |
||||
<!-- console.log('unshift')--> |
||||
<!-- state.cs.unshift(r(props.list[state.localIndex - (half - 1)]))--> |
||||
<!-- state.cs.pop()--> |
||||
<!-- state.styleTop = (state.localIndex - 2) * state.wrapper.height--> |
||||
<!-- }--> |
||||
<!-- }--> |
||||
<!-- }--> |
||||
<!-- if (state.localIndex < half) {--> |
||||
<!-- console.log('--')--> |
||||
<!-- state.styleTop = 0--> |
||||
<!-- }--> |
||||
|
||||
<!-- }, null, SlideType.VERTICAL)--> |
||||
<!-- slideReset(wrapperEl.value, state, SlideType.VERTICAL, emit)--> |
||||
<!--}--> |
||||
|
||||
|
||||
<!--function canNext(isNext) {--> |
||||
<!-- return !((state.localIndex === 0 && !isNext) || (state.localIndex === props.list.length - 1 && isNext));--> |
||||
<!--}--> |
||||
<!--</script>--> |
||||
|
||||
<!--<template>--> |
||||
<!-- <div class="slide v">--> |
||||
<!-- <div class="slide-list flex-direction-column"--> |
||||
<!-- ref="wrapperEl"--> |
||||
<!-- @touchstart="touchStart"--> |
||||
<!-- @touchmove="touchMove"--> |
||||
<!-- @touchend="touchEnd"--> |
||||
<!-- >--> |
||||
<!-- <component :style='{top: state.styleTop + "px"}' :is="v" v-for="(v,i) in state.cs" :key="v.id"/>--> |
||||
<!-- </div>--> |
||||
<!-- </div>--> |
||||
<!--</template>--> |
||||
|
||||
<!-- |
||||
测试用<component :is的方法是否可行。结论,可行。但是不实用。当list数据更新时,<component的表现形式为,不销毁组件,只更新props。 |
||||
|
||||
感觉会导致已经加载到的video,重新加载。但未经测试 |
||||
--> |
Loading…
Reference in new issue