比较完美完成返回滚动实现
This commit is contained in:
parent
e16176d6ea
commit
f0e5ea4363
22
src/App.vue
22
src/App.vue
@ -22,6 +22,7 @@ import {
|
|||||||
NMessageProvider,
|
NMessageProvider,
|
||||||
} from "naive-ui";
|
} from "naive-ui";
|
||||||
import router from "./router";
|
import router from "./router";
|
||||||
|
|
||||||
// import { CloudCircleSharp } from "@vicons/ionicons5";
|
// import { CloudCircleSharp } from "@vicons/ionicons5";
|
||||||
|
|
||||||
const store = useStore();
|
const store = useStore();
|
||||||
@ -44,6 +45,16 @@ store.commit("loadSettings");
|
|||||||
store.state.settings.playing = false; //默认停止播放
|
store.state.settings.playing = false; //默认停止播放
|
||||||
store.commit("loadCaches");
|
store.commit("loadCaches");
|
||||||
|
|
||||||
|
// onMounted(() => {
|
||||||
|
// window.addEventListener('popstate', popstate, false);
|
||||||
|
// })
|
||||||
|
// const popstate = (event)=>{
|
||||||
|
// console.log('popstate--',event);
|
||||||
|
// }
|
||||||
|
// onUnmounted(() => {
|
||||||
|
// window.removeEventListener('popstate',pop)
|
||||||
|
// })
|
||||||
|
|
||||||
// router.replace('/discover/recommend')
|
// router.replace('/discover/recommend')
|
||||||
|
|
||||||
const showPlaying = ref(false); //是否显示播放列表
|
const showPlaying = ref(false); //是否显示播放列表
|
||||||
@ -60,14 +71,15 @@ watch(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
//处理route消息
|
//处理route消息
|
||||||
const routeToken = pubsub.subscribe("router", (msg, data) => {
|
const routeToken = pubsub.subscribe("router", (msg, data) => {
|
||||||
switch (msg) {
|
switch (msg) {
|
||||||
case "router.beforeEach":
|
case "router.beforeEach":
|
||||||
case "router.afterEach":
|
case "router.afterEach":
|
||||||
store.commit("saveSettings", {
|
// store.commit("saveSettings", {
|
||||||
currentRoute: data.to.fullPath,
|
// currentRoute: data.to.fullPath,
|
||||||
});
|
// });
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -140,9 +152,9 @@ const hideWins = (e) => {
|
|||||||
</div>
|
</div>
|
||||||
<div id="main">
|
<div id="main">
|
||||||
<router-view v-slot="{ Component, route }">
|
<router-view v-slot="{ Component, route }">
|
||||||
<keep-alive exclude="FM,Friends">
|
<!-- <keep-alive exclude="FM,Friends"> -->
|
||||||
<component :is="Component" />
|
<component :is="Component" />
|
||||||
</keep-alive>
|
<!-- </keep-alive> -->
|
||||||
</router-view>
|
</router-view>
|
||||||
<!-- <router-view v-slot="{ Component, route }">
|
<!-- <router-view v-slot="{ Component, route }">
|
||||||
<keep-alive v-if="route.meta.keepAlive">
|
<keep-alive v-if="route.meta.keepAlive">
|
||||||
|
16
src/components/Albumlist.vue
Normal file
16
src/components/Albumlist.vue
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<script setup>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
</style>
|
55
src/components/Artistlist.vue
Normal file
55
src/components/Artistlist.vue
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
<script setup>
|
||||||
|
import { NAvatar } from 'naive-ui';
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
artists: Array,
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<table class="arList">
|
||||||
|
<tr v-for="(ar) in artists" :key="ar.idx" @click="$router.push('/singer/'+ar.id)">
|
||||||
|
<td class="img" >
|
||||||
|
<NAvatar :size="60" :src="ar.picUrl" object-fit="cover"></NAvatar>
|
||||||
|
<!-- <img :src="ar.picUrl" alt="歌手头像" width="100"> -->
|
||||||
|
</td>
|
||||||
|
<td class="content">
|
||||||
|
<span class="name">{{ar.name}}</span>
|
||||||
|
<span class="alias">
|
||||||
|
{{ar.alias.length > 0 ? '(' + ar.alias.join(' ') + ')' : ''}}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td class="others"></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
@import "@/assets/css/common.less";
|
||||||
|
.arList{
|
||||||
|
margin-top: 6px;
|
||||||
|
border-spacing: 0;
|
||||||
|
|
||||||
|
tr{
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
.content{
|
||||||
|
.name{
|
||||||
|
padding: 6px;
|
||||||
|
}
|
||||||
|
.alias{
|
||||||
|
font-size: 14px;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
</style>
|
@ -1,31 +1,14 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import {
|
import {
|
||||||
ref,
|
ref,
|
||||||
reactive,
|
|
||||||
h,
|
|
||||||
watch,
|
|
||||||
toRaw,
|
|
||||||
onMounted,
|
|
||||||
onUnmounted,
|
|
||||||
nextTick,
|
|
||||||
} from "vue";
|
} from "vue";
|
||||||
import { RouterLink, useRoute, useRouter } from "vue-router";
|
import { useRouter } from "vue-router";
|
||||||
import { useStore } from "vuex";
|
import { useStore } from "vuex";
|
||||||
import {
|
import {
|
||||||
NButton,
|
NButton,
|
||||||
NButtonGroup,
|
|
||||||
NSpace,
|
|
||||||
NIcon,
|
NIcon,
|
||||||
NDropdown,
|
NDropdown,
|
||||||
NMenu,
|
NMenu,
|
||||||
NLayout,
|
|
||||||
NLayoutHeader,
|
|
||||||
NLayoutFooter,
|
|
||||||
NLayoutContent,
|
|
||||||
NLayoutSider,
|
|
||||||
NTag,
|
|
||||||
NDataTable,
|
|
||||||
useMessage,
|
|
||||||
} from "naive-ui";
|
} from "naive-ui";
|
||||||
import Play from "@/assets/svgs/Play_.svg";
|
import Play from "@/assets/svgs/Play_.svg";
|
||||||
import Pause from "@/assets/svgs/Pause.svg";
|
import Pause from "@/assets/svgs/Pause.svg";
|
||||||
@ -42,8 +25,24 @@ const router = useRouter();
|
|||||||
dayjs.extend(duration);
|
dayjs.extend(duration);
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
songs: Array,
|
songs: Array, // 歌曲列表
|
||||||
|
ctxMenu: Array, //菜单
|
||||||
|
showHead: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
const emit = defineEmits({
|
||||||
|
itemDbclick: null, // 双击每行
|
||||||
|
ctxMenuSelect: null, // 点击菜单
|
||||||
|
})
|
||||||
|
|
||||||
|
const ctxMenuOptions = ()=>{
|
||||||
|
return (props.ctxMenu ? props.ctxMenu : [])
|
||||||
|
}
|
||||||
|
const onCtxMenuSelect = (key, id) => {
|
||||||
|
props.ctxMenuSelect?.(key, id)
|
||||||
|
}
|
||||||
|
|
||||||
// const s = ref(props.songs)
|
// const s = ref(props.songs)
|
||||||
// console.log(s.value.value);
|
// console.log(s.value.value);
|
||||||
@ -107,7 +106,7 @@ const props = defineProps({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<table class="tbList">
|
<table class="tbList">
|
||||||
<tr class="tr trh">
|
<tr class="tr trh" v-show="showHead">
|
||||||
<td class="icon"></td>
|
<td class="icon"></td>
|
||||||
<td class="name">音乐标题</td>
|
<td class="name">音乐标题</td>
|
||||||
<td class="ar">歌手</td>
|
<td class="ar">歌手</td>
|
||||||
@ -120,7 +119,7 @@ const props = defineProps({
|
|||||||
v-for="p in songs"
|
v-for="p in songs"
|
||||||
:key="p.id"
|
:key="p.id"
|
||||||
draggable="false"
|
draggable="false"
|
||||||
@dblclick="pubsub.publish('zp.play', { id: p.id, im: true })"
|
@dblclick="$emit('itemDbclick', p.id)"
|
||||||
>
|
>
|
||||||
<td class="icon">
|
<td class="icon">
|
||||||
<NButton
|
<NButton
|
||||||
@ -139,10 +138,12 @@ const props = defineProps({
|
|||||||
<span class="ntext">{{ p.name }}</span>
|
<span class="ntext">{{ p.name }}</span>
|
||||||
<span class="nm">
|
<span class="nm">
|
||||||
<n-dropdown
|
<n-dropdown
|
||||||
|
v-if="ctxMenuOptions().length > 0"
|
||||||
placement="right-start"
|
placement="right-start"
|
||||||
@select="handleSelect($event, p.id)"
|
@select="$emit('ctxMenuSelect', $event, p.id)"
|
||||||
trigger="click"
|
trigger="click"
|
||||||
:show-arrow="true"
|
:show-arrow="true"
|
||||||
|
:options="(ctxMenuOptions())"
|
||||||
>
|
>
|
||||||
<NButton
|
<NButton
|
||||||
class="mn"
|
class="mn"
|
||||||
@ -207,7 +208,7 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: #eee;
|
// background-color: #eee;
|
||||||
|
|
||||||
.name .mn {
|
.name .mn {
|
||||||
display: block;
|
display: block;
|
||||||
|
5
src/lib/eventBus.js
Normal file
5
src/lib/eventBus.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import { EventEmitter } from "events";
|
||||||
|
|
||||||
|
const eventBus = new EventEmitter();
|
||||||
|
|
||||||
|
export default eventBus;
|
122
src/lib/useBackSnaps.js
Normal file
122
src/lib/useBackSnaps.js
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
import { onMounted, onActivated, nextTick } from "vue";
|
||||||
|
import { useStore } from "vuex";
|
||||||
|
|
||||||
|
//设置
|
||||||
|
let config = {
|
||||||
|
elName: "mainContent", //#元素名称
|
||||||
|
log: false, //是否显示log
|
||||||
|
};
|
||||||
|
|
||||||
|
const backSnaps = []; //返回快照数组
|
||||||
|
let lashHistoryLength = 0; //上次History的长度
|
||||||
|
let lastHistoryPos = -1; //上次History的位置
|
||||||
|
|
||||||
|
const tsArr = [];
|
||||||
|
|
||||||
|
export const test = () => {
|
||||||
|
tsArr.push("tsArr");
|
||||||
|
console.log(tsArr);
|
||||||
|
};
|
||||||
|
|
||||||
|
export function cfg(cfg){
|
||||||
|
config = {...config, ...cfg}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useBackSnaps() {
|
||||||
|
|
||||||
|
onActivated(() => {
|
||||||
|
restore();
|
||||||
|
});
|
||||||
|
onMounted(() => {
|
||||||
|
restore();
|
||||||
|
});
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
export const saveBackSnaps = () => {
|
||||||
|
// console.log("路由afterEach: 当前页面 ", window.location);
|
||||||
|
// console.log("路由afterEach: ", window.history);
|
||||||
|
// console.log("路由afterEach: ", from.fullPath, " to ", to.fullPath);
|
||||||
|
|
||||||
|
// 判断动作是?
|
||||||
|
const moveOn =
|
||||||
|
lashHistoryLength == 0 ||
|
||||||
|
lastHistoryPos == -1 ||
|
||||||
|
window.history.length != lashHistoryLength ||
|
||||||
|
window.history.state.position - lastHistoryPos > 0;
|
||||||
|
|
||||||
|
//查找元素...
|
||||||
|
const $content = document.querySelector(`#${config.elName}`);
|
||||||
|
// if ($content)
|
||||||
|
// console.log("路由afterEach: ", $content, $content.scrollTop);
|
||||||
|
const idx = window.history.state.position + (moveOn ? -1 : 1);
|
||||||
|
if(window.history.length != lashHistoryLength){ //新路由,更新backSnaps数组长度
|
||||||
|
backSnaps.splice(idx + 1, backSnaps.length - idx)
|
||||||
|
}
|
||||||
|
//保存原来的
|
||||||
|
lashHistoryLength = window.history.length;
|
||||||
|
lastHistoryPos = window.history.state.position;
|
||||||
|
//保存
|
||||||
|
if (idx > -1) {
|
||||||
|
const backSnap = {
|
||||||
|
idx,
|
||||||
|
scrollTop: $content ? $content.scrollTop : 0,
|
||||||
|
};
|
||||||
|
// console.log("路由afterEach: ", backSnap);
|
||||||
|
if (backSnaps.length < idx + 1) backSnaps.length = idx + 1;
|
||||||
|
backSnaps[idx] = backSnaps[idx] ? {...backSnaps[idx], ...backSnap} : backSnap
|
||||||
|
// backSnaps[idx] = backSnap;
|
||||||
|
if (config.log)
|
||||||
|
console.log("useBackSnaps: 保存上个页面", backSnaps);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const saveSnap = (snap)=>{
|
||||||
|
const idx = window.history.state.position;
|
||||||
|
//保存
|
||||||
|
if (idx > -1) {
|
||||||
|
// const backSnap = {
|
||||||
|
// idx,
|
||||||
|
// url: window.location.href,
|
||||||
|
// };
|
||||||
|
// // console.log("路由afterEach: ", backSnap);
|
||||||
|
if (backSnaps.length < idx + 1) backSnaps.length = idx + 1;
|
||||||
|
backSnaps[idx] = backSnaps[idx] ? {...backSnaps[idx], ...{other: snap}} : {other: snap}
|
||||||
|
// backSnaps[idx] = backSnap;
|
||||||
|
if (config.log)
|
||||||
|
console.log("useBackSnaps: 保存当前页面", backSnaps);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getScrollTop = () => {
|
||||||
|
return backSnaps[window.history.state.position]
|
||||||
|
? backSnaps[window.history.state.position].scrollTop
|
||||||
|
: 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getSnap=()=>{
|
||||||
|
return backSnaps[window.history.state.position]
|
||||||
|
? backSnaps[window.history.state.position]
|
||||||
|
: null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 恢复scrollTop设置
|
||||||
|
const restore = () => {
|
||||||
|
if (config.log)
|
||||||
|
console.log(
|
||||||
|
`useBackSnaps: 查找上次"#${config.elName}"保存的设置...`
|
||||||
|
);
|
||||||
|
if (backSnaps[window.history.state.position]) {
|
||||||
|
nextTick(() => {
|
||||||
|
document.getElementById(config.elName).scrollTop =
|
||||||
|
backSnaps[window.history.state.position].scrollTop;
|
||||||
|
});
|
||||||
|
if (config.log)
|
||||||
|
console.log(
|
||||||
|
`useBackSnaps: 恢复${config.elName}的scrollTop为${
|
||||||
|
backSnaps[window.history.state.position].scrollTop
|
||||||
|
}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
@ -1,6 +1,9 @@
|
|||||||
import { createRouter, createWebHashHistory } from "vue-router";
|
import { createRouter, createWebHashHistory } from "vue-router";
|
||||||
import pubsub from 'pubsub-js'
|
import pubsub from "pubsub-js";
|
||||||
import Home from "../views/Home.vue";
|
import store from "@/store";
|
||||||
|
import { saveBackSnaps } from "../lib/useBackSnaps";
|
||||||
|
// import eventBus from '@/eventBus'
|
||||||
|
// import Home from "../views/Home.vue";
|
||||||
|
|
||||||
const routes = [
|
const routes = [
|
||||||
{
|
{
|
||||||
@ -15,7 +18,7 @@ const routes = [
|
|||||||
{
|
{
|
||||||
path: "/discover",
|
path: "/discover",
|
||||||
name: "discover",
|
name: "discover",
|
||||||
component: ()=> import('../views/discover/Discover.vue'),
|
component: () => import("../views/discover/Discover.vue"),
|
||||||
meta: {
|
meta: {
|
||||||
keepAlive: true,
|
keepAlive: true,
|
||||||
},
|
},
|
||||||
@ -23,7 +26,7 @@ const routes = [
|
|||||||
{
|
{
|
||||||
path: "recommend",
|
path: "recommend",
|
||||||
name: "discover.recommend",
|
name: "discover.recommend",
|
||||||
component: ()=> import('@/views/discover/Recommend.vue'),
|
component: () => import("@/views/discover/Recommend.vue"),
|
||||||
meta: {
|
meta: {
|
||||||
keepAlive: true,
|
keepAlive: true,
|
||||||
},
|
},
|
||||||
@ -31,39 +34,39 @@ const routes = [
|
|||||||
{
|
{
|
||||||
path: "songlist",
|
path: "songlist",
|
||||||
name: "discover.songlist",
|
name: "discover.songlist",
|
||||||
component: ()=> import('../views/discover/Songlist.vue'),
|
component: () => import("../views/discover/Songlist.vue"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "anchor",
|
path: "anchor",
|
||||||
name: "discover.anchor",
|
name: "discover.anchor",
|
||||||
component: ()=> import('../views/discover/Anchor.vue'),
|
component: () => import("../views/discover/Anchor.vue"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "ranking",
|
path: "ranking",
|
||||||
name: "discover.ranking",
|
name: "discover.ranking",
|
||||||
component: ()=> import('../views/discover/Ranking.vue'),
|
component: () => import("../views/discover/Ranking.vue"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "singer",
|
path: "singer",
|
||||||
name: "discover.singer",
|
name: "discover.singer",
|
||||||
component: ()=> import('../views/discover/Singer.vue'),
|
component: () => import("../views/discover/Singer.vue"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "latest",
|
path: "latest",
|
||||||
name: "discover.latest",
|
name: "discover.latest",
|
||||||
component: ()=> import('../views/discover/Latest.vue'),
|
component: () => import("../views/discover/Latest.vue"),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/fm",
|
path: "/fm",
|
||||||
name: "fm",
|
name: "fm",
|
||||||
component: ()=> import('../views/fm/FM.vue'),
|
component: () => import("../views/fm/FM.vue"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/videos",
|
path: "/videos",
|
||||||
name: "videos",
|
name: "videos",
|
||||||
component: ()=> import('../views/videos/Videos.vue'),
|
component: () => import("../views/videos/Videos.vue"),
|
||||||
meta: {
|
meta: {
|
||||||
keepAlive: true,
|
keepAlive: true,
|
||||||
},
|
},
|
||||||
@ -71,36 +74,37 @@ const routes = [
|
|||||||
{
|
{
|
||||||
path: "v",
|
path: "v",
|
||||||
name: "videos.v",
|
name: "videos.v",
|
||||||
component: ()=> import('../views/videos/V.vue'),
|
component: () => import("../views/videos/V.vue"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "mv",
|
path: "mv",
|
||||||
name: "videos.mv",
|
name: "videos.mv",
|
||||||
component: ()=> import('../views/videos/MV.vue'),
|
component: () => import("../views/videos/MV.vue"),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/played",
|
path: "/played",
|
||||||
name: "played",
|
name: "played",
|
||||||
component: ()=> import('@/views/Played.vue'),
|
component: () => import("@/views/Played.vue"),
|
||||||
meta: {
|
meta: {
|
||||||
keepAlive: true,
|
keepAlive: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/search/:type/:keywords",
|
path: "/search/:keywords",
|
||||||
name: "search",
|
name: "search",
|
||||||
component: ()=> import('@/views/SearchResult.vue'),
|
component: () => import("@/views/SearchResult.vue"),
|
||||||
meta: {
|
meta: {
|
||||||
keepAlive: false,
|
keepAlive: false,
|
||||||
|
scrollTop: 0,
|
||||||
},
|
},
|
||||||
props: true,
|
props: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/friends",
|
path: "/friends",
|
||||||
name: "friends",
|
name: "friends",
|
||||||
component: ()=> import('../views/friends/Friends.vue'),
|
component: () => import("../views/friends/Friends.vue"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/about",
|
path: "/about",
|
||||||
@ -120,19 +124,39 @@ const router = createRouter({
|
|||||||
|
|
||||||
router.beforeEach((to, from, next) => {
|
router.beforeEach((to, from, next) => {
|
||||||
//发布router.beforeEach
|
//发布router.beforeEach
|
||||||
pubsub.publish('router.beforeEach', {to: to, frmo: from})
|
|
||||||
|
store.commit("saveSettings", {
|
||||||
|
currentRoute: to.fullPath,
|
||||||
|
});
|
||||||
|
// const scrollTop = $content ? $content.scrollTop : 0;
|
||||||
|
// from.meta.scrollTop = scrollTop;
|
||||||
|
// }
|
||||||
// to and from are both route objects. must call `next`.
|
// to and from are both route objects. must call `next`.
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// window.addEventListener(
|
||||||
|
// "popstate",
|
||||||
|
// (e) => {
|
||||||
|
// console.log("popstate ", e);
|
||||||
|
// },
|
||||||
|
// false
|
||||||
|
// );
|
||||||
|
|
||||||
router.afterEach((to, from) => {
|
router.afterEach((to, from) => {
|
||||||
// to and from are both route objects.
|
// to and from are both route objects.
|
||||||
|
|
||||||
|
saveBackSnaps() //保存返回设置
|
||||||
|
|
||||||
|
|
||||||
//发布router.afterEach订阅
|
//发布router.afterEach订阅
|
||||||
pubsub.publish('router.afterEach', {to: to, frmo: from})
|
// pubsub.publish('router.afterEach', {to: to, frmo: from})
|
||||||
|
// eventBus.emit('router.afterEach', {to: to, frmo: from})
|
||||||
// console.log('router----',to.path)
|
// console.log('router----',to.path)
|
||||||
|
store.commit("saveSettings", {
|
||||||
|
currentRoute: to.fullPath,
|
||||||
|
});
|
||||||
if (to.meta.title) document.title = to.meta.title;
|
if (to.meta.title) document.title = to.meta.title;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
export default router;
|
export default router;
|
||||||
|
@ -6,6 +6,9 @@ export default createStore({
|
|||||||
// debugStr: "测试debug字符",
|
// debugStr: "测试debug字符",
|
||||||
showSongDetail: false, //是否显示歌曲详情
|
showSongDetail: false, //是否显示歌曲详情
|
||||||
keywords: "", //查询关键字
|
keywords: "", //查询关键字
|
||||||
|
backSnaps: [], //返回快照
|
||||||
|
lastHistoryPos: -1,
|
||||||
|
lashHistoryLength: 0,
|
||||||
settings: {
|
settings: {
|
||||||
currentRoute: "/discover/recommend", //当前路由
|
currentRoute: "/discover/recommend", //当前路由
|
||||||
songId: 0, //歌曲id
|
songId: 0, //歌曲id
|
||||||
@ -80,6 +83,21 @@ export default createStore({
|
|||||||
saveLoaclSettings(state.settings);
|
saveLoaclSettings(state.settings);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
//载入backSnaps设置
|
||||||
|
loadBackSnaps(state) {
|
||||||
|
const l = localStorage.getItem("zmusic.backSnaps");
|
||||||
|
if (l) state.backSnaps = { ...state.backSnaps, ...JSON.parse(l) };
|
||||||
|
},
|
||||||
|
//保存backSnaps设置
|
||||||
|
saveBackSnaps(state, backSnaps) {
|
||||||
|
state.backSnaps = { ...state.backSnaps, ...backSnaps };
|
||||||
|
saveLoaclTheme(state.backSnaps);
|
||||||
|
},
|
||||||
|
saveSnaps(state, snap)
|
||||||
|
{
|
||||||
|
// state.backSnaps[snap.idx] =
|
||||||
|
},
|
||||||
|
|
||||||
//载入theme设置
|
//载入theme设置
|
||||||
loadTheme(state) {
|
loadTheme(state) {
|
||||||
const l = localStorage.getItem("zmusic.theme");
|
const l = localStorage.getItem("zmusic.theme");
|
||||||
@ -158,3 +176,6 @@ function saveLoaclCaches(s) {
|
|||||||
function saveLoaclTheme(s) {
|
function saveLoaclTheme(s) {
|
||||||
localStorage.setItem("zmusic.theme", JSON.stringify(s));
|
localStorage.setItem("zmusic.theme", JSON.stringify(s));
|
||||||
}
|
}
|
||||||
|
function saveLoaclBackSnaps(s) {
|
||||||
|
localStorage.setItem("zmusic.backSnaps", JSON.stringify(s));
|
||||||
|
}
|
||||||
|
@ -27,10 +27,9 @@ import dayjs from 'dayjs'
|
|||||||
import 'dayjs/locale/zh-cn'
|
import 'dayjs/locale/zh-cn'
|
||||||
import pubsub from "pubsub-js";
|
import pubsub from "pubsub-js";
|
||||||
|
|
||||||
console.log('Played 初始化');
|
//使用useBackSnaps恢复滚动条位置
|
||||||
onUnmounted(() => {
|
import { useBackSnaps } from "@/lib/useBackSnaps";
|
||||||
console.log('Played 卸载');
|
useBackSnaps()
|
||||||
})
|
|
||||||
|
|
||||||
const menuOptions = [
|
const menuOptions = [
|
||||||
{
|
{
|
||||||
@ -149,7 +148,7 @@ const route = useRoute();
|
|||||||
:value="route.path"
|
:value="route.path"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="main-content">
|
<div id="mainContent" class="main-content">
|
||||||
<div class="ld-width">
|
<div class="ld-width">
|
||||||
<div class="lmt-width">
|
<div class="lmt-width">
|
||||||
<n-layout>
|
<n-layout>
|
||||||
|
@ -1,32 +1,76 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onActivated, watch, onMounted } from "vue";
|
import {
|
||||||
|
ref,
|
||||||
|
toRefs,
|
||||||
|
onActivated,
|
||||||
|
watch,
|
||||||
|
onMounted,
|
||||||
|
nextTick,
|
||||||
|
defineAsyncComponent,
|
||||||
|
onDeactivated,
|
||||||
|
onUnmounted,
|
||||||
|
} from "vue";
|
||||||
import { searchResult } from "../network/search";
|
import { searchResult } from "../network/search";
|
||||||
import Songlist from "../components/Songlist.vue";
|
|
||||||
import SongsList from "../components/SongsList.vue";
|
|
||||||
import { useStore } from "vuex";
|
import { useStore } from "vuex";
|
||||||
import { NPagination } from "naive-ui";
|
import { c, NPagination } from "naive-ui";
|
||||||
|
import pubsub from "pubsub-js";
|
||||||
|
import Artistlist from "../components/Artistlist.vue";
|
||||||
|
import { get } from "lodash";
|
||||||
|
import { useRoute } from "vue-router";
|
||||||
|
|
||||||
|
//使用useBackSnaps恢复滚动条位置
|
||||||
|
import {
|
||||||
|
useBackSnaps,
|
||||||
|
getScrollTop,
|
||||||
|
saveSnap,
|
||||||
|
getSnap,
|
||||||
|
} from "@/lib/useBackSnaps";
|
||||||
|
useBackSnaps();
|
||||||
|
const snap = {
|
||||||
|
...{
|
||||||
|
type: 1,
|
||||||
|
page: 1,
|
||||||
|
pageSize: 50,
|
||||||
|
},
|
||||||
|
...getSnap()?.other,
|
||||||
|
};
|
||||||
|
console.log(snap);
|
||||||
|
|
||||||
|
const Songlist = defineAsyncComponent(() =>
|
||||||
|
import("@/components/Songlist.vue")
|
||||||
|
);
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
type: String,
|
|
||||||
keywords: String,
|
keywords: String,
|
||||||
});
|
});
|
||||||
|
|
||||||
const store = useStore();
|
const store = useStore();
|
||||||
|
const route = useRoute();
|
||||||
|
|
||||||
onActivated(() => {});
|
// const type = ref(getSnap('type', 1));
|
||||||
|
const type = ref(snap.type);
|
||||||
const type = ref(props.type);
|
const page = ref(snap.page);
|
||||||
|
const pageSize = ref(snap.pageSize);
|
||||||
const keywords = ref(props.keywords);
|
const keywords = ref(props.keywords);
|
||||||
|
|
||||||
|
// type.value=snap.type
|
||||||
|
// page.value=snap.page
|
||||||
|
// pageSize.value=snap.pageSize
|
||||||
|
|
||||||
const count = ref(0);
|
const count = ref(0);
|
||||||
const page = ref(1);
|
|
||||||
const pageSize = ref(50);
|
|
||||||
const things = ref("单曲");
|
const things = ref("单曲");
|
||||||
|
const elWp = ref(null);
|
||||||
const songs = ref([]);
|
const songs = ref([]);
|
||||||
|
const artists = ref([]);
|
||||||
|
const albums = ref([]);
|
||||||
|
const playlists = ref([]);
|
||||||
|
const djRadios = ref([]);
|
||||||
|
const mvs = ref([]);
|
||||||
|
const videos = ref([]);
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => [props.type, props.keywords, page.value, pageSize.value],
|
() => [props.keywords, type.value, page.value, pageSize.value],
|
||||||
([t, k]) => {
|
([k, t]) => {
|
||||||
type.value = t;
|
|
||||||
keywords.value = k;
|
keywords.value = k;
|
||||||
search();
|
search();
|
||||||
}
|
}
|
||||||
@ -37,11 +81,30 @@ onMounted(() => {
|
|||||||
search();
|
search();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let firstTime = true;
|
||||||
|
|
||||||
const search = () => {
|
const search = () => {
|
||||||
switch (type.value) {
|
switch (type.value) {
|
||||||
case "1":
|
case 10:
|
||||||
|
things.value = "专辑";
|
||||||
|
break;
|
||||||
|
case 100:
|
||||||
|
things.value = "歌手";
|
||||||
|
break;
|
||||||
|
case 1000:
|
||||||
|
things.value = "歌单";
|
||||||
|
break;
|
||||||
|
case 1009:
|
||||||
|
things.value = "电台";
|
||||||
|
break;
|
||||||
|
case 1004:
|
||||||
|
things.value = "MV";
|
||||||
|
break;
|
||||||
|
case 1014:
|
||||||
|
things.value = "视频";
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
default:
|
default:
|
||||||
type.value = "1";
|
|
||||||
things.value = "单曲";
|
things.value = "单曲";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -58,8 +121,45 @@ const search = () => {
|
|||||||
if (type.value == 1) {
|
if (type.value == 1) {
|
||||||
count.value = res.data.result.songCount;
|
count.value = res.data.result.songCount;
|
||||||
songs.value = res.data.result.songs;
|
songs.value = res.data.result.songs;
|
||||||
console.log(songs.value);
|
} else if (type.value == 100) {
|
||||||
|
count.value = res.data.result.artistCount;
|
||||||
|
artists.value = res.data.result.artists;
|
||||||
|
} else if (type.value == 10) {
|
||||||
|
count.value = res.data.result.albumCount;
|
||||||
|
albums.value = res.data.result.albums;
|
||||||
|
} else if (type.value == 1000) {
|
||||||
|
count.value = res.data.result.playlistCount;
|
||||||
|
playlists.value = res.data.result.playlists;
|
||||||
|
} else if (type.value == 1009) {
|
||||||
|
count.value = res.data.result.djRadiosCount;
|
||||||
|
djRadios.value = res.data.result.djRadios;
|
||||||
|
} else if (type.value == 1004) {
|
||||||
|
count.value = res.data.result.mvCount;
|
||||||
|
mvs.value = res.data.result.mvs;
|
||||||
|
} else if (type.value == 1014) {
|
||||||
|
count.value = res.data.result.videoCount;
|
||||||
|
videos.value = res.data.result.videos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//判断分页情况
|
||||||
|
const maxPage = Math.ceil(count.value / pageSize.value);
|
||||||
|
// console.log('maxPage:' ,count.value, maxPage);
|
||||||
|
if (page.value > maxPage) page.value = maxPage;
|
||||||
|
if (page.value < 1) page.value = 1;
|
||||||
|
|
||||||
|
if (firstTime) {
|
||||||
|
setTimeout(() => {
|
||||||
|
console.log(getScrollTop());
|
||||||
|
elWp.value.scrollTop = getScrollTop();
|
||||||
|
}, 100);
|
||||||
|
firstTime = false;
|
||||||
|
} else elWp.value.scrollTop = 0;
|
||||||
|
|
||||||
|
saveSnap({
|
||||||
|
type: type.value,
|
||||||
|
page: page.value,
|
||||||
|
pageSize: pageSize.value,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
@ -77,47 +177,125 @@ const selStyle = (t) => {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const songMenu = [
|
||||||
|
{
|
||||||
|
label: "播放",
|
||||||
|
key: "play",
|
||||||
|
},
|
||||||
|
// {
|
||||||
|
// label: "下一首播放",
|
||||||
|
// key: "nextToPlay",
|
||||||
|
// },
|
||||||
|
];
|
||||||
|
|
||||||
|
const click = () => {
|
||||||
|
// console.log("ctxMenuClick");
|
||||||
|
console.log(elWp.value.scrollTop);
|
||||||
|
window.history.pushState(null, null);
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="main-content">
|
<div id="mainContent" class="main-content" ref="elWp">
|
||||||
<div class="lmt-width">
|
<div class="lmt-width">
|
||||||
<div class="title">
|
<div class="title">
|
||||||
{{ keywords }}
|
{{ keywords }}
|
||||||
<span class="result">找到 {{ count }} {{ things }}</span>
|
<span class="result">找到 {{ count }} {{ things }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- <button @click="click" style="z-index: 1000">btn</button> -->
|
||||||
|
|
||||||
<div class="tabs">
|
<div class="tabs">
|
||||||
<div class="tab">
|
<div class="tab">
|
||||||
<div class="btns">
|
<div class="btns">
|
||||||
<span class="caption" :style="selStyle('1')"> 单曲 </span>
|
<span
|
||||||
<span class="caption" :style="selStyle('10')">
|
class="caption"
|
||||||
专辑
|
:style="selStyle('1')"
|
||||||
|
@click="
|
||||||
|
type = 1;
|
||||||
|
page = 1;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
单曲
|
||||||
</span>
|
</span>
|
||||||
<span class="caption" :style="selStyle('100')">
|
<span
|
||||||
|
class="caption"
|
||||||
|
:style="selStyle('100')"
|
||||||
|
@click="
|
||||||
|
type = 100;
|
||||||
|
page = 1;
|
||||||
|
"
|
||||||
|
>
|
||||||
歌手
|
歌手
|
||||||
</span>
|
</span>
|
||||||
<span class="caption" :style="selStyle('1000')">
|
<span
|
||||||
|
class="caption"
|
||||||
|
:style="selStyle('10')"
|
||||||
|
@click="type = 10;page=1;"
|
||||||
|
>
|
||||||
|
专辑
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="caption"
|
||||||
|
:style="selStyle('1000')"
|
||||||
|
@click="type = 1000;page=1;"
|
||||||
|
>
|
||||||
歌单
|
歌单
|
||||||
</span>
|
</span>
|
||||||
<span class="caption" :style="selStyle('1009')">
|
<span
|
||||||
|
class="caption"
|
||||||
|
:style="selStyle('1009')"
|
||||||
|
@click="type = 1009;page=1;"
|
||||||
|
>
|
||||||
电台
|
电台
|
||||||
</span>
|
</span>
|
||||||
<span class="caption" :style="selStyle('1004')">
|
<span
|
||||||
|
class="caption"
|
||||||
|
:style="selStyle('1004')"
|
||||||
|
@click="type = 1004;page=1;"
|
||||||
|
>
|
||||||
MV
|
MV
|
||||||
</span>
|
</span>
|
||||||
<span class="caption" :style="selStyle('1014')">
|
<span
|
||||||
|
class="caption"
|
||||||
|
:style="selStyle('1014')"
|
||||||
|
@click="type = 1014;page=1;"
|
||||||
|
>
|
||||||
视频
|
视频
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="bt"></div>
|
<div class="bt"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel" v-show="type == '1'">
|
<div class="panel" v-show="type == 1">
|
||||||
<Songlist :songs="songs"></Songlist>
|
<Songlist
|
||||||
|
:songs="songs"
|
||||||
|
:ctxMenu="songMenu"
|
||||||
|
@ctxMenuSelect="
|
||||||
|
(key, id) => {
|
||||||
|
switch (key) {
|
||||||
|
case 'play':
|
||||||
|
pubsub.publish('zp.play', {
|
||||||
|
id,
|
||||||
|
im: true,
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case 'nextToPlay':
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"
|
||||||
|
@itemDbclick="
|
||||||
|
(id) => {
|
||||||
|
pubsub.publish('zp.play', { id, im: true });
|
||||||
|
}
|
||||||
|
"
|
||||||
|
></Songlist>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel" v-show="type == '10'"></div>
|
<div class="panel" v-show="type == 10"></div>
|
||||||
<div class="panel" v-show="type == '100'"></div>
|
<div class="panel" v-show="type == 100">
|
||||||
<div class="panel" v-show="type == '1000'"></div>
|
<Artistlist :artists="artists" />
|
||||||
|
</div>
|
||||||
|
<div class="panel" v-show="type == 1000"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="pager">
|
<div class="pager">
|
||||||
<NPagination
|
<NPagination
|
||||||
@ -130,7 +308,9 @@ const selStyle = (t) => {
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {};
|
export default {
|
||||||
|
name: "SearchResult",
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
@ -156,6 +336,7 @@ export default {};
|
|||||||
margin-right: 16px;
|
margin-right: 16px;
|
||||||
color: #666;
|
color: #666;
|
||||||
border-bottom: solid 2px #f0f0f0;
|
border-bottom: solid 2px #f0f0f0;
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
// .sel {
|
// .sel {
|
||||||
// color: red;
|
// color: red;
|
||||||
|
@ -18,7 +18,7 @@ const search = () => {
|
|||||||
pubsub.publish("zp.toggleSearch");
|
pubsub.publish("zp.toggleSearch");
|
||||||
// elSearch.value.blur()
|
// elSearch.value.blur()
|
||||||
store.commit('addSearchHistory', keywords.value)
|
store.commit('addSearchHistory', keywords.value)
|
||||||
router.push(`/search/1/${keywords.value}`);
|
router.push(`/search/${keywords.value}`);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ onUnmounted(() => {
|
|||||||
@close.stop="store.commit('removeSearchHistory', h)"
|
@close.stop="store.commit('removeSearchHistory', h)"
|
||||||
@click="()=>{
|
@click="()=>{
|
||||||
pubsub.publish('zp.toggleSearch');
|
pubsub.publish('zp.toggleSearch');
|
||||||
router.push(`/search/1/${h}`);
|
router.push(`/search/${h}`);
|
||||||
}"
|
}"
|
||||||
>{{ h }}</NTag
|
>{{ h }}</NTag
|
||||||
>
|
>
|
||||||
@ -101,7 +101,7 @@ onUnmounted(() => {
|
|||||||
@click="()=>{
|
@click="()=>{
|
||||||
pubsub.publish('zp.toggleSearch');
|
pubsub.publish('zp.toggleSearch');
|
||||||
store.commit('addSearchHistory', item.searchWord)
|
store.commit('addSearchHistory', item.searchWord)
|
||||||
router.push(`/search/1/${item.searchWord}`);
|
router.push(`/search/${item.searchWord}`);
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<div class="idx" :class="{ idxHot: item.iconType == 1 }">
|
<div class="idx" :class="{ idxHot: item.iconType == 1 }">
|
||||||
|
@ -116,7 +116,7 @@ const route = useRoute();
|
|||||||
:value="route.path"
|
:value="route.path"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="main-content">
|
<div id="mainContent" class="main-content">
|
||||||
<!-- <input type="text"> -->
|
<!-- <input type="text"> -->
|
||||||
<!-- <NScrollbar > -->
|
<!-- <NScrollbar > -->
|
||||||
<div class="ld-width">
|
<div class="ld-width">
|
||||||
|
@ -217,6 +217,10 @@ import {
|
|||||||
import pubsub from "pubsub-js";
|
import pubsub from "pubsub-js";
|
||||||
import ArtistsSpan from "@/components/ArtistsSpan.vue";
|
import ArtistsSpan from "@/components/ArtistsSpan.vue";
|
||||||
|
|
||||||
|
//使用useBackSnaps恢复滚动条位置
|
||||||
|
import { useBackSnaps } from "@/lib/useBackSnaps";
|
||||||
|
useBackSnaps()
|
||||||
|
|
||||||
// console.log("recommend 初始化");
|
// console.log("recommend 初始化");
|
||||||
// onUnmounted(() => {
|
// onUnmounted(() => {
|
||||||
// console.log('recommend 卸载');
|
// console.log('recommend 卸载');
|
||||||
|
Loading…
x
Reference in New Issue
Block a user