大家好!本篇将要分享的内容是如何在Nuxt3中进行状态管理。在Nuxt 主要有两种方式进行状态管理:
- 第一种是使用Nuxt3 中的useState,在Nuxt3中提供了一个内置的组合式函数
useState来进行状态管理, 用useState设置的状态可以在组件之间进行共享, 在初始设置时他接收一个唯一的key作为第一个参数。第二个参数是一个函数,并且这个函数返回一个值,这个值就是状态。 - 第二种是集成第三方库,比如说
Pinia或者Vuex, 本篇以Pinia为例
useState 的使用
1. 先初始化一个项目:
pnpm dlx nuxi@latest init nuxt3-state
2. 创建项目结构
3. 登录页面编写
<template>
<div>
<div class="form-item">
<label>用户名:</label>
<input v-model="userName" />
</div>
<div class="form-item">
<label>密码:</label>
<input type="password" v-model="password" />
</div>
<div class="btn-wrap">
<button @click="login">登录</button>
</div>
</div>
</template>
<script setup>
const userName = ref('')
const password = ref('')
const router = useRouter()
const login = () => {
useState('userInfo', () => {
return {
name: userName.value,
email: userName.value + '@163.com'
}
})
router.push('/')
}
</script>
<style scoped>
.form-item {
display: flex;
margin-top: 20px;
}
.form-item label {
width: 80px;
}
.form-item input {
outline: none;
border: none;
box-shadow: 0 0 0 1px #dcdfe6 inset;
border-radius: 4px;
line-height: 40px;
}
.btn-wrap {
margin-top: 20px;
}
.btn-wrap button {
padding: 6px 12px;
background: #409eff;
border: none;
border-radius: 4px;
color: #fff;
margin-left: 80px;
cursor: pointer;
}
</style>
在登录组件中点击登录后,用useState设置了用户信息。
4. 首页
pages/index.vue
<template>
<div>
<h1>首页</h1>
<p>恭喜您登录成功!以下是您的个人信息:</p>
<p>用户名: <strong>{{ userInfo.name }}</strong></p>
<p>邮箱: <strong>{{ userInfo.email }}</strong></p>
</div>
</template>
<script setup>
const userInfo = useState('userInfo') | {}
</script>
<style scoped>
</style>
在首页中我们使用useState 获取登录页面设置的用户信息。
5. 运行效果
可以看到我们在登录页面设置的用户信息能在首页进行获取到。到这里我们就掌握了useState 的用法。
集成Pinia
1. 安装依赖
执行pnpm i pinia @pinia/nuxt
到这里很有可能会出现以下错误:
我们按照提示执行下pnpm install 命令,然后再执行pnpm i pinia @pinia/nuxt 就可以安装成功了。
我们将之前useState 实现的状态改成Pinia来写。
2. 修改nuxt.conifig.ts
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
compatibilityDate: '2024-11-01',
devtools: { enabled: true },
modules:['@pinia/nuxt']
})
主要增加了modules:['@pinia/nuxt']
3. 项目根目录下新增stores,stores下新增user.ts
stores/user.ts
interface Iuser {
name: string | '',
email: string | ''
}
export default defineStore('userStore', {
state () {
return {
userInfo: {
name: '',
email: ''
}
}
},
actions: {
setUserInfo({ name, email}: Iuser) {
this.userInfo.name = name
this.userInfo.email = email
}
}
})
4. 修改login.vue
pages/login.vue
<template>
<div>
<div class="form-item">
<label>用户名:</label>
<input v-model="userName" />
</div>
<div class="form-item">
<label>密码:</label>
<input type="password" v-model="password" />
</div>
<div class="btn-wrap">
<button @click="login">登录</button>
</div>
</div>
</template>
<script setup>
import useUserStore from '~/stores/user'
const userName = ref('')
const password = ref('')
const router = useRouter()
const userStore = useUserStore()
const login = () => {
userStore.setUserInfo({
name: userName.value,
email: userName.value + '163.com'
})
router.push('/')
}
</script>
<style scoped>
.form-item {
display: flex;
margin-top: 20px;
}
.form-item label {
width: 80px;
}
.form-item input {
outline: none;
border: none;
box-shadow: 0 0 0 1px #dcdfe6 inset;
border-radius: 4px;
line-height: 40px;
}
.btn-wrap {
margin-top: 20px;
}
.btn-wrap button {
padding: 6px 12px;
background: #409eff;
border: none;
border-radius: 4px;
color: #fff;
margin-left: 80px;
cursor: pointer;
}
</style>
login.vue中,我们主要将login方法里面的逻辑改成了调用pinia的actions里面的方法来实现。
5. 修改index.vue
pages/index.vue
<template>
<div>
<h1>首页</h1>
<p>恭喜您登录成功!以下是您的个人信息:</p>
<p>用户名: <strong>{{ userInfo.name }}</strong></p>
<p>邮箱: <strong>{{ userInfo.email }}</strong></p>
</div>
</template>
<script setup>
import userUserStore from '~/stores/user.ts'
const { userInfo } = userUserStore()
</script>
<style scoped>
</style>
在index.vue中我们也是主要将useState 获取状态改成了用pinia 来实现。
6. 运行效果
可以看到我们依然能正常设置用户信息。
总结
通过本篇的介绍,我们知道了Nuxt3中主要有两种方式管理状态,一种是Nuxt3内置的useState, 另一种是集成第三方库。本篇以Pinia 为例进行了介绍,并且介绍了安装依赖时出错处理的方式。