store
不是 Vue 3 的内置功能,而是通过第三方状态管理库来实现的。Vue 3 推荐使用 Pinia 或 Vuex 来管理应用的全局状态。Pinia 是 Vue 3 官方推荐的状态管理库,具有更简洁的 API 和更好的类型支持。
下面是如何使用 Pinia 在 Vue 3 中创建和使用 store
的示例。
1. 安装 Pinia
首先,你需要安装 Pinia:
npm install pinia
2. 创建一个 Pinia Store
接下来,你可以创建一个 store
文件,比如 auth.js
,并定义状态、动作和 getters。
// src/store/auth.js
import { defineStore } from 'pinia';
import axios from 'axios';
export const useAuthStore = defineStore('auth', {
state: () => ({
loggedIn: localStorage.getItem('loggedIn') === 'true',
username: localStorage.getItem('username') || '',
}),
actions: {
setLoggedIn(status) {
this.loggedIn = status;
if (status) {
localStorage.setItem('loggedIn', 'true');
} else {
localStorage.removeItem('loggedIn');
localStorage.removeItem('username');
}
},
setUsername(username) {
this.username = username;
localStorage.setItem('username', username);
},
async register(username, password) {
try {
const response = await axios.post('/api/register', { username, password });
if (response.status === 201) {
this.setUsername(username);
this.setLoggedIn(true);
} else {
console.error('注册失败:', response.data.message);
}
} catch (error) {
console.error('注册时发生错误:', error);
}
},
async login(username, password) {
try {
const response = await axios.post('/api/login', { username, password });
if (response.status === 200) {
this.setUsername(username);
this.setLoggedIn(true);
} else {
console.error('登录失败:', response.data.message);
}
} catch (error) {
console.error('登录时发生错误:', error);
}
},
logout() {
this.setLoggedIn(false);
this.setUsername('');
},
},
});
3. 在 Vue 应用中使用 Pinia
在你的 Vue 应用的入口文件中(通常是 main.js
或 main.ts
),你需要引入并使用 Pinia:
// src/main.js
import { createApp } from 'vue';
import { createPinia } from 'pinia';
import App from './App.vue';
import router from './router';
const app = createApp(App);
const pinia = createPinia();
app.use(pinia);
app.use(router);
app.mount('#app');
4. 在组件中使用 Pinia Store
在组件中,你可以使用 useAuthStore
钩子来访问和操作 store
。
登录组件示例:
<!-- src/components/Login.vue -->
<template>
<div class="login-container">
<h1>登录</h1>
<form @submit.prevent="handleLogin">
<div class="form-group">
<label for="username">用户名</label>
<input type="text" id="username" v-model="username" required />
</div>
<div class="form-group">
<label for="password">密码</label>
<input type="password" id="password" v-model="password" required />
</div>
<button type="submit">登录</button>
</form>
</div>
</template>
<script setup>
import { ref } from 'vue';
import { useRouter } from 'vue-router';
import { useAuthStore } from '../store/auth';
const username = ref('');
const password = ref('');
const authStore = useAuthStore();
const router = useRouter();
const handleLogin = async () => {
await authStore.login(username.value, password.value);
if (authStore.loggedIn) {
router.push('/');
}
};
</script>
<style scoped>
.login-container {
max-width: 400px;
margin: 0 auto;
padding: 20px;
border: 1px solid #ccc;
border-radius: 4px;
background-color: #fff;
}
.form-group {
margin-bottom: 15px;
}
.form-group label {
display: block;
margin-bottom: 5px;
}
.form-group input {
width: 100%;
padding: 8px;
box-sizing: border-box;
}
button {
width: 100%;
padding: 10px;
background-color: #007bff;
color: #fff;
border: none;
border-radius: 4px;
cursor: pointer;
}
</style>
注册组件示例:
<!-- src/components/Register.vue -->
<template>
<div class="register-container">
<h1>注册</h1>
<form @submit.prevent="handleRegister">
<div class="form-group">
<label for="username">用户名</label>
<input type="text" id="username" v-model="username" required />
</div>
<div class="form-group">
<label for="password">密码</label>
<input type="password" id="password" v-model="password" required />
</div>
<button type="submit">注册</button>
</form>
</div>
</template>
<script setup>
import { ref } from 'vue';
import { useRouter } from 'vue-router';
import { useAuthStore } from '../store/auth';
const username = ref('');
const password = ref('');
const authStore = useAuthStore();
const router = useRouter();
const handleRegister = async () => {
await authStore.register(username.value, password.value);
if (authStore.loggedIn) {
router.push('/');
}
};
</script>
<style scoped>
.register-container {
max-width: 400px;
margin: 0 auto;
padding: 20px;
border: 1px solid #ccc;
border-radius: 4px;
background-color: #fff;
}
.form-group {
margin-bottom: 15px;
}
.form-group label {
display: block;
margin-bottom: 5px;
}
.form-group input {
width: 100%;
padding: 8px;
box-sizing: border-box;
}
button {
width: 100%;
padding: 10px;
background-color: #007bff;
color: #fff;
border: none;
border-radius: 4px;
cursor: pointer;
}
</style>
总结
- Pinia 是 Vue 3 官方推荐的状态管理库,用于管理应用的全局状态。
-
安装 Pinia:通过
npm install pinia
安装。 -
创建 Store:使用
defineStore
定义store
,包括状态、动作和 getters。 - 在应用中使用 Pinia:在应用的入口文件中引入并使用 Pinia。
-
在组件中使用 Store:通过
useAuthStore
钩子访问和操作store
。
这样,你可以在 Vue 3 项目中高效地管理全局状态。