折腾记录|使用 Nuxt.js 重写个人主页,使用 SSR 优化 SEO ,实现一些期待已久的效果
在 22 年刚创建个人主页的时候,由于我的技术水平不够,只能用一些 wordpress typecho 这种直观的工具,后来因为换域名等等一系列的问题就被搁置了…再后来为了过备案,用图形化工具和 bootstrap 糊了一个,而如今熟练掌握 Vue 和 React 等框架之后,也到了完全重写的时候了,于是就有了这段记录。
关键词:Vue SSR,Nuxt.js
网页的开发一直在持续哇…本文章会持续跟进更新
最后链接:https://www.grtsinry43.com/
框架选择
首先,对于这种主页类的网站,单纯的 Vue React SPA(单页面应用)肯定是不行的,比如说这里我们使用 pure-admin 模板创建的一个后台系统(Vue3),对于搜索引擎来说不会等待页面完全加载和渲染,而抓到的这些内容无法分析网站的关键词和主题等,导致很难被搜索引擎排名考前,因此我们不得不从历史中汲取经验,从服务端生成静态网页,到了客户端渲染的单页面应用,又回到了服务端渲染

对于个人主页这种比较小的项目,我更喜欢使用 Vue 来完成开发,也就是其对应的 SSR 框架——Nuxt.js
快速上手
由于要使用 NuxtUI,我们便可以使用官方的创建工程的脚手架
1
| npx nuxi@latest init -t ui [项目名称]
|
创建好项目之后,我们便可以像正常写 Vue 一样来进行开发啦
前置准备工作
在代码块以及项目名称中,我们选用一个等宽而且适用于代码的字体 JetBrains Mono,于是我们可以在 assets/fonts.css 中这样进行引入
1 2 3 4 5 6 7 8 9 10 11
| @font-face { font-family: 'JetBrains Mono'; src: url('https://gcore.jsdelivr.net/gh/JetBrains/JetBrainsMono/web/woff2/JetBrainsMono-Medium.woff2') format('woff2'); font-weight: 500; font-style: normal; }
.font-jb-mono { font-family: 'JetBrains Mono', 'Courier New', Courier, 'Lucida Sans Typewriter', 'Lucida Console', 'Microsoft YaHei', 'WenQuanYi Micro Hei', monospace; }
|
注意这里要设置好 fallback 字体,因为某些 Windows 系统(雾)默认会回落到宋体,导致中文字体不堪入目
以后当我们需要使用的时候只需要挂上这个类名就好
防止掉头发
经典防止掉头发几件套:assets/global.css
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| * { margin: 0; padding: 0; box-sizing: border-box; }
a { text-decoration: none; color: inherit; }
ul { list-style: none; }
|
疑难解决方案与创新点
桌面与移动端导航栏适配
为了达到最完美的使用效果,我直接写了 NavBar 和 NavBarMobile 两个组件,通过简单的媒体查询来进行切换
1 2 3 4 5 6 7 8 9
| @media (max-width: 800px) { .nav-bar-desktop { display: none; }
.nav-bar-mobile { display: block; } }
|
对于移动段的 Navbar,我选择了可收起菜单来优化体验
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| const toggleMenu = () => { isMenuOpen.value = !isMenuOpen.value }
const toggleLocale = () => { locale.value = locale.value === 'en' ? 'zh' : 'en'; }; </script>
<template> <div class="nav-container fixed w-full bg-opacity-80 bg-blue-50 text-blue-950 dark:bg-opacity-80 dark:bg-black dark:text-white"> <UContainer class="flex flex-row items-center justify-between nav-inner"> <div class="nav-logo"> <NuxtLink :to="localePath('/')" class="font-bold">{{ $t('homePageTitle') }}</NuxtLink> </div> <!-- Toggle Button for Mobile Menu --> <UButton class="lg:hidden bg-opacity-0 dark:bg-opacity-0" @click="toggleMenu" icon="i-heroicons:bars-3-bottom-right" square color="gray" > </UButton> <!-- Theme Toggle Button --> <div class="theme-option lg:block"> <UToggle on-icon="i-heroicons-moon-20-solid" off-icon="i-heroicons-sun-20-solid" :model-value="colorMode.preference === 'dark'" @change="toggleTheme" /> </div> <!-- Icons Container --> <div class="actions-container hidden lg:grid"> <Icon class="language-toggle-icon hover:text-blue-400 dark:hover:text-blue-600" name="i-heroicons-language" @click="toggleLocale"/> <Icon class="rss-icon hover:text-blue-400 dark:hover:text-blue-600" name="i-heroicons-rss"/> <a href="https://github.com/grtsinry43/home-web" target="_blank"> <Icon class="github-icon hover:text-blue-400 dark:hover:text-blue-600" name="i-grommet-icons:github"/> </a> </div> </UContainer>
<!-- Mobile Navigation Menu --> <div v-show="isMenuOpen" class="nav-extend-container flex flex-col items-center bg-blue-50 bg-opacity-85 dark:bg-black dark:bg-opacity-80 backdrop-blur-lg"> 这里就是菜单项目啦 </div> </div> </template>
|
深浅色模式的极不优雅解决方案
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| import {onMounted} from "vue"; const colorMode = useColorMode();
const toggleTheme = () => { if (colorMode.preference === 'system') { colorMode.preference = colorMode.value === 'dark' ? 'light' : 'dark'; buttonState.value = colorMode.preference === 'dark'; } else { colorMode.preference = colorMode.preference === 'dark' ? 'light' : 'dark'; buttonState.value = colorMode.preference === 'dark'; } };
const buttonState = ref(false);
onMounted(() => { buttonState.value = colorMode.value === 'dark'; })
|
这里深色模式的实现有点太不优雅了,我发现 NuxtUI 官网确实有一个跟随主题的开关,但是自己实现起来就是很奇怪,对于输出的 colorMode 有两个用的上的属性,一个是 preference 对应偏好主题(light dark system),一个是 value 对应当前主题(light dark),由于偏好能被保存下来,于是选择在切换按钮时改变 preference 的对应的值
当组件被挂载(onMounted),首先根据 value 设置初始的状态,当点击切换时,对于当前是否偏好系统要采取不同的方式来切换,不知道大佬们有没有什么好办法,或者过几天我再看看 Nuxt 源码
条评论