Nuxt3 项目基础配置超详细 and 项目模板

2023-11-01 11:24:57 浏览数 (3)

Nuxt特点

  • 自动化
    • 自动导入 (文件系统自动配置路由)
    • 零配置支持Typescript
    • 配置构建工具
  • 渲染模式 - 通用渲染(服务器端渲染和水化渲染) - 客户端渲染 - 完整的静态站点生成 - 混合渲染(每个路由的缓存策略) PS:虽然很便捷,但是很多坑

Nuxt基础配置模板地址 https://github.com/Seven7v/Nuxt3-vue3-project

代码语言:txt复制
git clone https://github.com/Seven7v/Nuxt3-vue3-project.git

首先安装一个Nuxt项目

代码语言:txt复制
npx nuxi@latest init may-app // my-app你的项目名称

安装成功 就是我们的基本运行项目工作

代码语言:txt复制
cd my-app
代码语言:txt复制
npm i
代码语言:txt复制
npm run dev

package.json 命令

生成的项目中,package.json中自动生成了几个命令

npm run build生成的是/.mjs文件,不是之前vue项目生成的静态文件,需要将生成的sever部署需要在node环境下部署,普通环境无法运行

代码语言:txt复制
 "scripts": {
    "build": "nuxt build", // 生成环境,同构渲染
    "dev": "nuxt dev", // 开发者环境,支持同构渲染
    "generate": "nuxt generate", // 生成静态资源,在output中的public文件夹中
    "preview": "nuxt preview", // build 命令后可以可以启动一个node服务来运行生成的文件
    "postinstall": "nuxt prepare"
  },

Nutx的自动化

入口文件为app.vue

pages

首先手动创建一个pages文件夹,用来存放项目页面。

poges 文件夹中的页面会自动配置好页面路由。

代码语言:txt复制
|- pages
    |-- home.vue

同理 如果 是这样的目录结构,/home路由也可以加载index.vue中的内容

代码语言:txt复制
|- pages
    |-- home
         |-- index.vue

app.js增加<NuxtPage>组件,与vue-router中的<router-view>功能一致

代码语言:txt复制
<template>
  <div>
    <NuxtPage></NuxtPage>
  </div>
</template>

这里通过localhost:3000/home就可以直接访问home页面

components

创建components文件夹 ,用来存放组件内容

components文件夹内的组件会自动注册,不需要使用import导入

代码语言:txt复制
|- components
    |-- Header.vue

app.js中直接使用<Header/>

代码语言:txt复制
<template>
  <div>
    <Header/>
    <NuxtPage></NuxtPage>
  </div>
</template>

此时Header的组件内容也会显示出来

layouts

创建layouts文件夹,并创建default.vue

代码语言:txt复制
|- layouts
    |-- default.vue
    |-- notab.vue

default.vue中加入<NuxtPage>和刚刚完成的组件

代码语言:txt复制
<template>
  <div>
    <Header />
    <NuxtPage></NuxtPage>
    <Tabbar />
  </div>
</template>

app.js中直接使用<NuxtLayout>组件默认会将default中的内容展示出来

代码语言:txt复制
<template>
  <div>
    <NuxtLayout></NuxtLayout>
  </div>
</template>

如果想展示notab页面中的布局 可以使用name属性

代码语言:txt复制
<template>
  <div>
    <NuxtLayout name = "notab"></NuxtLayout>
  </div>
</template>

这时页面可以切换布局

composables

composables文件夹下是公共函数,nuxt会自动加载里面的ts代码到页面使用,可以在里面写一些全局的方法。 文件名多用use开头

代码语言:txt复制
|- composables
    |-- useLang.ts

useLang.ts

代码语言:txt复制
export const useLang = () => useState("lang",()=>'zh-cn')

Nuxt 路由

基本路由

vue-router提供的router-link相似,在Nuxt中使用路由跳转 使用组件<NuxtLink>

也可以使用 custom属性 定制生成的内容不是 <a> 标签

代码语言:txt复制
 <!-- active-class="active"  给active class 设置样式,可以自动实现选中高亮 -->
 <template>
  <div class="mod-header">
    <div>
        <!-- 基本写法 -->
        <NuxtLink  to="/home" active-class="active">
          Home
        </NuxtLink>
        <!-- 定制元素 -->
        <!-- custom属性代表定制 -->
        <NuxtLink custom v-slot="{isActive, href, navigate } " to="/home" active-class="active">
          <h4 :href="href" @click="navigate" :class="isActive?'active':''">
              Home
          </h4>
        </NuxtLink>
    </div>
  </div>
