data.js 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. import { shallowRef, readonly, computed, inject } from 'vue';
  2. import serializedSiteData from '@siteData';
  3. import { resolveSiteDataByRoute } from '../shared';
  4. import { withBase } from './utils';
  5. export const dataSymbol = Symbol();
  6. export const siteDataRef = shallowRef(parse(serializedSiteData));
  7. function parse(data) {
  8. const parsed = JSON.parse(data);
  9. return (import.meta.env.DEV ? readonly(parsed) : parsed);
  10. }
  11. // hmr
  12. if (import.meta.hot) {
  13. import.meta.hot.accept('/@siteData', (m) => {
  14. siteDataRef.value = parse(m.default);
  15. });
  16. }
  17. // per-app data
  18. export function initData(route) {
  19. const site = computed(() => resolveSiteDataByRoute(siteDataRef.value, route.path));
  20. return {
  21. site,
  22. theme: computed(() => site.value.themeConfig),
  23. page: computed(() => route.data),
  24. frontmatter: computed(() => route.data.frontmatter),
  25. lang: computed(() => site.value.lang),
  26. localePath: computed(() => {
  27. const { langs, lang } = site.value;
  28. const path = Object.keys(langs).find((langPath) => langs[langPath].lang === lang);
  29. return withBase(path || '/');
  30. }),
  31. title: computed(() => {
  32. return route.data.title
  33. ? route.data.title + ' | ' + site.value.title
  34. : site.value.title;
  35. }),
  36. description: computed(() => {
  37. return route.data.description || site.value.description;
  38. })
  39. };
  40. }
  41. export function useData() {
  42. const data = inject(dataSymbol);
  43. if (!data) {
  44. throw new Error('vitepress data not properly injected in app');
  45. }
  46. return data;
  47. }