Skip to content

Commit

Permalink
fix: avoid calling composition apis in computed hook
Browse files Browse the repository at this point in the history
  • Loading branch information
Mister-Hope committed Jan 25, 2024
1 parent 53ec581 commit 993e1b9
Show file tree
Hide file tree
Showing 7 changed files with 141 additions and 105 deletions.
11 changes: 5 additions & 6 deletions packages/blog2/src/client/composables/useBlogCategory.ts
Expand Up @@ -28,18 +28,17 @@ export const blogCategoryMap = readonly(_blogCategoryMap);
export const useBlogCategory = <
T extends Record<string, unknown> = Record<string, unknown>,
>(
key = "",
key?: string,
): ComputedRef<BlogCategoryData<T>> => {
const page = usePageData();
const frontmatter = usePageFrontmatter<{
blog?: BlogCategoryFrontmatterOptions;
}>();
const router = useRouter();
const routeLocale = useRouteLocale();

return computed(() => {
const mapKey =
key ||
usePageFrontmatter<{ blog?: BlogCategoryFrontmatterOptions }>().value.blog
?.key ||
"";
const mapKey = key ?? frontmatter.value.blog?.key ?? "";

if (!mapKey) {
console.warn(`useBlogCategory: key not found`);
Expand Down
11 changes: 5 additions & 6 deletions packages/blog2/src/client/composables/useBlogType.ts
Expand Up @@ -23,17 +23,16 @@ export const blogTypeMap = readonly(_blogTypeMap);
export const useBlogType = <
T extends Record<string, unknown> = Record<string, unknown>,
>(
key = "",
key?: string,
): ComputedRef<BlogTypeData<T>> => {
const frontmatter = usePageFrontmatter<{
blog?: BlogTypeFrontmatterOptions;
}>();
const router = useRouter();
const routeLocale = useRouteLocale();

return computed(() => {
const mapKey =
key ||
usePageFrontmatter<{ blog?: BlogTypeFrontmatterOptions }>().value.blog
?.key ||
"";
const mapKey = key ?? frontmatter.value.blog?.key ?? "";

if (!mapKey) {
console.warn(`useBlogType: key not found`);
Expand Down
7 changes: 3 additions & 4 deletions packages/comment2/src/client/components/Giscus.ts
Expand Up @@ -86,6 +86,7 @@ export default defineComponent({

setup(props) {
const giscusOptions = useGiscusOptions();
const lang = usePageLang();

const enableGiscus = Boolean(
giscusOptions.repo &&
Expand All @@ -99,11 +100,9 @@ export default defineComponent({
const loaded = ref(false);

const giscusLang = computed(() => {
const lang = usePageLang().value as GiscusLang;
if (SUPPORTED_LANGUAGES.includes(<GiscusLang>lang.value)) return lang;

if (SUPPORTED_LANGUAGES.includes(lang)) return lang;

const shortCode = lang.split("-")[0] as GiscusLang;
const shortCode = lang.value.split("-")[0] as GiscusLang;

if (SUPPORTED_LANGUAGES.includes(shortCode)) return shortCode;

Expand Down
15 changes: 11 additions & 4 deletions packages/theme/src/client/components/PageNav.ts
Expand Up @@ -3,6 +3,7 @@ import { isPlainObject, isString } from "@vuepress/shared";
import { useEventListener } from "@vueuse/core";
import type { VNode } from "vue";
import { computed, defineComponent, h } from "vue";
import type { Router } from "vue-router";
import { useRouter } from "vue-router";

import AutoLink from "@theme-hope/components/AutoLink";
Expand All @@ -23,10 +24,9 @@ import "../styles/page-nav.scss";
* Resolve `prev` or `next` config from frontmatter
*/
const resolveFromFrontmatterConfig = (
router: Router,
conf: unknown,
): AutoLinkOptions | null | false => {
const router = useRouter();

if (conf === false) return false;

if (isString(conf)) return resolveLinkInfo(router, conf, true);
Expand Down Expand Up @@ -76,10 +76,14 @@ export default defineComponent({
const frontmatter = usePageFrontmatter<ThemeNormalPageFrontmatter>();
const sidebarItems = useSidebarItems();
const page = usePageData();
const router = useRouter();
const navigate = useNavigate();

const prevNavLink = computed(() => {
const prevConfig = resolveFromFrontmatterConfig(frontmatter.value.prev);
const prevConfig = resolveFromFrontmatterConfig(
router,
frontmatter.value.prev,
);

return prevConfig === false
? null
Expand All @@ -94,7 +98,10 @@ export default defineComponent({
});

const nextNavLink = computed(() => {
const nextConfig = resolveFromFrontmatterConfig(frontmatter.value.next);
const nextConfig = resolveFromFrontmatterConfig(
router,
frontmatter.value.next,
);

return nextConfig === false
? null
Expand Down
7 changes: 5 additions & 2 deletions packages/theme/src/client/composables/themeData.ts
Expand Up @@ -24,5 +24,8 @@ export const useThemeAuthor = (): ComputedRef<AuthorInfo[]> => {
return computed(() => getAuthor(themeLocale.value.author, false));
};

export const usePure = (): ComputedRef<boolean> =>
computed(() => Boolean(useThemeData().value.pure));
export const usePure = (): ComputedRef<boolean> => {
const themeData = useThemeData();

return computed(() => Boolean(themeData.value.pure));
};
177 changes: 96 additions & 81 deletions packages/theme/src/client/modules/sidebar/composables/resolveConfig.ts
@@ -1,13 +1,12 @@
/* eslint-disable @typescript-eslint/no-unsafe-argument */
import type { PageHeader } from "@vuepress/client";
import { usePageData, useRouteLocale } from "@vuepress/client";
import type { PageData, PageHeader } from "@vuepress/client";
import {
isArray,
isLinkExternal,
isPlainObject,
isString,
} from "@vuepress/shared";
import { useRouter } from "vue-router";
import type { Router } from "vue-router";
import { keys, startsWith } from "vuepress-shared/client";

import { sidebarData } from "@temp/theme-hope/sidebar";
Expand All @@ -29,50 +28,42 @@ import type {
/**
* Util to transform page header to sidebar item
*/
export const headerToSidebarItem = (
header: PageHeader,
headerDepth: number,
): ResolvedSidebarHeaderItem => {
const page = usePageData();

return {
type: "heading",
text: header.title,
link: `${page.value.path}#${header.slug}`,
children: headersToSidebarItemChildren(header.children, headerDepth),
};
};

export const headersToSidebarItemChildren = (
page: PageData,
headers: PageHeader[],
headerDepth: number,
): ResolvedSidebarHeaderItem[] =>
headerDepth > 0
? headers.map((header) => headerToSidebarItem(header, headerDepth - 1))
? headers.map((header) => ({
type: "heading",
text: header.title,
link: `${page.path}#${header.slug}`,
children: headersToSidebarItemChildren(
page,
header.children,
headerDepth - 1,
),
}))
: [];

/**
* Resolve sidebar items if the config is `heading`
*/
export const resolveHeadingSidebarItems = (
headerDepth: number,
): ResolvedSidebarHeaderItem[] => {
const page = usePageData();

return headersToSidebarItemChildren(page.value.headers, headerDepth);
};
export interface ResolveArraySidebarOptions {
config: SidebarArrayOptions;
router: Router;
page: PageData;
headerDepth: number;
prefix?: string;
}

/**
* Resolve sidebar items if the config is an array
*/
export const resolveArraySidebarItems = (
sidebarConfig: SidebarArrayOptions,
headerDepth: number,
export const resolveArraySidebarItems = ({
config,
router,
page,
headerDepth,
prefix = "",
): ResolvedSidebarItem[] => {
const router = useRouter();
const page = usePageData();

}: ResolveArraySidebarOptions): ResolvedSidebarItem[] => {
const handleChildItem = (
item: SidebarItem,
pathPrefix = prefix,
Expand Down Expand Up @@ -116,79 +107,103 @@ export const resolveArraySidebarItems = (
children:
// if the sidebar item is current page and children is not set
// use headers of current page as children
childItem.link === page.value.path
childItem.link === page.path
? headersToSidebarItemChildren(
page,
// skip h1 header
page.value.headers[0]?.level === 1
? page.value.headers[0].children
: page.value.headers,
page.headers[0]?.level === 1
? page.headers[0].children
: page.headers,
headerDepth,
)
: [],
};
};

return sidebarConfig.map((item) => handleChildItem(item));
return config.map((item) => handleChildItem(item));
};

export interface ResolveMultiSidebarOptions {
config: SidebarObjectOptions;
router: Router;
page: PageData;
headerDepth: number;
}

/**
* Resolve sidebar items if the config is a key -> value (path-prefix -> array) object
*/
export const resolveMultiSidebarItems = (
sidebarConfig: SidebarObjectOptions,
headerDepth: number,
): ResolvedSidebarItem[] => {
const page = usePageData();
const sidebarRoutes = keys(sidebarConfig).sort((x, y) => y.length - x.length);
export const resolveMultiSidebarItems = ({
config,
router,
page,
headerDepth,
}: ResolveMultiSidebarOptions): ResolvedSidebarItem[] => {
const sidebarRoutes = keys(config).sort((x, y) => y.length - x.length);

// find matching config
for (const base of sidebarRoutes)
if (startsWith(decodeURI(page.value.path), base)) {
const matchedConfig = sidebarConfig[base];

return matchedConfig
? resolveArraySidebarItems(
matchedConfig === "structure"
? sidebarData[base]
: matchedConfig === "heading"
? resolveHeadingSidebarItems(headerDepth)
: matchedConfig,
if (startsWith(decodeURI(page.path), base)) {
const matched = config[base];

return matched
? resolveArraySidebarItems({
config:
matched === "structure"
? <SidebarArrayOptions>sidebarData[base]
: matched === "heading"
? headersToSidebarItemChildren(
page,
page.headers,
headerDepth,
)
: matched,
router,
page,
headerDepth,
base,
)
prefix: base,
})
: [];
}

console.warn(`${page.value.path} is missing sidebar config.`);
console.warn(`${page.path} is missing sidebar config.`);

return [];
};

export interface ResolveSidebarOptions {
config: SidebarOptions;
router: Router;
routeLocale: string;
page: PageData;
headerDepth: number;
}

/**
* Resolve sidebar items global computed
*
* It should only be resolved and provided once
*/
export const resolveSidebarItems = (
sidebarConfig: SidebarOptions,
headerDepth: number,
): ResolvedSidebarItem[] => {
const routeLocale = useRouteLocale();

export const resolveSidebarItems = ({
config,
router,
routeLocale,
page,
headerDepth,
}: ResolveSidebarOptions): ResolvedSidebarItem[] =>
// resolve sidebar items according to the config
return sidebarConfig === false
? []
: sidebarConfig === "heading"
? resolveHeadingSidebarItems(headerDepth)
: sidebarConfig === "structure"
? resolveArraySidebarItems(
sidebarData[routeLocale.value],
headerDepth,
routeLocale.value,
)
: isArray(sidebarConfig)
? resolveArraySidebarItems(sidebarConfig, headerDepth)
: isPlainObject(sidebarConfig)
? resolveMultiSidebarItems(sidebarConfig, headerDepth)
: [];
};
config === "heading"
? headersToSidebarItemChildren(page, page.headers, headerDepth)
: config === "structure"
? resolveArraySidebarItems({
config: <SidebarArrayOptions>sidebarData[routeLocale],
router,
page,
headerDepth,
prefix: routeLocale,
})
: isArray(config)
? resolveArraySidebarItems({ config, router, page, headerDepth })
: isPlainObject(config)
? resolveMultiSidebarItems({ config, router, page, headerDepth })
: [];

0 comments on commit 993e1b9

Please sign in to comment.