一个博客文档

  • 深色模式切换
  • Markdown 渲染
  • 图片渲染
  • 社交分享卡片
  • 页面过渡效果
  • markdown 中嵌套 embed
  • 访问统计
  • 评论系统
  • 阅读时间估算
  • RSS 订阅
  • SEO 优化
  • 图片懒加载

Nuxt 配置

都是一些基础的配置,可以参考 Nuxt 文档

KeepAlive

刚开始其实照文档配置了,但是没有生效。
后来才想起来,配置的页面设置了不同的 layout ,其中有个设置了 layout ,另一个设置的 false 。在 Nuxt 中,如果两个页面使用了不同的 layout,即使设置了 KeepAlive 也不会生效。

KeepAlive 只能保持同一个 layout 下的页面状态

这个文档中没有提到,所以需要注意。

深色模式切换

其实就是使用的 nuxt-color-mode 库,使用文档见 nuxt-color-mode 文档

nuxt.config.ts 中配置:

nuxt.config.ts
TYPESCRIPT
          export default defineNuxtConfig({
  colorMode: {
    classSuffix: '',
    fallback: 'dark',
    // 默认使用系统主题,可以从 localstorage 中查看到
    preference: 'system',
  },
})

        

有一点需要注意的是,这里初始设置了跟随系统主题,可以在 localstorage 中查看到, nuxt-color-mode 的 value 值为 system

而在系统中主动点击切换颜色模式后,就是将 nuxt-color-mode 的 value 值为 dark 或者 light,也是可以在 localstorage 中查看到的。所以当改变了这个值之后,网站的颜色就是设置的那个状态了,而要想继续跟随系统主题,还是需要将 color-mode 的值设置为 system

而系统中设置的背景是 linear-gradient渐变背景的渲染性能问题导致,当快速滚动时,浏览器需要不断重新计算和渲染复杂的渐变背景,导致出现白色闪烁。

所以,这里将渐变背景放在单独的伪元素中,然后设置 pointer-events: none,这样就不会影响页面的滚动和交互。

而在 ios 上,向下滚动的时候,底部的 bar 会消失。快速向下滚动的时候,之前设置的 position: fixed; top: 0; left: 0; right: 0; bottom: 0; 并不会影响到之前的底部 bar,所以需要设置 height: 100vh; 来覆盖一下。

Markdown 渲染

markdown 渲染使用的是 @nuxt/content 库,使用文档见 nuxt-content 文档

代码块添加拷贝按钮

图片渲染

图片存储

图片存储在 public/content-images 目录下,图片会被自动上传到云端。

          public/
  content-images/
    post/
      2023/
        1-第一篇文章/
          image1.jpg
          image2.png
        2-第二篇文章/
          image1.jpg
      2024/
        1-第一篇文章/
          image1.jpg

        
TEXT

图片引用

在 Vscode 中,点击需要的图片,右键,选择“复制相对路径”,然后在到 Markdown 文件中粘贴使用。

图片放大查看

https://content.nuxt.com/components/prose#proseimg

在 Markdown 中使用 <ProseImg> 组件(/app/components/content/ProseImg.vue )来渲染图片。只需要创建组件,@nuxt/content 会自动识别。

然后给其添加自定义类名,preview 类名用于图片放大查看。

社交分享卡片

og:image 是社交分享卡片,在 app/pages/post/[...slug].vue 中定义。 使用的是 nuxt-og-image 库,使用文档见 nuxt-og-image 文档

示例:

          defineOgImageComponent('NuxtSeo', {
  title: 'Hello OG Image 👋',
  description: 'Look what at me in dark mode',
  theme: '#ff0000',
  colorMode: 'dark',
})

        
TYPESCRIPT

自定义:

          defineOgImageComponent('MarkdownOG', {
  title: 'Is this thing on?',
  description: 'Look what at me',
  date: '2024-12-03',
})

        
TYPESCRIPT

支持中文,需要在 nuxt.config.ts 中配置字体:

          export default defineNuxtConfig({
  ogImage: {
    fonts: [
      // 添加支持中文的字体
      'serif', 
      'Noto Serif SC', 
      'JetBrains Mono',
    ],
  },  
})

        
TYPESCRIPT

最后配置好了,可以在一些验证网站上试一下,比如: https://threadcreator.com/tools/twitter-card-validator 或者 https://tweethunter.io/tweetpik/twitter-card-validator

页面过渡效果

其实跟 vue 中添加的页面过渡效果一样的方式,不过是可以在 nuxt.config.ts 中配置,也可以在单独的页面中通过 definePageMeta 配置。

需要注意的是,页面 layout 改变的过渡效果是 layoutTransition,而页面内容改变的过渡效果是 pageTransition。 所以在 nuxt.config.ts 需要同时配置这两个属性。

          export default defineNuxtConfig({
  app: {
    layoutTransition: { name: 'page', mode: 'out-in' },
    pageTransition: { name: 'page', mode: 'out-in' },
  },
})

        
TYPESCRIPT

markdown 中嵌套(embed) codepen 代码

可以直接使用 iframe 标签,也可以使用组件 CodepenEmbed(当然是在 components/content/ 目录下定义了组件)。

比如:

更新:

@nuxt/content v3.0.0

    1. 语法大变更
    1. sqlite 数据库,获取到数据,后续不用再调接口了
    1. 基础的数据结构没变,比如 toc 还是一样的