Skip to content

开发技巧

介绍 Teek 开发路程的一些技巧。

规范

Teek 建议在进行项目开发时,一个文件的代码行数推荐 300 行以下,最好不超过 500 行,禁止超过 1000 行。

如果超过 300+ 行,应该考虑下是否可以拆分为多个文件,这是一个良好的 结构化思维和分治思维

提示

Teek 建议您在开发前先思考有哪些模块,然后分别创建模块文件,而不是先在一个文件写完,再拆分。

举个例子:

代码合在一个文件:

html
<div><divclass="header"><imgsrc="logo.png"/><h1>网站名称</h1></div><divclass="main-content"><divclass="banner"><ul><li><imgsrc="banner1.png"/></li><!-- 省略n行代码 --></ul></div><divclass="post-list"><!-- 省略n行代码 --></div><!-- 省略n行代码 --></div></div>

将代码进行模块化,根据功能/布局/逻辑等进行拆分:

html
<div><header/><main><Banner/><PostList/><Card/><AboutMe/></main><footer/></div>

假设您没有参与过该项目开发,现在由您来开始开发 PostList模块的功能,我相信您更喜欢第二种,因为它已经明确的在向您挥手。

SSR 兼容

在 VitePress 主题开发时,请考虑 SSR 兼容性。否则在构建项目时,报错:window/document is not defined

关于 SSR 兼容性,VitePress 官方提供了 SSR 兼容性的文档可以参考,文档里介绍了几个方式如何兼容 SSR。

但是 Teek 在这里提供一个 VitePress 官方没有 直接说明的一种方式,这也是 Teek 兼容 SSR 的方式,即:

在任何访问浏览器或调用 DOM API 的代码前加上 SSR 环境校验

首先自定义一个 SSR 环境检验变量:

ts
constisClient=typeofwindow !=="undefined"&&typeofdocument !=="undefined";

然后在使用 DOM API 之前加上这个校验,这样就防止构建时报错:

vue
<scriptsetuplang="ts">import{isClient } from"vitepress-theme-teek";constinit=() =>{if(!isClient) return;constxxDom=document.querySelector(".xx");};init();</script><template></template>

如果您的代码在 Vue 组件的 beforeMountmounted钩子中执行,则无需考虑 SSR,Vue 已经处理了。

利用对象/数组减少 HTML 编写

对象形式

templateifif-else判断

vue
<scriptsetuplang="ts">import{A,B,C,D } from"./components";import{useData } from"vitepress";const{theme} =useData();constprovider=theme.value.provider;</script><template><templatev-if="provider ==='a'"name="a"><A/></template><templatev-else-if="provider ==='b'"name="b"><B/></template><templatev-else-if="provider ==='d'"name="c"><C/></template><templatev-else-if="provider ==='d'"name="d"><D/></template></template>

可以将其转为对象:

vue
<scriptsetuplang="ts">import{A,B,C,D } from"./components";import{useData } from"vitepress";const{theme} =useData();constprovider=theme.value.provider;constproviderMap={a:{el:A,props:{name:"a"} },b:{el:B,props:{name:"b"} },c:{el:C,props:{name:"c"} },d:{el:D,props:{name:"d"} },};</script><template><componentv-if="provider":is="providerMap[provider]?.el"v-bind="providerMap[provider]?.props"/></template>

可以在组件 Layout的评论区相关代码或者 HomeBanner查看具体使用。

数组形式

template编写类似的重复 HTML

vue
<scriptsetuplang="ts"></script><template><div><div><spanclass="title">A</span><spanclass="desc">测试 A</span></div><div><aclass="link"href="/b">B</a><spanclass="desc">测试 B</span></div><div><imgclass="link"src="/c.png"/><spanclass="desc">测试 C</span></div></div></template>

可以将其转为数组:

vue
<scriptsetuplang="ts">constlist=[{title:"A",desc:"测试 A",className:"title"},{title:"B",desc:"测试 B",isLink:true,className:"link",link:"/b"},{desc:"测试 C",isImg:true,className:"img",link:"/c.png"},];</script><template><div><divv-for="item in list":key="item.title"><av-if="item.isLink":class="item.className":href="item.link">{{item.title }}</a><imgv-else-if="item.isImg":class="item.className":src="item.link"/><spanv-else:class="item.className">{{item.title }}</span><spanclass="desc">{{item.desc }}</span></div></div></template>

仅限于重复度接近 90% 以上或者简单的 HTML,否则不建议使用数组 + for循环,可读性会变差。

可以在组件 ArticleInfo查看具体使用。

配置项支持方式

config 配置

如果配置项仅支持在 .vitepress/config.mts配置:

在组件里这样使用:

vue
<scriptsetuplang="ts">import{useData } from"vitepress";const{theme} =useData();const{enabled=true,name="",obj={},arr=[] } ={...theme.xxx };</script><template></template>

这样避免了获取 theme.xxx里的属性时报 undefined(没配置 xxx),同时如果 theme.xxx里的某些属性没有配置,则赋予默认值。

config 和 frontmatter 配置

配置项同时支持在 .vitepress/config.mts和 Markdown 的 frontmatter配置,当两种都配置,则以 frontmatter为准。

在组件里这样使用:

vue
<scriptsetuplang="ts">import{computed } from"vue";import{useData } from"vitepress";const{theme,frontmatter} =useData();constthemeConfig=computed(() =>({enabled:true,name:"",obj:{},arr:[],...theme.xxx,...frontmatter.value.xxx,...frontmatter.value.tk.xxx,}));console.log(themeConfig.value.xxx);</script><template></template>

frontmatter.value.tk.xxx是在首页 index.md配置 frontmatter时,额外添加了 tk,这是为了避免与 VitePress 自带配置的命名冲突。

支持 frontmatter配置时,一定要用 computed监听 frontmatter变化,因为不同 Markdown 的 frontmatter有可能不一样,如果没有监听 frontmatter变化,会导致切换 Markdown 文章后,新文章的配置不会重新生效。

如:

ts
import{defineTeekConfig } from"vitepress-theme-teek/config";constteekConfig=defineTeekConfig({comment:{provider:"giscus",options:{repo:"your repo",repoId:"your repoId",category:"your category",categoryId:"your categoryId",}};});
yaml
---tk:comment:provider:"giscus"options:repo:"your repo"repoId:"your repoId"category:"your category"categoryId:"your categoryId"---
yaml
---comment:provider:"giscus"options:repo:"your repo"repoId:"your repoId"category:"your category"categoryId:"your categoryId"---
最近更新