从零开始的nuxt3之路(2),模板页面
2024-11-22 16:09:05

正文

路由整理

因为nuxt自带的根据目录生成模板,所以这里要注意文件的命名规范。

命名规范

按照上方目录的指引,我们在components下写入所有的常用的页面组件。

然后,我们在pages的目录下,按照制定的页面创建对应名字的文件夹。

页面模板

页面模版分为默认模版和自定义模板。

layouts/default,主要是nuxt3的模板目录,页面如果不特殊申明所使用的模板,就会默认使用这个模板。

1
2
3
4
5
6
7
8
9
10
11
<template>
<div>
<AppHeader />

<div class="main-container">
<slot />
</div>

<AppFooter />
</div>
</template>

配置项目

这里我们需要配置nuxt.config.ts,在nuxt中,几乎所有的全局配置都是在这里写的。

比如我们接下来要说的:SEO配置,css样式,外部js,还有快捷引入方式等。

SEO配置

这里我看有些人会专门拆开这些配置放在页面内去写。

虽然这种写法可以,但是我感觉很不可理喻,毕竟这是主要配置一次的东西。

有什么特殊要求直接在这里改就好,没必要单独抽离去改,太过于分离了。

1
2
3
4
5
6
7
8
9
10
11
app: {
head: {
title: '网站名称',
meta: [
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ name: 'keywords', content: '网站关键字' },
{ name: 'description', content: '网站描述' }
],
link: []
}
},

CSS引入

这里我选择引入的是less,scss虽然我用的很久,但是因为node-scss整的烂活,且到现在dart-sass也经常闹warning

思考了一段时间后,我这里就放弃了scss,引入less,稳妥第一。

lessscss的使用方法大差不差,用那种都是无所谓的。

引入UI框架

UI这点可根据自己常用的框架进行调整,我这里按照,这个无所谓好坏的。

因为个人公司常用的是elementUI plus,所以这里也引入这个UI框架。

在项目目录下,我们先安装包,个人项目里喜欢用pnpm管理,这点根据自己的需求酌情考虑。

1
pnpm install element-plus -s

安装Nuxt官方专门针对引入Element Plus 开发的模块

1
pnpm i @element-plus/nuxt -D

nuxt.config.ts中配置modules参数

1
2
3
4
5
6
export default defineNuxtConfig({
modules: [
'@element-plus/nuxt'
],
elementPlus: { /** Options */ }
})

全局引入element ui 图标

Element Plus UI 的图标并未在nuxt3中做自动导入,所以使用的时候,需要手动从@element-plus/icons-vue中导入。

如果引入不多的话,我们这里可以采用局部引入的方式。

1
2
3
4
5
6
7
8
9
<template>
<el-icon>
<Document />
</el-icon>
</template>

<script lang="ts" setup>
import { Document } from '@element-plus/icons-vue'
</script>

如果我们很多地方都要用到图标,且有时候需要使用动态引入的时候,我么可以在Nuxt3中创建一个plugin来完成。

plugins目录中创建一个global.ts文件,用于全局引入一些组件。

1
2
3
4
5
6
7
8
9
10
import * as ElementPlusIconsVue from '@element-plus/icons-vue'

export default defineNuxtPlugin(async (NuxtApp) => {
// nuxtApp包含的属性可看文档 https://nuxt.com/docs/guide/going-further/internals

// 全局组件引入
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
NuxtApp.vueApp.component(key, component)
}
})

通过上述方式,我们就可以全局引入图标,而不是每个页面需要手动引入了。

引入pina

pina的主要作用是全局数据管理,之所以选择它,主要原因是个人偏好,次要原因是pina的文档好。

一开始也考虑过直接用cookie或者localstorage来做全局数据管理,但是后来想了想,pina这种数据管理,在v3项目中已经很成熟了,就不做不成熟的尝试了。

1
pnpm i @pinia/nuxt

在模块nuxt.config.ts中引入,这里要注意nuxt3的版本,如果版本不对,引入的方式可能有不同。

我这里的nuxt版本是3.15.4,如果当前开发的版本已经确定,尽可能的不要乱升级。

1
2
3
4
5
6
7
8
9
10
11
12
13
modules: [
[
'@pinia/nuxt',
{
autoImports: [
// 自动引入 `defineStore()`
'defineStore',
// 自动引入 `defineStore()` 并重命名为 `definePiniaStore()`
['defineStore', 'definePiniaStore']
]
}
]
]

在根目录中创建store文件夹,我看有很多项目会整合pina的不同模块,我个人觉得没啥必要。

我这里就按照模块分开命名了几个文件,以下以store/user.ts为例。

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
// import { login } from '@/api/login'

import { defineStore } from 'pinia'

export default defineStore('user', {
state: () => ({
name: '',

}),

mutations: {
SET_NAME: (state, name) => {
state.name = name
},
},

actions: {
// 登录
Login({ commit }, userInfo) {
const username = userInfo.username.trim()
const password = userInfo.password
const code = userInfo.code
const uuid = userInfo.uuid
return new Promise((resolve, reject) => {
login(username, password, code, uuid)
.then((res) => {
setToken(res.data.token)
commit('SET_NAME', res.data.name)
resolve()
})
.catch((error) => {
reject(error)
})
})
},
}
})

在文件中使用pina定义的模块,这里调pina的数据,最好还是在setup之外的生命周期内使用,不然数据初始化失败会出现一些意料之外的问题。

1
2
3
4
5
6
7
8
9
<script setup lang="ts">
// 引入pina 实例,不要在setup中使用,而是等实例化之后再用
import useUserStore from '@/store/user'
const userStore = useUserStore()

onMounted(() => {
console.log(userStore.name, '测试>>>>>')
})
</script>

这里我们稍微配置一下,自动引入pina,省的我们每个页面都像上边一样手动引入。

1
2
3
4
5
6
// nuxt.config.js
export default defineNuxtConfig({
imports: {
dirs: ["stores/**/index.{ts,js,mjs,mts}"]
},
})

然后我们就可以不需要import 引入就能使用了,非常方便。

结语

页面模板的搭建至关重要,随着项目的不断完善,这个搭建过程会尽可能的完善。

参考

Nuxt3使用pinia并持久化处理,同时配置自动引入自定义的仓库store模块 - 木灵鱼儿

Prev
2024-11-22 16:09:05
Next