做Nuxt3这两个月,我整理总结出这套模板...

2,722 阅读7分钟

v2-190e5e8261bdfb1def79988f47a7538b_r.png 该模板项目更适用营销类网站,营销类网页偏向于前端效果的展示且很注重SEO,Vue技术栈的入手Nuxt3很轻松,nuxt写起来蛮舒服但不得不说槽点也蛮多。

仓库地址:github.com/zuowendong/…

预览地址:zuowendong.github.io/nuxt3templa…

模板中集成了:

  1. tailwindcss
  2. daisyui,基于tailwindcss的UI组件库
  3. aos,页面滚动动画
  4. postcss-px-to-viewport-tailwind,支持tailwindcss不同断点转vw
  5. vue-i18n,国际化
  6. font-split,字体分包

tailwind css

对于一个人项目,那不考虑协作方面顾虑,蛮推荐 tailwind css 快速开发,不用考虑class名称真的太爽,配合上vscode插件 Tailwind CSS IntelliSense 和 Tailwind CSS Highlight 上手门槛也不算高。而且使用 tailwind css 的断点做响应式适配也丝滑。

aos

AOS.js 是一款 JS 动画库,可以轻松地为网页元素添加各种滚动动画效果。它可以检测元素在视窗中的位置,并在元素出现时为其添加相应的动画类。

将 aos 添加 nuxt plugin 作为插件便于使用。

// plugins/aos.client.ts

import AOS from "aos";
import { defineNuxtPlugin } from "#app";

export default defineNuxtPlugin(() => {
  return {
    provide: {
      aos: () => AOS,
    },
  };
});

同时需要在 nuxt.config 中配置 plugins 和 css,这样 aos 才会生效。

// nuxt.config.ts

export default defineNuxtConfig({
	// ...
  css: [
    "~/assets/css/global.css",
    "aos/dist/aos.css"
  ],
  plugins: ["~/plugins/aos.client.ts"]
})

在你需要的页面上使用 aos 即可,例如在 app.vue 中全局使用。

// app.vue

import { onMounted } from "vue";
import { useNuxtApp } from "#app";

const { $aos } = useNuxtApp();
onMounted(() => {
  $aos().init({});
});

最后在任何一个页面的元素上都可以使用 aos,例如在首页的 box 上添加一个从下往上显示的动画。

// pages/index.vue

<section
  ref="sectionRef"
  class="w-[100px] h-[100px] md:w-[200px] md:h-[200px] xl:w-[300px] xl:h-[300px] text-[16px] md:text-[20px] xl:text-[24px] text-blue-500 md:text-red-500 xl:text-green-600 text-center leading-[100px] md:leading-[200px] xl:leading-[300px] border border-[#333]"
  data-aos="fade-up"
  data-aos-offset="0"
  data-aos-duration="1500"
  data-aos-delay="300"
  data-aos-once="true"
>
  {{ sectionWidth }}
</section>

postcss-px-to-viewport-tailwind

一般客户建站都会要求适配桌面端和移动端。

Tailwind css 的断点支持根据不同的屏幕尺寸应用不同的样式。默认情况下是使用 min-width 媒体查询来创建断点,这意味着样式会在指定的屏幕宽度及以上生效。

一般UI设计师给出的效果图尺寸中,移动端可能是 375 或者 750,桌面端的设计稿是 1920,平板的尺寸是介于 768 - 1280,当然具体数值由UI和项目团队内部决定。

针对这样不同的设计稿尺寸,想要同一份代码适配,tailwind css 的断点是能够实现的,但是会导致庞大的工作量,还需要针对不同的设备尺寸出具不同的设计稿。例如,tailwind css 默认的断点配置是:

screens: {
  sm: "640px",
  md: "768px",
  lg: "1024px",
  xl: "1280px",
  "2xl": "1536px",
  laptop: "1440px",
  desktop: "1920px",
}

如果设计稿是基于 1920 的,在设备尺寸为 1280 时,此时样式就不合适了,按照纯 tailwind css 断点设置就需要不同断点设置不同样式,这样要求的设计稿需要很完善,我们需要写的代码量也激增。

postcss-px-to-viewport-tailwind 插件可以很完美的解决上述问题,通过匹配不同的tailwind css 断点对应不同的设计稿尺寸,将匹配上的设备尺寸区间内转换成 vw,可以很好的解决适配问题。比如,认定桌面端尺寸范围是 1280 - 1920,这个范围内的样式都是按照 1920 设计稿实现,通过 vw 适配方案就能很好实现。认定设备尺寸小于 768 的都是移动端,按照 375 设计稿实现,同样是vw 方案,通过 postcss-px-to-viewport-tailwind 设定 768 这个尺寸断点下都按照 375 设计稿宽度转换即可。

