123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212 |
- <template>
- <!-- 资讯详情页 -->
- <div class="main-background">
- <div class="nav-placeholder"></div>
- <!-- 新闻 -->
- <section class="main-section main-background main-background-type0 small-h">
- <div class="content mb-2">
- <!-- 路径 -->
- <a-breadcrumb>
- <a-breadcrumb-item><a href="" @click="navTo('/')">首页</a></a-breadcrumb-item>
- <a-breadcrumb-item>{{ title }}</a-breadcrumb-item>
- </a-breadcrumb>
- </div>
- <div class="content mb-2">
- <!-- 搜素栏 -->
- <div class="row mt-3">
- <!-- 左栏 -->
- <div class="col-sm-12 col-md-6 col-lg-6">
- <!-- 分类 -->
- <TagBar
- :tags="tagsData || []"
- :margin="[30, 70]"
- v-model:selectedTag="selectedTag"
- />
- </div>
- <!-- 右栏 -->
- <div class="col-sm-12 col-md-6 col-lg-6 d-flex flex-row justify-content-end">
- <Dropdown
- v-for="(drop, k) in dropDownNames" :key="k"
- :selectedValue="dropDownValues[k] || drop.defaultSelectedValue"
- :options="drop.options"
- @update:selectedValue="(v) => handleChangeDropDownValue(k, v)"
- />
- <SimpleInput v-if="showSearch" v-model="searchText" placeholder="请输入关键词" @enter="handleSearch">
- <template #suffix>
- <img
- class="search-icon"
- src="@/assets/images/news/IconSearch.png"
- alt="搜索"
- @click="newsLoader.loadData(undefined, true)"
- />
- </template>
- </SimpleInput>
- </div>
- </div>
- </div>
- <div class="content news-list">
- <!-- 新闻列表 -->
- <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>
- </SimplePageContentLoader>
- <!-- 分页 -->
- <Pagination
- v-model:currentPage="newsLoader.page.value"
- :totalPages="newsLoader.totalPages.value"
- />
- </div>
- </section>
- </div>
- </template>
- <script setup lang="ts">
- import { computed, onMounted, ref, watch, type PropType } from 'vue';
- import { useSimplePagerDataLoader } from '@/composeable/SimplePagerDataLoader';
- import { usePageAction } from '@/composeable/PageAction';
- import DateUtils from '@/common/utils/DateUtils';
- import TagBar from '../content/TagBar.vue';
- import Dropdown from '../controls/Dropdown.vue';
- 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';
- const { navTo } = usePageAction();
- export interface DropdownCommonItem {
- value: number;
- title: string;
- }
- export interface DropDownNames {
- options: (string|DropdownCommonItem)[],
- defaultSelectedValue: number|string,
- }
- const props = defineProps({
- title: {
- type: String,
- default: '',
- },
- dropDownNames: {
- type: Object as PropType<DropDownNames[]>,
- default: null,
- },
- showSearch: {
- type: Boolean,
- default: true,
- },
- tagsData: {
- type: Object as PropType<{
- id: number,
- name: string,
- }[]>,
- default: null,
- },
- pageSize: {
- type: Number,
- default: 8,
- },
- rowCount: {
- type: Number,
- default: 2,
- },
- rowType: {
- type: Number,
- default: 1,
- },
- defaultSelectTag: {
- type: Number,
- default: 1,
- },
- load: {
- type: Function as PropType<(
- page: number,
- pageSize: number,
- selectedTag: number,
- searchText: string,
- dropDownValues: number[],
- ) => Promise<{
- page: number,
- total: number,
- data: any[],
- }>>,
- required: true,
- },
- })
- const rowWidth = computed(() => {
- switch (props.rowCount) {
- case 2:
- return `calc(50% - 100px)`;
- case 3:
- return `calc(33% - 100px)`;
- case 4:
- return `calc(25% - 100px)`;
- }
- });
- const rowMargin = computed(() => {
- switch (props.rowCount) {
- case 2:
- return 30;
- case 3:
- return 30;
- case 4:
- return 30;
- }
- return '0';
- });
- const searchText = ref('');
- const dropDownValues = ref<any>([]);
- function handleSearch() {
- newsLoader.loadData(undefined, true);
- }
- function handleChangeDropDownValue(index: number, value: number) {
- dropDownValues.value[index] = value;
- newsLoader.loadData(undefined, true);
- }
- function handleShowDetail(item: any) {
- navTo('/news/detail', { id: item.id });
- }
- const newsLoader = useSimplePagerDataLoader(props.pageSize, (page, size) => props.load(
- page, size,
- selectedTag.value,
- searchText.value,
- dropDownValues.value,
- ));
- //子分类
- const selectedTag = ref(props.defaultSelectTag);
- watch(selectedTag, () => {
- newsLoader.loadData(undefined, true);
- })
- onMounted(() => {
- newsLoader.loadData(undefined, true);
- });
- </script>
- <style lang="scss">
- .search-icon {
- width: 20px;
- height: 20px;
- cursor: pointer;
- }
- </style>
|