</template>
<!-- 如果想要使用scss 或者 less 预处理器需要额外安装 -->
 <style lang="scss" scoped>
.active {
  border-bottom: 2px solid #000;
}
</style>

路由下的子路由如/home/hot可以有两种目录结构 (这里有个坑

代码语言:txt复制
|- pages
    |-- home.vue
    |-- home // 文件夹
          |--hot.vue  

这样的目录结构,hot.vue 相当于是home.vue的组件内容,可以在home.vue的<NuxtPage>显示,如果home.vue中不写<NuxtPage>, 跳转**/home/hot** 不会显示页面内容

或者

代码语言:txt复制
|- pages
    |-- home
         |-- index.vue
         |-- hot.vue // 单独页面 不是组件内容

这样的目录结构,home 页面和hot页面时单独存在的,跳转**/home/hot** 可以单独显示hot页面内容,在home 中 使用<NuxtPage> 无效

代码语言:txt复制
<NuxtLink  to="/home/hot" >HOT</NuxtLink>

动态路由

涉及到详情页路由,如/detial/idxxxxx格式的路由目录格式

代码语言:txt复制
|- pages
    |-- detail
         |-- [id].vue

如果访问 /detail/9527 后面跟任何ID都可以显示当前页面

[id].vue获取参数

代码语言:txt复制
<script setup lang="ts">
const route = useRoute() // 可以直接使用,不需要导入

console.log(route.params) // route.params 中就是我们传递过来的内容 { id : '9527 '}
</script>

使用 路由的跳转方法router.push不需要先导入useRouter ,可以直接在页面中使用

代码语言:txt复制
<script setup lang="ts">
const router = useRouter() // 可以直接使用,不需要导入

const handleToDetail = (id: number) => {
  router.push(`/detail/${id}`)
}
</script>

路由中间件

这里有关于页面路由配置的写法,但是并不详细

内联配置

代码语言:txt复制
<!-- 对单页面的路由守卫 -->
<script setup lang="ts">
 definePageMeta({
  middleware: (to, from) => {
    if (!localStorage.getItem('token')) {
      return navigateTo('/login') //一定要写return
    }
  }
})
</script>

命名中间件

如果多个页面需要配置守卫,可以将单页的内容 抽出

代码语言:txt复制
|- middleware
   |-- auth.ts // 中间件名称自定义

auth.ts中写入

代码语言:txt复制
export default defineNuxtRouteMiddleware((to, from) => {
  if (!localStorage.getItem('token')) {
    return navigateTo('/login') //一定要写return
  }
})

页面如果需要用到中间件的地方只需要配置,就可以实现导航守卫功能

代码语言:txt复制
<script setup lang="ts">
definePageMeta({
  middleware: 'auth'
})
</script>

全局中间件

代码语言:txt复制
|- middleware
   |-- auth.global.ts // 加上global后缀,默认全局中间件,进入所有路由都会通过这里

auth.global.ts

代码语言:txt复制
export default defineNuxtRouteMiddleware((to, from) => {
  const limitList = ['/article', '/home', '/product'] // 配置适配 路由
  if (limitList.includes(to.fullPath)) {
    if (!localStorage.getItem('token')) { // !!!!这里有个大坑
      return navigateTo('/login') //一定要写return
    }
  }
})

这样写如果从不做验证的页面进如,后跳转到**/home**时完全没有问题的,但是如果,路由地址中直接写**/home**回车,页面会加载不出来,提示500报错,没有localStorage。此时/home时首页,首页渲染时服务端返回,所以没有localStorage,可以将token 放到cookie中解决 ****

也可以使用 proess.server来判断,此代码是否是在服务端 运行的,如果时true,可以做对应处理。

打印后,在启动项目的终端会打印出true

将token储存在cookie中,使用useCookie

useCookie可以实现如下操作

代码语言:txt复制
if (process.server) {
      // 从服务端的cookie中获取token
    } else {
      // js 使用从浏览器的cookie中获取token
    }

从而可以写成,这样从/home直接进入的话就不会报错了

代码语言:txt复制
export default defineNuxtRouteMiddleware((to, from) => {
  const limitList = ['/article', '/home', '/product']
  if (limitList.includes(to.fullPath)) {
    const token = useCookie('token')
    if (!token.value) {
      return navigateTo('/login') //一定要写return
    }
  }
})

页面重定向

现在进入页面 直接加载会显示404,这时可以进行重定向

代码语言:txt复制
|- middleware
   |-- redirect.global.ts // 中间件名称自定义
代码语言:txt复制
export default defineNuxtRouteMiddleware((to, from) => {
  if (to.fullPath === '/') {
    return navigateTo('/home')
  }
})

0 人点赞