change: loading performance
This commit is contained in:
parent
7c8be0ccb9
commit
716b5535ae
14 changed files with 129 additions and 98 deletions
14
app.vue
14
app.vue
|
@ -3,19 +3,13 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import calculateTitle from "./composables/calculateTitle";
|
const { seo, title } = useGlobal();
|
||||||
import provideGlobal from "./composables/provideGlobal";
|
|
||||||
|
|
||||||
const { SEO } = await provideGlobal();
|
|
||||||
const title = await calculateTitle();
|
|
||||||
|
|
||||||
const { metaDescription, keywords } = SEO ?? {};
|
|
||||||
|
|
||||||
useHead({
|
useHead({
|
||||||
title: title,
|
title: title.value,
|
||||||
meta: [
|
meta: [
|
||||||
{ name: "description", content: metaDescription },
|
{ name: "description", content: seo.value?.metaDescription },
|
||||||
{ name: "keywords", content: keywords },
|
{ name: "keywords", content: seo.value?.keywords ?? "" },
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -29,7 +29,6 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
const title = await calculateTitle();
|
const { footer, title } = useGlobal();
|
||||||
const { footer } = await provideGlobal();
|
const { links, maintained_by, copyright } = footer.value ?? {};
|
||||||
const { links, maintained_by, copyright } = footer ?? {};
|
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -64,8 +64,6 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import provideGlobal from "../composables/provideGlobal";
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
params: { slug: params },
|
params: { slug: params },
|
||||||
} = useRoute();
|
} = useRoute();
|
||||||
|
@ -73,12 +71,12 @@ const {
|
||||||
const runtimeConfig = useRuntimeConfig();
|
const runtimeConfig = useRuntimeConfig();
|
||||||
const baseUrl = runtimeConfig.public.strapi.url;
|
const baseUrl = runtimeConfig.public.strapi.url;
|
||||||
|
|
||||||
const { logo, navbar } = await provideGlobal();
|
const { logo, navbar } = useGlobal();
|
||||||
|
|
||||||
const open = ref(false);
|
const open = ref(false);
|
||||||
|
|
||||||
const navbar_sub_items = computed(() => {
|
const navbar_sub_items = computed(() => {
|
||||||
if (!navbar) return [];
|
if (!navbar.value) return [];
|
||||||
return navbar.navbar_items.find((ni) => ni.URL == params?.[0])?.navbar_sub_items;
|
return navbar.value.navbar_items.find((ni) => ni.URL == params?.[0])?.navbar_sub_items;
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -4,10 +4,10 @@
|
||||||
:class="allowNavigation ? '' : 'pointer-events-none'"
|
:class="allowNavigation ? '' : 'pointer-events-none'"
|
||||||
:to="`${urlOverwrite ?? $route.path}/${data?.slug}`"
|
:to="`${urlOverwrite ?? $route.path}/${data?.slug}`"
|
||||||
>
|
>
|
||||||
<div class="w-full h-56 relative">
|
<div class="w-full h-56 min-h-56 relative">
|
||||||
<NuxtPicture
|
<NuxtPicture
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
class="w-full h-full object-cover object-center"
|
class="w-full h-full min-h-full object-cover object-center"
|
||||||
:src="data?.image?.url || logo?.url ? baseUrl + (data?.image?.url ?? logo?.url) : '/favicon.png'"
|
:src="data?.image?.url || logo?.url ? baseUrl + (data?.image?.url ?? logo?.url) : '/favicon.png'"
|
||||||
:imgAttrs="{ class: 'w-full h-full object-cover object-center' }"
|
:imgAttrs="{ class: 'w-full h-full object-cover object-center' }"
|
||||||
/>
|
/>
|
||||||
|
@ -20,11 +20,11 @@
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="w-full h-44 relative bg-white px-2 py-5 flex flex-col justify-start items-start gap-2 overflow-y-auto">
|
<div class="w-full grow relative bg-white p-2 pb-4 flex flex-col justify-start items-start gap-2 overflow-y-auto">
|
||||||
<h1>
|
<h1>
|
||||||
{{ data?.title }}
|
{{ data?.title }}
|
||||||
</h1>
|
</h1>
|
||||||
<p v-if="itemDate && lookup?.show_date" class="w-full text-[#5c5c5c]">
|
<p class="w-full text-[#5c5c5c] line-clamp-2 overflow-hidden">
|
||||||
{{ itemDate }}
|
{{ itemDate }}
|
||||||
</p>
|
</p>
|
||||||
<p class="w-full text-[#5c5c5c] line-clamp-2 overflow-hidden">
|
<p class="w-full text-[#5c5c5c] line-clamp-2 overflow-hidden">
|
||||||
|
@ -42,7 +42,7 @@ import type Lookup from "../../types/collection/lookup";
|
||||||
const runtimeConfig = useRuntimeConfig();
|
const runtimeConfig = useRuntimeConfig();
|
||||||
const baseUrl = runtimeConfig.public.strapi.url;
|
const baseUrl = runtimeConfig.public.strapi.url;
|
||||||
|
|
||||||
const { logo } = await provideGlobal();
|
const { logo } = useGlobal();
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
data: Object as PropType<BaseCollection>,
|
data: Object as PropType<BaseCollection>,
|
||||||
|
|
|
@ -25,7 +25,7 @@ import type SharedEmphasiseArticle from "../../types/component/shared/emphasiseA
|
||||||
import type Lookup from "../../types/collection/lookup";
|
import type Lookup from "../../types/collection/lookup";
|
||||||
|
|
||||||
const { find } = useStrapi();
|
const { find } = useStrapi();
|
||||||
const { data: lookup } = await useAsyncData("lookup", () =>
|
const { data: lookup } = await useAsyncData(() =>
|
||||||
find<Lookup>("collection-lookups", {
|
find<Lookup>("collection-lookups", {
|
||||||
filters: {
|
filters: {
|
||||||
collection: "articles",
|
collection: "articles",
|
||||||
|
|
|
@ -113,13 +113,13 @@ const pagination = ref<Meta>({ page: 0, pageSize: 0, pageCount: 0, total: 0 });
|
||||||
const activeYear = ref<number>(0);
|
const activeYear = ref<number>(0);
|
||||||
|
|
||||||
if (props.data?.lookup.list_with_date != "none") {
|
if (props.data?.lookup.list_with_date != "none") {
|
||||||
const { data: year } = await useAsyncData<Array<number>>("distinct-years", () =>
|
const { data: year } = await useAsyncData<Array<number>>(() =>
|
||||||
$fetch(`${baseUrl}/api/custom/${props.data?.lookup.collection}/distinct-years`)
|
$fetch(`${baseUrl}/api/custom/${props.data?.lookup.collection}/distinct-years`)
|
||||||
);
|
);
|
||||||
years.value = year.value ?? [];
|
years.value = year.value ?? [];
|
||||||
activeYear.value = years.value[0] ?? 0;
|
activeYear.value = years.value[0] ?? 0;
|
||||||
}
|
}
|
||||||
const { data: collections } = await useAsyncData("collection", () =>
|
const { data: collections } = await useAsyncData(() =>
|
||||||
find<BaseCollection>(props.data?.lookup.collection ?? "", {
|
find<BaseCollection>(props.data?.lookup.collection ?? "", {
|
||||||
...(props.data?.lookup?.list_with_date != "none"
|
...(props.data?.lookup?.list_with_date != "none"
|
||||||
? {
|
? {
|
||||||
|
@ -235,7 +235,7 @@ async function changeTimedData(year: number) {
|
||||||
withCount: true,
|
withCount: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
console.log(data);
|
|
||||||
collection.value = data?.data;
|
collection.value = data?.data;
|
||||||
pagination.value = (data?.meta.pagination as unknown as {
|
pagination.value = (data?.meta.pagination as unknown as {
|
||||||
page: number;
|
page: number;
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
import provideGlobal from "./provideGlobal";
|
|
||||||
|
|
||||||
export default async function () {
|
|
||||||
const runtimeConfig = useRuntimeConfig();
|
|
||||||
const appTitle = runtimeConfig.public.app.title;
|
|
||||||
|
|
||||||
const { SEO } = await provideGlobal();
|
|
||||||
const { metaTitle } = SEO ?? {};
|
|
||||||
|
|
||||||
return metaTitle ?? appTitle;
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
import type Global from "../types/single/global";
|
|
||||||
|
|
||||||
export default async function () {
|
|
||||||
const { findOne } = useStrapi();
|
|
||||||
const { data: global } = await useAsyncData("global", () => findOne<Global>("global"));
|
|
||||||
const { logo, navbar, footer, SEO } = global.value?.data ?? {};
|
|
||||||
|
|
||||||
return { logo, navbar, footer, SEO };
|
|
||||||
}
|
|
26
composables/useGlobal.ts
Normal file
26
composables/useGlobal.ts
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
import type BaseFile from "../types/component/baseFile";
|
||||||
|
import type Footer from "../types/component/global/footer";
|
||||||
|
import type Navbar from "../types/component/global/navbar";
|
||||||
|
import type SEO from "../types/component/global/seo";
|
||||||
|
import type Global from "../types/single/global";
|
||||||
|
|
||||||
|
export const useGlobal = () => {
|
||||||
|
const global = useState<Global | null>("global");
|
||||||
|
const runtimeConfig = useRuntimeConfig();
|
||||||
|
const appTitle = runtimeConfig.public.app.title;
|
||||||
|
|
||||||
|
const logo = computed<BaseFile | null>(() => global.value?.logo ?? null);
|
||||||
|
const navbar = computed<Navbar | null>(() => global.value?.navbar ?? null);
|
||||||
|
const footer = computed<Footer | null>(() => global.value?.footer ?? null);
|
||||||
|
const seo = computed<SEO | null>(() => global.value?.SEO ?? null);
|
||||||
|
const title = computed<string>(() => seo.value?.metaTitle ?? appTitle);
|
||||||
|
|
||||||
|
return {
|
||||||
|
logo,
|
||||||
|
global,
|
||||||
|
navbar,
|
||||||
|
footer,
|
||||||
|
seo,
|
||||||
|
title,
|
||||||
|
};
|
||||||
|
};
|
|
@ -1,30 +1,15 @@
|
||||||
import type Article from "../types/collection/article";
|
|
||||||
import type Page from "../types/collection/page";
|
import type Page from "../types/collection/page";
|
||||||
import type { ComponentTypes } from "../types/component/baseComponent";
|
import type { ComponentTypes } from "../types/component/baseComponent";
|
||||||
import type SharedList from "../types/component/shared/list";
|
|
||||||
import type Global from "../types/single/global";
|
|
||||||
|
|
||||||
export default async function () {
|
export const useSitemap = () => {
|
||||||
const { find } = useStrapi();
|
const { navbar, footer } = useGlobal();
|
||||||
|
const pages = useState<Page[]>("sitemap_pages");
|
||||||
|
|
||||||
const nuxtApp = useNuxtApp();
|
const sitemap = ref<sitemap>([]);
|
||||||
const { navbar, footer } = await nuxtApp.runWithContext(() => provideGlobal());
|
|
||||||
const { data: page_res } = await nuxtApp.runWithContext(() =>
|
|
||||||
useAsyncData("sitemap_pages", () =>
|
|
||||||
find<Page>("pages", {
|
|
||||||
filters: {
|
|
||||||
ref_only_access: false,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
)
|
|
||||||
);
|
|
||||||
const pages = page_res.value?.data ?? [];
|
|
||||||
|
|
||||||
const accessableURLs: Array<{ path: string; origin: string; document?: string; hasCollection?: boolean }> = [];
|
for (const element of navbar.value?.navbar_items ?? []) {
|
||||||
|
|
||||||
for (const element of navbar?.navbar_items ?? []) {
|
|
||||||
if (!element.default_active_child) {
|
if (!element.default_active_child) {
|
||||||
accessableURLs.push({
|
sitemap.value.push({
|
||||||
path: element.URL.startsWith("/") ? element.URL : `/${element.URL}`,
|
path: element.URL.startsWith("/") ? element.URL : `/${element.URL}`,
|
||||||
origin: "navbar",
|
origin: "navbar",
|
||||||
document: element?.page?.documentId,
|
document: element?.page?.documentId,
|
||||||
|
@ -33,7 +18,7 @@ export default async function () {
|
||||||
}
|
}
|
||||||
for (const subelement of element.navbar_sub_items) {
|
for (const subelement of element.navbar_sub_items) {
|
||||||
let url = `${element.URL}/${subelement.URL}`;
|
let url = `${element.URL}/${subelement.URL}`;
|
||||||
accessableURLs.push({
|
sitemap.value.push({
|
||||||
path: url.startsWith("/") ? url : `/${url}`,
|
path: url.startsWith("/") ? url : `/${url}`,
|
||||||
origin: "navbar",
|
origin: "navbar",
|
||||||
document: subelement?.page?.documentId,
|
document: subelement?.page?.documentId,
|
||||||
|
@ -43,10 +28,10 @@ export default async function () {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const element of pages) {
|
for (const element of pages.value) {
|
||||||
let url = element.slug.replaceAll("~", "/");
|
let url = element.slug.replaceAll("~", "/");
|
||||||
if (!accessableURLs.find((a) => a.path == url)) {
|
if (!sitemap.value.find((a) => a.path == url)) {
|
||||||
accessableURLs.push({
|
sitemap.value.push({
|
||||||
path: url.startsWith("/") ? url : `/${url}`,
|
path: url.startsWith("/") ? url : `/${url}`,
|
||||||
origin: "page",
|
origin: "page",
|
||||||
document: element.documentId,
|
document: element.documentId,
|
||||||
|
@ -55,10 +40,10 @@ export default async function () {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const element of footer?.links ?? []) {
|
for (const element of footer.value?.links ?? []) {
|
||||||
let url = element.URL.startsWith("/") ? element.URL : `/${element.URL}`;
|
let url = element.URL.startsWith("/") ? element.URL : `/${element.URL}`;
|
||||||
if (!accessableURLs.find((a) => a.path == url) && !element.URL.startsWith("http")) {
|
if (!sitemap.value.find((a) => a.path == url) && !element.URL.startsWith("http")) {
|
||||||
accessableURLs.push({
|
sitemap.value.push({
|
||||||
path: url,
|
path: url,
|
||||||
origin: "footer",
|
origin: "footer",
|
||||||
document: undefined,
|
document: undefined,
|
||||||
|
@ -67,5 +52,12 @@ export default async function () {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return accessableURLs;
|
return sitemap;
|
||||||
}
|
};
|
||||||
|
|
||||||
|
type sitemap = Array<{
|
||||||
|
path: string;
|
||||||
|
origin: string;
|
||||||
|
document?: string;
|
||||||
|
hasCollection?: boolean;
|
||||||
|
}>;
|
|
@ -22,14 +22,13 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import provideGlobal from "../composables/provideGlobal";
|
|
||||||
import type Homepage from "../types/single/homepage";
|
import type Homepage from "../types/single/homepage";
|
||||||
|
|
||||||
const runtimeConfig = useRuntimeConfig();
|
const runtimeConfig = useRuntimeConfig();
|
||||||
const baseUrl = runtimeConfig.public.strapi.url;
|
const baseUrl = runtimeConfig.public.strapi.url;
|
||||||
const { findOne } = useStrapi();
|
const { findOne } = useStrapi();
|
||||||
|
|
||||||
const { logo } = await provideGlobal();
|
const { logo } = useGlobal();
|
||||||
|
|
||||||
const { data: homepage } = await useAsyncData("homepage", () => findOne<Homepage>("homepage"));
|
const { data: homepage } = await useAsyncData("homepage", () => findOne<Homepage>("homepage"));
|
||||||
const { backdrop } = homepage.value?.data ?? {};
|
const { backdrop } = homepage.value?.data ?? {};
|
||||||
|
|
|
@ -12,14 +12,13 @@ import type Event from "../types/collection/event";
|
||||||
import type Operation from "../types/collection/operation";
|
import type Operation from "../types/collection/operation";
|
||||||
import type Vehicle from "../types/collection/vehicle";
|
import type Vehicle from "../types/collection/vehicle";
|
||||||
import type Page from "../types/collection/page";
|
import type Page from "../types/collection/page";
|
||||||
import provideGlobal from "../composables/provideGlobal";
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
params: { slug: params },
|
params: { slug: params },
|
||||||
} = useRoute();
|
} = useRoute();
|
||||||
const { findOne, find } = useStrapi();
|
const { findOne, find } = useStrapi();
|
||||||
|
|
||||||
const sitemap = await calculateSitemap();
|
const sitemap = useSitemap();
|
||||||
|
|
||||||
const detail = ref<Article | Operation | Event | Vehicle | undefined>(undefined);
|
const detail = ref<Article | Operation | Event | Vehicle | undefined>(undefined);
|
||||||
|
|
||||||
|
@ -27,10 +26,10 @@ const activePath = computed(() => {
|
||||||
return "/" + (Array.isArray(params) ? params.join("/") : params);
|
return "/" + (Array.isArray(params) ? params.join("/") : params);
|
||||||
});
|
});
|
||||||
const activePageBySitemap = computed(() => {
|
const activePageBySitemap = computed(() => {
|
||||||
return sitemap.find((s) => s.path == activePath.value);
|
return sitemap.value.find((s) => s.path == activePath.value);
|
||||||
});
|
});
|
||||||
const similarestPage = computed(() => {
|
const similarestPage = computed(() => {
|
||||||
return sitemap.reduce(
|
return sitemap.value.reduce(
|
||||||
(bestMatch, current) => {
|
(bestMatch, current) => {
|
||||||
const currentMatchLength = current.path
|
const currentMatchLength = current.path
|
||||||
.split("/")
|
.split("/")
|
||||||
|
@ -49,23 +48,27 @@ const similarestPage = computed(() => {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
const { data: pages } = await useAsyncData("pages", () =>
|
const { data: pages } = await useAsyncData(
|
||||||
findOne<Page | Array<Page>>("pages", similarestPage.value?.document, {
|
() =>
|
||||||
populate: {
|
findOne<Page | Array<Page>>("pages", similarestPage.value?.document, {
|
||||||
populate: "*",
|
populate: {
|
||||||
content: {
|
|
||||||
populate: "*",
|
populate: "*",
|
||||||
|
content: {
|
||||||
|
populate: "*",
|
||||||
|
},
|
||||||
|
hero: {
|
||||||
|
populate: "*",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
hero: {
|
filters: {
|
||||||
populate: "*",
|
...(!similarestPage.value?.document
|
||||||
|
? { slug: Array.isArray(params) ? params.join("~") : params, ref_only_access: false }
|
||||||
|
: {}),
|
||||||
},
|
},
|
||||||
},
|
}),
|
||||||
filters: {
|
{
|
||||||
...(!similarestPage.value?.document
|
default: () => null,
|
||||||
? { slug: Array.isArray(params) ? params.join("~") : params, ref_only_access: false }
|
}
|
||||||
: {}),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
);
|
);
|
||||||
const page = computed(() => {
|
const page = computed(() => {
|
||||||
return Array.isArray(pages.value?.data) ? pages.value.data[0] : pages.value?.data;
|
return Array.isArray(pages.value?.data) ? pages.value.data[0] : pages.value?.data;
|
||||||
|
@ -100,7 +103,7 @@ if (isCollectionDetail) {
|
||||||
];
|
];
|
||||||
|
|
||||||
for (const element of collectionOfDetail) {
|
for (const element of collectionOfDetail) {
|
||||||
const { data: details } = await useAsyncData("detail", () =>
|
const { data: details } = await useAsyncData(() =>
|
||||||
find<Article | Operation | Event | Vehicle>(element ?? "", {
|
find<Article | Operation | Event | Vehicle>(element ?? "", {
|
||||||
populate: "*",
|
populate: "*",
|
||||||
filters: {
|
filters: {
|
||||||
|
|
15
plugins/global.ts
Normal file
15
plugins/global.ts
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
import type Global from "../types/single/global";
|
||||||
|
|
||||||
|
export default defineNuxtPlugin(async (nuxtApp) => {
|
||||||
|
const globalState = useState<Global | null>("global", () => null);
|
||||||
|
|
||||||
|
if (!globalState.value) {
|
||||||
|
const { findOne } = useStrapi();
|
||||||
|
const { data: global } = await useAsyncData("global", () => findOne<Global>("global"), {
|
||||||
|
server: true,
|
||||||
|
lazy: false,
|
||||||
|
default: () => {},
|
||||||
|
});
|
||||||
|
globalState.value = global.value?.data ?? null;
|
||||||
|
}
|
||||||
|
});
|
25
plugins/sitemap.ts
Normal file
25
plugins/sitemap.ts
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
import type Page from "../types/collection/page";
|
||||||
|
import type Global from "../types/single/global";
|
||||||
|
|
||||||
|
export default defineNuxtPlugin(async (nuxtApp) => {
|
||||||
|
const pageState = useState<Page[]>("sitemap_pages", () => []);
|
||||||
|
|
||||||
|
if (!pageState.value) {
|
||||||
|
const { find } = useStrapi();
|
||||||
|
const { data: page_res } = await useAsyncData(
|
||||||
|
"sitemap_pages",
|
||||||
|
() =>
|
||||||
|
find<Page>("pages", {
|
||||||
|
filters: {
|
||||||
|
ref_only_access: false,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
server: true,
|
||||||
|
lazy: false,
|
||||||
|
default: () => {},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
pageState.value = page_res.value?.data ?? [];
|
||||||
|
}
|
||||||
|
});
|
Loading…
Add table
Reference in a new issue