zuowendong.github.io/nuxt3templa… 首页给出不同设备尺寸下的展示效果对比。

使用

// nuxt.config.ts

postcss: {
  plugins: {
    tailwindcss: {},
    autoprefixer: {
      overrideBrowserslist: ["last 5 version", ">1%", "ie >=8"],
    },
    "postcss-px-to-viewport-tailwind": {
      unitToConvert: "px", // 要转化的单位
      viewportWidth: 375, // 默认(移动端)设计稿尺寸
      viewportWidthPaid: 750, // 平板设计稿尺寸
      viewportWidthPc: 1920,  // pc设计稿尺寸
      width2Tailwind: {
        viewportWidthPaid: "md",  // 平板设计稿对应的 tailwind css 断点 md
        viewportWidthPc: "xl", // 设备尺寸在 xl 以上都按照 pc 设计稿实现
      },
      unitPrecision: 6, // 转换后的精度,即小数点位数
      propList: ["*"], // 指定转换的css属性的单位,*代表全部css属性的单位都进行转换
      viewportUnit: "vw", // 指定需要转换成的视窗单位,默认vw
      fontViewportUnit: "vw", // 指定字体需要转换成的视窗单位,默认vw
      selectorBlackList: [], // 指定不转换为视窗单位的类名,例如van-(vantUI组件),
      minPixelValue: 1, // 默认值1,小于或等于1px则不进行转换
      mediaQuery: true, // 是否在媒体查询的css代码中也进行转换,默认false
      replace: true, // 是否转换后直接更换属性值
      exclude: [/node_modules/], // 设置忽略文件,用正则做目录名匹配,最好不要排除node_modules 文件,排除后在项目中会发现字体不能跟随页面放大
      landscape: false, // 是否处理横屏情况
    },
  },
},

注意,其中 width2Tailwind 配置项中 key 需要和上面定义的不同 viewportWidth 的 key 一致。除了默认设计稿宽度 viewportWidth 这个 key 不可修改,像viewportWidthPaid 和 viewportWidthPc 都是自定义的。例如,你也可以如下这样设置:

{
  viewportWidth: 320,
  viewportWidthSM: 640,
  viewportWidthMD: 750,
  viewportWidthLG: 1024,
  viewportWidthXL: 1280,
  viewportWidth2xl: 1440,
  width2Tailwind: {
    viewportWidthSM: 'sm',
    viewportWidthMD: 'md',
    viewportWidthLG: 'lg',
    viewportWidthXl: 'xl',
    viewportWidth2xl: '2xl'	
  } 
}

vue-i18n

vue-i18n 是一个 Vue.js 的国际化插件,可以轻松开发多语言应用切换语言环境。

在 plugins 中新建 i18n.ts

// plugins/i18n.ts

import { createI18n } from "vue-i18n";
import { defineNuxtPlugin } from "#app";

import en from "~/locales/en.json";
import zh from "~/locales/zh.json";

export let t: (v: string) => string;

export default defineNuxtPlugin(({ vueApp }) => {
  const i18n = createI18n({
    legacy: false,
    globalInjection: true,
    locale: "zh",
    messages: {
      en,
      zh,
    },
  });

  t = i18n.global.t;
  vueApp.use(i18n);
});

在 nuxt.config 中添加上

plugins: ["~/plugins/i18n.ts"]

字体分包

网站资源中占比最大的就是图片和字体文件,其中自定义字体尤其中文字体在首屏加载中耗时最长,是必须要优化的一点。

查询字体优化方案那最常见的应该就是字蛛 font-spider。font-spider 会解析你指定的 html 并统计其中的文字,最后对字库进行类似 “tree shaking” 的操作,只保留项目中出现的文字。对于Nuxt 项目并没有找到很好的实现示例,首先 ssr 中并不会直接显示 html 文件,它的 README 中也说明了不支持 js 动态插入的元素与样式。

另一种方案就是字体分包 font-spilt,大体积的font文件会在网络传输中耗时很久,那就将大文件分割成诸多小文件,这样分片操作可以有效减少请求耗时。

字体分包操作我集成在下面这个项目中可以作为工具使用,只用将你需要的分包的字体文件放在 font 文件夹里,在入口文件 index.js 中 指定你的目标字体路径 FontPath,执行 yarn dev 会在根目录 dist 中输出分包结果。

github.com/zuowendong/…

使用

在 nuxt3 中使用分包字体,最终生成的分包字体文件里会有一个 result.css,只需要将所有的字体文件和这个css放入assets 中,再在nuxt.config的css 配置里引入这个 css 即可。

具体实现可以查看项目仓库:github.com/zuowendong/…

最后

欢迎关注本人原创微信公众号【前端一起学】,一起学习一起交流~