|
@@ -7,7 +7,8 @@
|
|
|
<div class="content mb-2">
|
|
|
<!-- 路径 -->
|
|
|
<a-breadcrumb>
|
|
|
- <a-breadcrumb-item><a href="" @click="navTo('/')">首页</a></a-breadcrumb-item>
|
|
|
+ <a-breadcrumb-item><a href="javascript:;" @click="navTo('/')">首页</a></a-breadcrumb-item>
|
|
|
+ <a-breadcrumb-item v-if="prevPage"><a href="javascript:;" @click="prevPage.url ? navTo(prevPage.url) : back()">{{ prevPage.title }}</a></a-breadcrumb-item>
|
|
|
<a-breadcrumb-item>{{ title }}</a-breadcrumb-item>
|
|
|
</a-breadcrumb>
|
|
|
</div>
|
|
@@ -33,7 +34,7 @@
|
|
|
/>
|
|
|
<SimpleInput v-if="showSearch" v-model="searchText" placeholder="请输入关键词" @enter="handleSearch">
|
|
|
<template #suffix>
|
|
|
- <img
|
|
|
+ <IconSearch
|
|
|
class="search-icon"
|
|
|
src="@/assets/images/news/IconSearch.png"
|
|
|
alt="搜索"
|
|
@@ -44,31 +45,45 @@
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
- <div class="content news-list">
|
|
|
+ <div
|
|
|
+ :class="[
|
|
|
+ 'content',
|
|
|
+ 'news-list',
|
|
|
+ rowCount === 1 ? '' : 'grid',
|
|
|
+ ]"
|
|
|
+ >
|
|
|
<!-- 新闻列表 -->
|
|
|
<SimplePageContentLoader :loader="newsLoader">
|
|
|
- <div
|
|
|
- v-for="(item, k) in newsLoader.list.value"
|
|
|
- :key="item.id"
|
|
|
- class="item user-select-none main-clickable"
|
|
|
- :style="{ width: rowWidth }"
|
|
|
- @click="navTo('/news/detail', { id: item.id })"
|
|
|
- >
|
|
|
- <img :src="item.image" alt="新闻图片" />
|
|
|
- <TitleDescBlock
|
|
|
- :title="item.title"
|
|
|
- :desc="item.desc || item.title"
|
|
|
- :date="DateUtils.formatDate(item.publish_at, DateUtils.FormatStrings.YearCommon)"
|
|
|
- @click="handleShowDetail(item)"
|
|
|
+ <div class="list">
|
|
|
+ <div
|
|
|
+ v-for="(item, k) in newsLoader.list.value"
|
|
|
+ :key="item.id"
|
|
|
+ class="item user-select-none main-clickable"
|
|
|
+ :style="{ width: rowWidth }"
|
|
|
+ @click="navTo('/news/detail', { id: item.id })"
|
|
|
+ >
|
|
|
+ <img :src="item.image" alt="新闻图片" />
|
|
|
+ <TitleDescBlock
|
|
|
+ :title="item.title"
|
|
|
+ :desc="item.desc || item.title"
|
|
|
+ :date="DateUtils.formatDate(item.publish_at, DateUtils.FormatStrings.YearCommon)"
|
|
|
+ @click="handleShowDetail(item)"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ v-for="count of placeholderItemCount"
|
|
|
+ :key="count"
|
|
|
+ class="item empty"
|
|
|
+ :style="{ width: rowWidth }"
|
|
|
/>
|
|
|
</div>
|
|
|
</SimplePageContentLoader>
|
|
|
- <!-- 分页 -->
|
|
|
- <Pagination
|
|
|
- v-model:currentPage="newsLoader.page.value"
|
|
|
- :totalPages="newsLoader.totalPages.value"
|
|
|
- />
|
|
|
</div>
|
|
|
+ <!-- 分页 -->
|
|
|
+ <Pagination
|
|
|
+ v-model:currentPage="newsLoader.page.value"
|
|
|
+ :totalPages="newsLoader.totalPages.value"
|
|
|
+ />
|
|
|
</section>
|
|
|
</div>
|
|
|
</template>
|
|
@@ -84,8 +99,9 @@ import SimpleInput from '../controls/SimpleInput.vue';
|
|
|
import SimplePageContentLoader from '@/components/content/SimplePageContentLoader.vue';
|
|
|
import Pagination from '../controls/Pagination.vue';
|
|
|
import TitleDescBlock from '../parts/TitleDescBlock.vue';
|
|
|
+import IconSearch from '../icons/IconSearch.vue';
|
|
|
|
|
|
-const { navTo } = usePageAction();
|
|
|
+const { navTo, back } = usePageAction();
|
|
|
|
|
|
export interface DropdownCommonItem {
|
|
|
value: number;
|
|
@@ -101,6 +117,13 @@ const props = defineProps({
|
|
|
type: String,
|
|
|
default: '',
|
|
|
},
|
|
|
+ prevPage: {
|
|
|
+ type: Object as PropType<{
|
|
|
+ title: string,
|
|
|
+ url?: string,
|
|
|
+ }>,
|
|
|
+ default: null,
|
|
|
+ },
|
|
|
dropDownNames: {
|
|
|
type: Object as PropType<DropDownNames[]>,
|
|
|
default: null,
|
|
@@ -148,26 +171,29 @@ const props = defineProps({
|
|
|
},
|
|
|
})
|
|
|
|
|
|
+const realRowCount = computed(() => {
|
|
|
+ if (window.innerWidth < 768)
|
|
|
+ return 1;
|
|
|
+ return props.rowCount;
|
|
|
+});
|
|
|
const rowWidth = computed(() => {
|
|
|
- switch (props.rowCount) {
|
|
|
+ switch (realRowCount.value) {
|
|
|
case 2:
|
|
|
- return `calc(50% - 100px)`;
|
|
|
+ return `calc(50% - 25px)`;
|
|
|
case 3:
|
|
|
- return `calc(33% - 100px)`;
|
|
|
+ return `calc(33% - 25px)`;
|
|
|
case 4:
|
|
|
- return `calc(25% - 100px)`;
|
|
|
+ return `calc(25% - 25px)`;
|
|
|
}
|
|
|
});
|
|
|
-const rowMargin = computed(() => {
|
|
|
- switch (props.rowCount) {
|
|
|
+const placeholderItemCount = computed(() => {
|
|
|
+ switch (realRowCount.value) {
|
|
|
case 2:
|
|
|
- return 30;
|
|
|
case 3:
|
|
|
- return 30;
|
|
|
case 4:
|
|
|
- return 30;
|
|
|
+ return newsLoader.list.value.length % realRowCount.value;
|
|
|
}
|
|
|
- return '0';
|
|
|
+ return 0;
|
|
|
});
|
|
|
const searchText = ref('');
|
|
|
const dropDownValues = ref<any>([]);
|
|
@@ -202,10 +228,13 @@ onMounted(() => {
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss">
|
|
|
+@use "@/assets/scss/colors";
|
|
|
+
|
|
|
.search-icon {
|
|
|
- width: 20px;
|
|
|
- height: 20px;
|
|
|
+ width: 25px;
|
|
|
+ height: 25px;
|
|
|
cursor: pointer;
|
|
|
+ color: colors.$primary-color;
|
|
|
}
|
|
|
</style>
|
|
|
|