Vuex和Vuex-persistedstate
Vuex
Vuex是Vue框架生态的一环,用于实现全局数据状态的统一管理。
官方地址:https://next.vuex.vuejs.org/zh/index.html
cd ~/Desktop/luffycity/luffycityweb
# 在客户端项目根目录下执行安装命令
yarn add vuex@next
npm install vuex
开始使用
在main.js导入并且使用use方法启用
import { createApp } from 'vue'
import { createStore } from 'vuex'
// 创建一个新的 store 实例
const store = createStore({
state () {
return {
count: 0
}
},
mutations: {
increment (state) {
state.count++
}
}
})
核心的五个属性
state
该属性等同于vue中的data属性,用来存储全局的对象
const state={
user:{name:"alex"}
}
getters
唯一的获取state中值的方法,计算属性
const state={
user:{name:"alex"}
}
const getters={
getUser(state){
return state.user.name
}
}
mutations 相当于vue中的methos
唯一的修改state中值的方法,同步阻塞
const state={
user:{name:"alex"}
}
const mutations={
updateUser(state,new_user){
state.user = new_user
}
}
actions
异步阻塞,也可以修改state值,但是底层还是调用mutations,而不是直接变更。
并且调用mutations还要通过commit方法,传入函数名进行调用
const state={
user:{name:"alex"}
}
const mutations={
updateUser(state,new_user){
state.user = new_user
}
const actions={
// 和mutations不同,不用传state,可以通过上下文context,
// 这个context 可以获取整个代码文件中的属性和方法
// 调mutations的方法通过commit调用,而调用actions的要用dispatch调用
asyncUpdateUser(context,new_user){ //这个context参数可以不显示传
context.commit("updateUser",new_user)
}
}
}
Module
用来对vuex下面进行模块化切分组合,看下官网例子https://vuex.vuejs.org/zh/guide/modules.html
const moduleA = {
state: () => ({ ... }),
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
state: () => ({ ... }),
mutations: { ... },
actions: { ... }
}
const store = createStore({
modules: {
a: moduleA,
b: moduleB
}
})
store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态
登录小案例
父组件 home.vue
子组件 login.vue
vuex全局的代码 login.js
子组件中输入用户名,如果是aa或者bb则登录成功,成功后的用户显示在父组件的标签中作为全局显示.
未登录成功则显示未登录
main.js代码
import { createApp } from 'vue'
// import './style.css'
import App from './App.vue'
import store from './components/login.js'
createApp(App).use(store).mount('#app')
home.vue代码
<script setup>
import { ref } from 'vue'
import login from "./login.vue"
import store from "./login.js"
</script>
<template>
<p>用户信息>>{{store.state.user}}</p>
<login></login>
</template>
<style scoped>
</style>
login.vue代码
<script setup>
import { ref,reactive } from 'vue'
import store from "./login.js"
const user =ref("")
// 同步阻塞 执行mutations
const submit =()=>{
if (user.value==="aa"){
store.commit("login_success",user)
}
}
// 异步调用 执行actions
const submit2 =()=>{
if (user.value==="bb"){
store.dispatch("asyncUpdateUser",user)
}
}
</script>
<template>
<label>用户登录</label>
<!-- <input type="" name="" v-model="userinfo.user"> -->
<input type="" name="" v-model="user">
<button @click="submit">commit同步阻塞</button>
<button @click="submit2">action异步阻塞</button>
</template>
login.js代码
import { createStore } from 'vuex'
export default createStore({
// 也可以用函数形式写
// state(){
// // state:{
// return{user:"未登录"}
// // }
// },
state:{user:"未登录"},
mutations:{
login_success(state,newuser){
state.user = newuser
console.log(state.user)
}
},
actions:{
// 和mutations不同,不用传state,可以通过上下文context,
// 这个context 可以获取整个代码文件中的属性和方法
// 调mutations的方法通过commit调用,而调用actions的要用dispatch调用
asyncUpdateUser(context,new_user){ //这个context参数可以不显示传
context.commit("login_success",new_user)
}
}
})


vuex-persistedstate
因为vuex默认是保存数据在内存中的,所以基于浏览器开发的网页,如果在F5刷新网页时会存在数据丢失的情况。所以我们可以把store数据永久存储到localStorage中。这里就需要使用插件vuex-persistedstate来实现。
在前端项目的根目录下执行安装命令
cd ~/Desktop/luffycity/luffycityweb
yarn add vuex-persistedstate
npm install vuex-persistedstate --save
在vuex的store/index.js文件中导入此插件。
import {createStore} from "vuex"
import createPersistedState from "vuex-persistedstate"
// 实例化一个vuex存储库
export default createStore({
// 调用永久存储vuex数据的插件,localstorage里会多一个名叫vuex的Key,里面就是vuex的数据
plugins: [createPersistedState()],
state(){ // 相当于组件中的data,用于保存全局状态数据
return {
user: {}
}
},
getters: {
getUserInfo(state){
// 从jwt的载荷中提取用户信息
let now = parseInt( (new Date() - 0) / 1000 );
if(state.user.exp === undefined) {
// 没登录
state.user = {}
localStorage.token = null;
sessionStorage.token = null;
return null
}
if(parseInt(state.user.exp) < now) {
// 过期处理
state.user = {}
localStorage.token = null;
sessionStorage.token = null;
return null
}
return state.user;
}
},
mutations: { // 相当于组件中的methods,用于操作state全局数据
login(state, payload){
state.user = payload; // state.user 就是上面声明的user
}
}
})
完成了登录功能以后,我们要防止用户FQ访问需要认证身份的页面时,可以基于vue-router的导航守卫来完成。