Nuxt+Vue3+TS+Vite入门教程

服务器 0

介绍

什么是Nuxt3

Nuxt3是一个基于Vue.js的应用框架,它提供了一些默认的配置和约定,使得开发者可以更快速地构建出高质量的Vue.js应用程序。Nuxt3是Nuxt.js的下一代版本,它采用了全新的架构和设计,提供了更好的性能和可扩展性。

Nuxt3 的优势

1、更快的启动和渲染速度
2、更好的性能和可扩展性
3、更灵活的配置和插件系统
4、更好的开发体验和文档支持

Nuxt3 的生态

Nuxt3的生态非常丰富,包括了许多插件、模块、组件库、工具等等。可以在Nuxt3官方网站的生态页面(https://nuxt.com/modules)上找到相关的Nuxt3生态。

安装

安装 Nuxt3

在安装Nuxt3之前,你需要保证你的node.js大于16.10.0 或者最新版本

创建一个nuxt项目

npx nuxi init <project-name>

切换到刚创建的项目根目录

cd <project-name>

下载相关依赖

npm install

基础

Nuxt3 的目录结构

  • assets/: 存放静态资源文件,如样式、图片、字体等。
  • components/: 存放组件文件,可以在页面中引用。
  • layouts/: 存放布局文件,可以在页面中引用。
  • middleware/: 存放中间件文件,可以在路由中使用。
  • composables/: 存放可重用的逻辑代码,可以在页面、组件和插件中使用。
  • pages/: 存放页面文件,每个文件对应一个路由。
  • plugins/: 存放插件文件,可以在应用程序中使用。
  • static/: 存放静态文件,如 robots.txt、favicon.ico 等。
  • store/: 存放 Vuex store 文件。
  • server/: 存放服务器端代码,包括中间件、API、插件等等。
  • utils/: 存放工具函数文件。
  • nuxt.config.ts: Nuxt3 的配置文件,使用 TypeScript 编写。
  • package.json: 项目的依赖和脚本配置文件。
  • tsconfig.json: TypeScript 的配置文件。

页面和路由

Nuxt3的页面和路由是基于文件系统的路由系统,它允许开发者通过在pages目录下创建.vue文件来定义页面和路由。每个.vue文件对应一个路由,Nuxt3会根据文件名自动生成路由路径。例如,pages/index.vue对应的路由路径为/,pages/about.vue对应的路由路径为/about。此外,Nuxt3还支持动态路由和嵌套路由,可以通过在文件名中使用[]和_来定义动态路由和嵌套路由。例如,pages/posts/[id].vue对应的动态路由路径为/posts/:id,pages/posts/_slug/comments.vue对应的嵌套路由路径为/posts/:slug/comments。

动态路由
-| pages/---| index.vue---| users-[group]/-----| [id].vue
// 你可以通过使用$route.params来获取传递的参数<template>  <p>{{ $route.params.group }} - {{ $route.params.id }}</p></template>

如果要使用组合 API 访问路由,有一个全局函数允许您像在选项 API 中一样访问路由。

<script setup>const route = useRoute()if (route.params.group === 'admins' && !route.params.id) {  console.log('Warning! Make sure user is authenticated!')}</script>

如果希望参数是可选的,则必须将其括在双方括号中 - 例如,或者将同时匹配和. ~/pages/[[slug]]/index.vue ~/pages/[[slug]].vue

嵌套路由

文件名和目录同名 nuxt3 就会自动给你制造成嵌套路由,父组件中使用NuxtChild组件显示嵌套子组件内容

比如下面目录结构:-| pages/---| parent/------| child.vue---| parent.vue
// pages/parent.vue<template>  <div>    <h1>I am the parent view</h1>    <NuxtPage :foobar="123" />  </div></template>
导航

要在应用的页面之间导航,您应该使用 组件。此组件包含在Nuxt中,因此您不必像导入其他组件那样导入它。

<template>  <NuxtLink to="/">Home page</NuxtLink></template>
编程导航

Nuxt 3 允许通过实用程序方法进行编程导航。使用此实用工具方法,你将能够以编程方式在应用中导航用户。这非常适合从用户那里获取输入并在整个应用程序中动态导航它们。
在此示例中,我们有一个名为navigate()的简单方法,当用户提交搜索表单时调用该方法。

<script setup>const router = useRouter();const name = ref('');const type = ref(1);function navigate(){  return navigateTo({    path: '/search',    query: {      name: name.value,      type: type.value    }  })}</script>

布局和组件

默认布局

Nuxt提供了一个可自定义的布局框架,您可以在整个应用程序中使用,非常适合将常见的UI或代码模式提取到可重用的布局组件中。布局放置在目录中,并在使用时通过异步导入自动加载。

// ~/layouts/default.vue<template>  <div>    Some default layout shared across all pages    <slot />  </div></template>

在布局文件中,布局的内容将在中加载,而不是使用特殊的组件。

如果您使用,还需要在app.vue添加

<template>  <NuxtLayout>    some page content  </NuxtLayout></template>
使用其它自定义组件
-| layouts/---| default.vue---| custom.vue
<template>  <NuxtLayout :name="layout">    <NuxtPage />  </NuxtLayout></template><script setup>// You might choose this based on an API call or logged-in statusconst layout = "custom";</script>
动态修改布局组件
<template>  <div>    <button @click="enableCustomLayout">Update layout</button>  </div></template><script setup>function enableCustomLayout () {  setPageLayout('custom')}definePageMeta({  layout: false,});</script>

更多介绍请看

组件目录

components/目录是你放置所有 Vue 组件的地方,然后可以将它们导入到你的页面或其他组件中,Nuxt会自动导入目录中的任何组件(以及您可能正在使用的任何模块组件)

| components/--| TheHeader.vue--| TheFooter.vue
// layouts/default.vue<template>  <div>    <TheHeader />    <slot />    <TheFooter />  </div></template>
自定义目录

默认情况下,只扫描components目录进行自动导入。如果您想添加其他目录,或更改在此目录的子文件夹中扫描组件的方式,可以将其他目录添加到配置中

export default defineNuxtConfig({  components: [    { path: '~/components/special-components', prefix: 'Special' },    '~/components'  ]})
组件名称

如果嵌套目录中有如下的组件,例如:

| components/--| base/----| foo/------| Button.vue

然后,组件的名称将基于其自己的路径目录和文件名,并删除重复的段。因此,组件的名称将为:

<BaseFooButton />
动态组件

如果您想使用Vue语法,则需要使用Vue提供的API

<template>  <component :is="clickable ? MyButton : 'div'" /></template><script setup>const MyButton = resolveComponent('MyButton')</script>
动态导入(延迟加载组件)

要动态导入组件(也称为延迟加载组件),您只需要将前缀lazy添加到组件的名称即可。

// layouts/default.vue<template>  <div>    <TheHeader />    <slot />    <LazyTheFooter />  </div></template>
<template>  <div>    <h1>Mountains</h1>    <LazyMountainsList v-if="show" />    <button v-if="!show" @click="show = true">Show List</button>  </div></template><script>export default {  data() {    return {      show: false    }  }}</script>
显式导入组件

您还可以从中显式导入组件,如果您想要或需要绕过Nuxt的自动导入功能。

<template>  <div>    <h1>Mountains</h1>    <LazyMountainsList v-if="show" />    <button v-if="!show" @click="show = true">Show List</button>    <NuxtLink to="/">Home</NuxtLink>  </div></template><script setup>  import { NuxtLink, LazyMountainsList } from '#components'  const show = ref(false)</script>

更多内容请移步

数据获取和渲染

获取数据

Nuxt 提供了四个API useFetch, useLazyFetch, useAsyncData 和 useLazyAsyncData 来处理数据请求.

useFetch

在您的页面、组件和插件中,您可以使用 useFetch 从任何 URL 通用地获取数据。这个API是由useAsyncData和$fetch组成的。它基于URL和fetch选项自动生成密钥,根据服务器路由提供请求URL的类型提示,并推断API响应类型。

<script setup>const { data: count } = await useFetch('/api/count')</script><template>  Page visits: {{ count }}</template>
useLazyFetch

此可组合对象的行为与使用带有 lazy: true 选项集的 Fetch 相同。换句话说,异步函数不会阻止导航。这意味着您将需要处理数据为 null(或您在自定义默认工厂函数中提供的任何值)的情况。

<template>  <!-- you will need to handle a loading state -->  <div v-if="pending">    Loading ...  </div>  <div v-else>    <div v-for="post in posts">      <!-- do something -->    </div>  </div></template><script setup>const { pending, data: posts } = useLazyFetch('/api/posts')watch(posts, (newPosts) => {  // Because posts starts out null, you will not have access  // to its contents immediately, but you can watch it.})</script>
useAsyncData

在您的页面、组件和插件中,您可以使用它来访问异步解析的数据

// server/api/count.tslet counter = 0export default defineEventHandler(() => {  counter++  return counter})
<script setup>const { data } = await useAsyncData('count', () => $fetch('/api/count'))</script><template>  Page visits: {{ data }}</template>
useLazyAsyncData

此可组合对象的行为与选项集相同。换句话说,异步函数不会阻止导航。这意味着您将需要处理数据所在的情况(或您在自定义工厂函数中提供的任何值)

<template>  <div>    {{ pending ? 'Loading' : count }}  </div></template><script setup>const { pending, data: count } = useLazyAsyncData('count', () => $fetch('/api/count'))watch(count, (newCount) => {  // Because count starts out null, you won't have access  // to its contents immediately, but you can watch it.})</script>

更多内容请移步

进阶

插件和模块
插件目录

Nuxt3的插件是用来扩展应用程序功能的,它们可以在应用程序启动之前或之后运行,并且可以访问Nuxt3的上下文对象。插件可以用来添加第三方库、设置全局变量、添加实例方法、添加Vue组件等等。插件可以在plugins目录中定义,并在nuxt.config.ts文件中配置。
Nuxt自动读取插件目录中的文件,并在创建Vue应用程序时加载它们。您可以在文件名中使用.server或.client后缀,以便仅在服务器端或客户端加载插件。

只有目录顶层的文件(或任何子目录中的索引文件)才会注册为插件。

plugins | - myPlugin.ts  // scanned | - myOtherPlugin | --- supportingFile.ts   // not scanned | --- componentToRegister.vue   // not scanned | --- index.ts  // currently scanned but deprecated
新建一个插件
export default defineNuxtPlugin(nuxtApp => {  // Doing something with nuxtApp})

更多内容请移步

模块目录

Nuxt扫描modules/目录并在启动之前加载它们。在构建应用程序时,您开发的任何本地模块都可以放置在这里。
自动注册的文件模式为:

modules/*/index.tsmodules/*.ts

您不需要将这些本地模块单独添加到nuxt.config.ts中。

// modules/hello/index.ts// `nuxt/kit` is a helper subpath import you can use when defining local modules// that means you do not need to add `@nuxt/kit` to your project's dependenciesimport { createResolver, defineNuxtModule, addServerHandler } from 'nuxt/kit'export default defineNuxtModule({  meta: {    name: 'hello'  },  setup () {    const { resolve } = createResolver(import.meta.url)    // Add an API route    addServerHandler({      route: '/api/hello',      handler: resolve('./runtime/api-route')    })  }})
export default defineEventHandler(() => {  return { hello: 'world' }}

当启动Nuxt时,hello模块将被注册,/api/hello路由将可用。

中间件和拦截器
中间件

Nuxt的中间件是一种可定制的路由中间件框架,可以在整个应用程序中使用。它非常适合在导航到特定路由之前提取要运行的代码。中间件可以用于验证用户身份、检查权限、预取数据等。在Nuxt中,中间件可以在middleware/目录中定义,并在nuxt.config.ts文件中配置。中间件可以是全局的,也可以是特定页面的。全局中间件将在每个页面上运行,而特定页面的中间件将仅在该页面上运行。在中间件中,您可以访问上下文对象,例如context.app、context.store和context.route。

通过中间件封装的一个简单的拦截器案例:

import { api } from '~/api/api';import { userStore } from '~/stores/user';export default defineNuxtRouteMiddleware((to, from) => {    const token = useCookie('token')    const store = userStore();    if (typeof (token.value) == 'undefined') {        return navigateTo('/')    }    api.user.getInfo().then(info => {        if (!info.success) {            store.$patch({                isLogin: !store.isLogin            })            store.$patch({                isLogin: false            })            token.value = undefined            store.$patch({                showLogin: true            })            navigateTo('/')        }    })})

更多内容请移步

Hooks和服务端
composables(Hooks)

Nuxt的composables(Hooks)是一种可重用的逻辑代码块,可以在不同的页面、组件和插件中使用。它们是基于Vue 3的Composition API构建的,可以让您更轻松地管理和共享状态、副作用和计算逻辑。Nuxt提供了一些内置的composables,例如useAsyncData、useFetch和useRoute,您也可以创建自己的composables。使用composables可以使代码更加模块化和可维护,同时也可以提高代码的可重用性和可测试性。

在服务端渲染方面,Nuxt的composables可以在服务器端和客户端上运行,因为它们是基于Vue 3的Composition API构建的。但是,需要注意的是,某些composables可能会在服务器端和客户端上产生不同的行为,因此您需要仔细测试您的代码以确保它们在两个环境中都能正常工作。另外,由于服务器端渲染的特殊性,某些composables可能无法在服务器端上运行,因此您需要仔细阅读Nuxt的文档以了解哪些composables适用于服务器端渲染。

总之,Nuxt的composables是一种非常有用的工具,可以帮助您更轻松地管理和共享状态、副作用和计算逻辑。无论您是在客户端还是服务器端上编写代码,都可以使用composables来提高代码的可重用性和可测试性。

Nuxt3使用compositables/目录使用自动导入将Vue可组合文件自动导入到应用程序中!

// 方法1:使用命名导出export const useFoo = () => {  return useState('foo', () => 'bar')}
// 方法2:使用默认导出// It will be available as useFoo() (camelCase of file name without extension)export default function () {  return useState('foo', () => 'bar')}

用法:您现在可以在.js、.ts和.vue文件中使用自动导入的可组合文件

<template>  <div>    {{ foo }}  </div></template><script setup>const foo = useFoo()</script>

更多内容请移步

服务端

server/ 目录是 Nuxt 项目中用于服务器端渲染(SSR)和服务器中间件的文件夹。当 Nuxt 在 SSR 模式下运行时,它使用 Node.js 在服务器上渲染 Vue 组件并将生成的 HTML 发送到客户端。server/ 目录包含用于配置服务器和处理请求的文件。
server/ 目录中一个重要的文件是routes,它用于创建服务器实例并配置中间件。该文件导出一个函数,该函数以 nuxtApp 对象作为参数,可以用于访问 Nuxt 应用程序实例并配置服务器。
server/ 目录中另一个重要的文件是middleware,它用于定义服务器中间件。服务器中间件类似于客户端中间件,但它在服务器上运行而不是在客户端上。服务器中间件可用于处理请求、修改响应或执行其他服务器端任务。
除了这些文件之外,server/ 目录可能包含其他用于配置服务器或处理请求的文件。例如,server/api 文件可以用于定义客户端可以访问的 API 端点。
总之,server/ 目录是 Nuxt 项目的重要部分,用于在 SSR 模式下配置服务器和处理请求。

在server/api/hello.ts中创建一个新文件:

export default defineEventHandler((event) => {  return {    api: 'works'  }})

现在,您可以使用wait$fetch(“/API/hello”)来普遍调用此API。

服务器路由

/server/api中的文件在其路由中会自动以/api作为前缀。要添加不带/api前缀的服务器路由,您可以将它们放在/server/routes目录中。

在server/routes/hello.ts中创建一个新文件

export default defineEventHandler(() => 'Hello World!')

给定上面的示例,/hello路由将在http://localhost:3000/hello.

服务器中间件

Nuxt将自动读取~/server/middleware中的任何文件,为您的项目创建服务器中间件。
中间件处理程序将在任何其他服务器路由之前对每个请求运行,以添加或检查标头、记录请求或扩展事件的请求对象。

// server/middleware/log.tsexport default defineEventHandler((event) => {  console.log('New request: ' + event.node.req.url)})
// server/middleware/auth.tsexport default defineEventHandler((event) => {  event.context.auth = { user: 123 }})

更多内容请移步

配置环境变量

要配置Nuxt环境变量,您需要了解以下几个知识点:
Nuxt的环境变量配置文件:Nuxt使用.env文件来配置环境变量。您可以在项目根目录下创建.env文件,并在其中定义您的环境变量。例如,您可以在.env文件中定义一个名为API_URL的环境变量,其值为您的API的URL。
环境变量的访问方式:您可以使用process.env对象来访问您在.env文件中定义的环境变量。例如,如果您在.env文件中定义了一个名为API_URL的环境变量,您可以在代码中使用process.env.API_URL来访问它。
环境变量的作用域:Nuxt的环境变量可以在客户端和服务器端上使用。如果您需要在客户端和服务器端上使用相同的环境变量,您可以将其定义在.env文件中。如果您需要在客户端和服务器端上使用不同的环境变量,您可以将其定义在.env.client和.env.server文件中。
环境变量的注入:Nuxt会将您在.env文件中定义的环境变量注入到客户端和服务器端的JavaScript代码中。这意味着您可以在客户端和服务器端的JavaScript代码中使用process.env对象来访问

# 请求接口地址VITE_REQUEST_BASE_URL = 'https://www.xxxxxx.net'VITE_SERVER_NAME = 'https://www.xxxxxx.net/api'# VITE开头的变量才会被暴露出去
import { loadEnv } from 'vite'const envName = loadEnv(process.argv[process.argv.length-1], './env').VITE_SERVER_NAMEexport default defineNuxtConfig({  app: {    head: {      meta: [        { name: 'viewport', content: 'width=device-width, initial-scale=1' }      ],      script: [        // { src: 'http://xxx.js' }      ],      link: [        // { rel: 'stylesheet', href: 'https://awesome-lib.css' }      ],    }  },  srcDir: 'src/',  css: [    '@/assets/styles/reset.css'  ],  modules: [    // ...    '@pinia/nuxt',    '@vueuse/nuxt',    '@element-plus/nuxt',  ],  vite: {    css: {      preprocessorOptions: {        scss: {          additionalData: '@import "@/assets/styles/default.scss";'	        }      }    }  },  runtimeConfig: { // 运行时常量    public: { // 客户端-服务的都能访问      baseUrl: envName    }  }})

更多内容请移步

部署

Nuxt.js有两种打包方式:静态和服务器端渲染(SSR)。静态打包方式生成的是静态HTML文件,可以直接部署到任何静态文件服务器上。而SSR打包方式则需要在服务器上运行Node.js,将Vue组件渲染为HTML并将其发送到客户端。因此,SSR打包方式需要在支持Node.js的服务器上部署。
关于部署到服务器和云平台,您可以将打包后的文件上传到服务器或云平台上,并在服务器上运行Node.js来启动Nuxt.js应用程序。您可以使用PM2等进程管理工具来管理Node.js进程,并使用Nginx等反向代理服务器来处理HTTP请求。

打包

对于静态打包方式,您可以使用以下命令进行打包:

npm run generate

对于SSR打包方式,您可以使用以下命令进行打包:

npm run build

这将生成一个.nuxt目录,其中包含所有的服务器端渲染代码和相关的资源文件。您可以将这些文件上传到支持Node.js的服务器上,并使用以下命令启动Nuxt.js应用程序:

部署到服务器

1、在服务器上安装Node.js和Nginx等必要的软件。可以使用以下命令在Ubuntu上安装Node.js:

sudo apt-get updatesudo apt-get install nodejs

2、可以使用以下命令在Ubuntu上安装Nginx:

sudo apt-get updatesudo apt-get install nginx

3、配置Nginx反向代理服务器。您需要将Nginx配置为将HTTP请求转发到Node.js服务器。可以使用以下配置文件作为参考:

server {    listen 80;    server_name example.com;    location / {        proxy_pass http://localhost:3000;        proxy_http_version 1.1;        proxy_set_header Upgrade $http_upgrade;        proxy_set_header Connection 'upgrade';        proxy_set_header Host $host;        proxy_cache_bypass $http_upgrade;    }}

4.配置完了重启nginx

nginx -s reload

5、启动Nuxt.js应用程序。您可以使用以下命令启动Nuxt.js应用程序:

npm run start

6、使用PM2等进程管理工具来管理Node.js进程。可以使用以下命令安装PM2:

npm install pm2 -g

7、可以使用以下命令启动Nuxt.js应用程序并使用PM2管理进程,进入到nuxt项目对应的文件夹,执行:

pm2 --name=你的服务名 start npm -- run start
pm2常用命令
pm2 list                             查看所有进程pm2 show 0                           查看进程详细信息,0为PM2进程id pm2 stop all                         停止PM2列表中所有的进程pm2 stop 0                           停止PM2列表中进程为0的进程pm2 reload all                       重载PM2列表中所有的进程pm2 reload 0                         重载PM2列表中进程为0的进程pm2 delete 0                         删除PM2列表中进程为0的进程pm2 delete all                       删除PM2列表中所有的进程

也许您对下面的内容还感兴趣: