docs:更新文档

This commit is contained in:
张益铭
2021-03-01 15:06:11 +08:00
parent 1542135ab0
commit 9064b372e8
5835 changed files with 904126 additions and 161722 deletions

View File

@@ -0,0 +1,4 @@
import { Ref } from 'vue';
import { SiteData } from '../../../../types/shared';
import { Route } from '../router';
export declare function useUpdateHead(route: Route, siteDataByRouteRef: Ref<SiteData>): void;

View File

@@ -0,0 +1,57 @@
import { watchEffect } from 'vue';
export function useUpdateHead(route, siteDataByRouteRef) {
const metaTags = Array.from(document.querySelectorAll('meta'));
let isFirstUpdate = true;
const updateHeadTags = (newTags) => {
if (process.env.NODE_ENV === 'production' && isFirstUpdate) {
// in production, the initial meta tags are already pre-rendered so we
// skip the first update.
isFirstUpdate = false;
return;
}
metaTags.forEach((el) => document.head.removeChild(el));
metaTags.length = 0;
if (newTags && newTags.length) {
newTags.forEach((headConfig) => {
const el = createHeadElement(headConfig);
document.head.appendChild(el);
metaTags.push(el);
});
}
};
watchEffect(() => {
const pageData = route.data;
const siteData = siteDataByRouteRef.value;
const pageTitle = pageData && pageData.title;
document.title = (pageTitle ? pageTitle + ` | ` : ``) + siteData.title;
updateHeadTags([
['meta', { charset: 'utf-8' }],
[
'meta',
{
name: 'viewport',
content: 'width=device-width,initial-scale=1'
}
],
[
'meta',
{
name: 'description',
content: siteData.description
}
],
...siteData.head,
...((pageData && pageData.frontmatter.head) || [])
]);
});
}
function createHeadElement([tag, attrs, innerHTML]) {
const el = document.createElement(tag);
for (const key in attrs) {
el.setAttribute(key, attrs[key]);
}
if (innerHTML) {
el.innerHTML = innerHTML;
}
return el;
}

View File

@@ -0,0 +1 @@
export declare function usePrefetch(): void;

View File

@@ -0,0 +1,88 @@
// Customized pre-fetch for page chunks based on
// https://github.com/GoogleChromeLabs/quicklink
import { onMounted, onUnmounted, onUpdated } from 'vue';
import { inBrowser, pathToFile } from '../utils';
const hasFetched = new Set();
const createLink = () => document.createElement('link');
const viaDOM = (url) => {
const link = createLink();
link.rel = `prefetch`;
link.href = url;
document.head.appendChild(link);
};
const viaXHR = (url) => {
const req = new XMLHttpRequest();
req.open('GET', url, (req.withCredentials = true));
req.send();
};
let link;
const doFetch = inBrowser &&
(link = createLink()) &&
link.relList &&
link.relList.supports &&
link.relList.supports('prefetch')
? viaDOM
: viaXHR;
export function usePrefetch() {
if (!inBrowser) {
return;
}
if (!window.IntersectionObserver) {
return;
}
let conn;
if ((conn = navigator.connection) &&
(conn.saveData || /2g/.test(conn.effectiveType))) {
// Don't prefetch if using 2G or if Save-Data is enabled.
return;
}
const rIC = window.requestIdleCallback || setTimeout;
let observer = null;
const observeLinks = () => {
if (observer) {
observer.disconnect();
}
observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
const link = entry.target;
observer.unobserve(link);
const { pathname } = link;
if (!hasFetched.has(pathname)) {
hasFetched.add(pathname);
const pageChunkPath = pathToFile(pathname);
doFetch(pageChunkPath);
}
}
});
});
rIC(() => {
document.querySelectorAll('.vitepress-content a').forEach((link) => {
const { target, hostname, pathname } = link;
if (
// only prefetch same page navigation, since a new page will load
// the lean js chunk instead.
target !== `_blank` &&
// only prefetch inbound links
hostname === location.hostname) {
if (pathname !== location.pathname) {
observer.observe(link);
}
else {
// No need to prefetch chunk for the current page, but also mark
// it as already fetched. This is because the initial page uses its
// lean chunk, and if we don't mark it, navigation to another page
// with a link back to the first page will fetch its full chunk
// which isn't needed.
hasFetched.add(pathname);
}
}
});
});
};
onMounted(observeLinks);
onUpdated(observeLinks);
onUnmounted(() => {
observer && observer.disconnect();
});
}

View File

@@ -0,0 +1,5 @@
import { Ref } from 'vue';
import { SiteData } from '../../../../types/shared';
export declare type SiteDataRef<T = any> = Ref<SiteData<T>>;
export declare const siteDataRef: Ref<SiteData>;
export declare function useSiteData<T = any>(): Ref<SiteData<T>>;

View File

@@ -0,0 +1,13 @@
import serialized from '@siteData';
import { ref, readonly } from 'vue';
const parse = (data) => readonly(JSON.parse(data));
export const siteDataRef = ref(parse(serialized));
export function useSiteData() {
return siteDataRef;
}
// hmr
if (import.meta.hot) {
import.meta.hot.acceptDeps('/@siteData', (m) => {
siteDataRef.value = parse(m.default);
});
}

View File

@@ -0,0 +1,9 @@
export declare function useSiteDataByRoute(route?: import("../router").Route): import("vue").ComputedRef<{
themeConfig: any;
locales: {};
lang: string;
title: string;
description: string;
base: string;
head: import("../../../../types/shared").HeadConfig[];
}>;

View File

@@ -0,0 +1,9 @@
import { computed } from 'vue';
import { resolveSiteDataByRoute } from '/@shared/config';
import { siteDataRef } from './siteData';
import { useRoute } from '../router';
export function useSiteDataByRoute(route = useRoute()) {
return computed(() => {
return resolveSiteDataByRoute(siteDataRef.value, route.path);
});
}