mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-09-07 00:36:41 +08:00
搜索框
This commit is contained in:
@@ -8,7 +8,23 @@ import Footer from "@/layouts/components/Footer.vue";
|
|||||||
import NavbarThemeSwitcher from "@/layouts/components/NavbarThemeSwitcher.vue";
|
import NavbarThemeSwitcher from "@/layouts/components/NavbarThemeSwitcher.vue";
|
||||||
import UserProfile from "@/layouts/components/UserProfile.vue";
|
import UserProfile from "@/layouts/components/UserProfile.vue";
|
||||||
|
|
||||||
// Banner
|
const router = useRouter();
|
||||||
|
|
||||||
|
// 搜索词
|
||||||
|
const searchWord = ref<string>("");
|
||||||
|
|
||||||
|
// Search
|
||||||
|
const search = () => {
|
||||||
|
if (!searchWord.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
router.push({
|
||||||
|
path: "/browse/media/search",
|
||||||
|
query: {
|
||||||
|
title: searchWord.value,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -24,16 +40,28 @@ import UserProfile from "@/layouts/components/UserProfile.vue";
|
|||||||
<!-- 👉 Search -->
|
<!-- 👉 Search -->
|
||||||
<div class="d-flex align-center cursor-pointer" style="user-select: none">
|
<div class="d-flex align-center cursor-pointer" style="user-select: none">
|
||||||
<!-- 👉 Search Trigger button -->
|
<!-- 👉 Search Trigger button -->
|
||||||
<IconBtn>
|
<IconBtn class="d-lg-none">
|
||||||
<VIcon icon="mdi-magnify" />
|
<VIcon icon="mdi-magnify" />
|
||||||
</IconBtn>
|
</IconBtn>
|
||||||
|
|
||||||
<span class="d-none d-md-flex align-center text-disabled">
|
|
||||||
<span class="me-3">搜索</span>
|
|
||||||
<span class="meta-key">⌘K</span>
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<span class="w-1/5">
|
||||||
|
<VTextField
|
||||||
|
v-model="searchWord"
|
||||||
|
class="d-none d-lg-block text-disabled"
|
||||||
|
density="compact"
|
||||||
|
variant="solo"
|
||||||
|
label="搜索电影、电视剧"
|
||||||
|
append-inner-icon="mdi-magnify"
|
||||||
|
single-line
|
||||||
|
hide-details
|
||||||
|
@click:append-inner="search"
|
||||||
|
@keydown.enter="search"
|
||||||
|
flat
|
||||||
|
rounded
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
|
||||||
<VSpacer />
|
<VSpacer />
|
||||||
|
|
||||||
<IconBtn
|
<IconBtn
|
||||||
|
|||||||
+27
-17
@@ -1,47 +1,57 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import MediaCardListView from '@/views/discover/MediaCardListView.vue';
|
import MediaCardListView from "@/views/discover/MediaCardListView.vue";
|
||||||
|
|
||||||
// 输入参数
|
// 输入参数
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
type: Array as PropType<string[]> | PropType<string>,
|
type: Array as PropType<string[]> | PropType<string>,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 路由参数
|
||||||
|
const route = useRoute();
|
||||||
|
|
||||||
|
// 面包屑标题定义
|
||||||
const titles: { [key: string]: any } = {
|
const titles: { [key: string]: any } = {
|
||||||
tmdb: {
|
tmdb: {
|
||||||
trending: '流行趋势',
|
trending: "流行趋势",
|
||||||
movies: '热门电影',
|
movies: "热门电影",
|
||||||
tvs: '热门电视剧',
|
tvs: "热门电视剧",
|
||||||
},
|
},
|
||||||
douban: {
|
douban: {
|
||||||
movies: '最新电影',
|
movies: "最新电影",
|
||||||
tvs: '最新电视剧',
|
tvs: "最新电视剧",
|
||||||
tv_weekly_chinese: '华语剧集榜',
|
tv_weekly_chinese: "华语剧集榜",
|
||||||
tv_weekly_global: '全球剧集榜',
|
tv_weekly_global: "全球剧集榜",
|
||||||
|
},
|
||||||
|
media: {
|
||||||
|
search: "搜索",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 计算API路径
|
||||||
const getApiPath = (types: string[] | string) => {
|
const getApiPath = (types: string[] | string) => {
|
||||||
if (Array.isArray(types)) {
|
if (Array.isArray(types)) {
|
||||||
return types.join('/')
|
return types.join("/");
|
||||||
} else {
|
} else {
|
||||||
return types
|
return types;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const getTitle = (types: string[] | string) => {
|
// 面包屑标题
|
||||||
|
const getTitle = (types: string[] | string, title: any = "") => {
|
||||||
if (Array.isArray(types)) {
|
if (Array.isArray(types)) {
|
||||||
return ['推荐', titles[types[0]][types[1]]]
|
if (title) {
|
||||||
|
return [titles[types[0]][types[1]], title];
|
||||||
|
}
|
||||||
|
return ["推荐", titles[types[0]][types[1]]];
|
||||||
} else {
|
} else {
|
||||||
return ["推荐"]
|
return ["发现"];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<VBreadcrumbs :items="getTitle(props.type||'')"></VBreadcrumbs>
|
<VBreadcrumbs :items="getTitle(props.type || '', route.query?.title)"></VBreadcrumbs>
|
||||||
<MediaCardListView :apipath="getApiPath(props.type||'')"/>
|
<MediaCardListView :apipath="getApiPath(props.type || '')" :params="route.query" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -6,12 +6,15 @@ import MediaCard from "@/components/cards/MediaCard.vue";
|
|||||||
// 输入参数
|
// 输入参数
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
apipath: String,
|
apipath: String,
|
||||||
|
params: Object as PropType<{ [key: string]: any }>,
|
||||||
});
|
});
|
||||||
|
|
||||||
// 当前页码
|
// 当前页码
|
||||||
const page = ref(1);
|
const page = ref(1);
|
||||||
// 是否加载中
|
// 是否加载中
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
|
// 是否加载完成
|
||||||
|
const finished = ref(false);
|
||||||
|
|
||||||
// 数据列表
|
// 数据列表
|
||||||
const dataList = ref<MediaInfo[]>([]);
|
const dataList = ref<MediaInfo[]>([]);
|
||||||
@@ -29,15 +32,23 @@ const fetchData = async ({ done }) => {
|
|||||||
}
|
}
|
||||||
// 设置加载中
|
// 设置加载中
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
|
// 参数
|
||||||
|
let params = {
|
||||||
|
page: page.value,
|
||||||
|
};
|
||||||
|
if (props.params) {
|
||||||
|
params = { ...params, ...props.params };
|
||||||
|
}
|
||||||
|
|
||||||
currData.value = await api.get(props.apipath, {
|
currData.value = await api.get(props.apipath, {
|
||||||
params: {
|
params: params,
|
||||||
page: page.value,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
// 合并数据
|
// 合并数据
|
||||||
dataList.value = [...dataList.value, ...currData.value];
|
dataList.value = [...dataList.value, ...currData.value];
|
||||||
// 页码+1
|
// 页码+1
|
||||||
page.value++;
|
page.value++;
|
||||||
|
// 标计为完成
|
||||||
|
finished.value = true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
} finally {
|
} finally {
|
||||||
@@ -49,6 +60,12 @@ const fetchData = async ({ done }) => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
<VProgressCircular
|
||||||
|
class="centered"
|
||||||
|
v-if="!finished"
|
||||||
|
indeterminate
|
||||||
|
color="primary"
|
||||||
|
></VProgressCircular>
|
||||||
<VInfiniteScroll
|
<VInfiniteScroll
|
||||||
mode="intersect"
|
mode="intersect"
|
||||||
side="end"
|
side="end"
|
||||||
@@ -66,4 +83,11 @@ const fetchData = async ({ done }) => {
|
|||||||
.grid-media-card {
|
.grid-media-card {
|
||||||
grid-template-columns: repeat(auto-fill, minmax(9.375rem, 1fr));
|
grid-template-columns: repeat(auto-fill, minmax(9.375rem, 1fr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.centered {
|
||||||
|
position: absolute;
|
||||||
|
inset-block-start: 50%;
|
||||||
|
inset-inline-start: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user