首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Vue集合vuex封装状态管理库

Vue集合vuex封装状态管理库

原创
作者头像
小焱
发布2025-08-25 11:43:24
发布2025-08-25 11:43:24
12800
代码可运行
举报
文章被收录于专栏:前端开发前端开发
运行总次数:0
代码可运行

Vue结合Vuex封装状态管理库

Vuex是Vue官方提供的状态管理模式,以下是一个封装良好的Vuex状态管理库实现,包含模块化设计、持久化存储和常用功能封装。

1. 目录结构设计
代码语言:txt
复制
store/
├── index.js          # 入口文件,创建store实例
├── state.js          # 根状态
├── mutations.js      # 根 mutations
├── actions.js        # 根 actions
├── getters.js        # 根 getters
├── modules/          # 模块目录
│   ├── user.js       # 用户模块
│   ├── app.js        # 应用模块
│   └── ...
└── plugins/          # 插件目录
    └── persistence.js # 持久化插件
2. 核心实现

store/index.js - 入口文件

代码语言:javascript
代码运行次数:0
运行
复制
import Vue from 'vue'
import Vuex from 'vuex'
import state from './state'
import mutations from './mutations'
import actions from './actions'
import getters from './getters'
import user from './modules/user'
import app from './modules/app'
import persistence from './plugins/persistence'

// 注册Vuex
Vue.use(Vuex)

// 自动导入modules目录下的所有模块
const requireModule = require.context('./modules', false, /\.js$/)
const modules = {}

requireModule.keys().forEach(fileName => {
  const moduleName = fileName.replace(/(^\.\/)|(\.js$)/g, '')
  modules[moduleName] = requireModule(fileName).default || requireModule(fileName)
})

// 创建store实例
const store = new Vuex.Store({
  state,
  mutations,
  actions,
  getters,
  modules: {
    ...modules,
    user,
    app
  },
  plugins: [persistence] // 应用持久化插件
})

export default store

store/plugins/persistence.js - 持久化插件

代码语言:javascript
代码运行次数:0
运行
复制
/**
 * Vuex持久化插件
 * 将指定的state保存到localStorage或sessionStorage
 */
export default function persistencePlugin (store) {
  // 初始化时从本地存储加载状态
  const savedState = localStorage.getItem('vuex_state')
  if (savedState) {
    try {
      store.replaceState({
        ...store.state,
        ...JSON.parse(savedState)
      })
    } catch (e) {
      console.error('Failed to parse saved state', e)
    }
  }

  // 订阅state变化,保存到本地存储
  store.subscribe((mutation, state) => {
    // 只保存需要持久化的模块
    const stateToPersist = {
      user: state.user,
      app: {
        theme: state.app.theme,
        language: state.app.language
      }
    }
    
    localStorage.setItem('vuex_state', JSON.stringify(stateToPersist))
  })
}

store/modules/user.js - 用户模块示例

代码语言:javascript
代码运行次数:0
运行
复制
const state = {
  token: '',
  userInfo: null,
  permissions: []
}

const mutations = {
  SET_TOKEN: (state, token) => {
    state.token = token
  },
  SET_USER_INFO: (state, userInfo) => {
    state.userInfo = userInfo
  },
  SET_PERMISSIONS: (state, permissions) => {
    state.permissions = permissions
  },
  CLEAR_USER_STATE: (state) => {
    state.token = ''
    state.userInfo = null
    state.permissions = []
  }
}

const actions = {
  // 登录
  login({ commit }, userData) {
    return new Promise((resolve, reject) => {
      // 模拟API请求
      setTimeout(() => {
        const { username } = userData
        const token = 'mock_token_' + Date.now()
        
        commit('SET_TOKEN', token)
        commit('SET_USER_INFO', { username, role: 'admin' })
        commit('SET_PERMISSIONS', ['read', 'write', 'delete'])
        
        resolve({ success: true, token })
      }, 500)
    })
  },
  
  // 退出登录
  logout({ commit }) {
    return new Promise(resolve => {
      commit('CLEAR_USER_STATE')
      resolve()
    })
  },
  
  // 获取用户信息
  getUserInfo({ commit, state }) {
    return new Promise((resolve) => {
      if (state.userInfo) {
        resolve(state.userInfo)
        return
      }
      
      // 模拟从服务器获取用户信息
      setTimeout(() => {
        const userInfo = {
          username: 'admin',
          name: 'Administrator',
          avatar: 'https://picsum.photos/200/200',
          role: 'admin'
        }
        commit('SET_USER_INFO', userInfo)
        resolve(userInfo)
      }, 300)
    })
  }
}

const getters = {
  isAuthenticated: state => !!state.token,
  hasPermission: state => (permission) => {
    return state.permissions.includes(permission)
  },
  userAvatar: state => state.userInfo?.avatar || ''
}

export default {
  namespaced: true, // 启用命名空间
  state,
  mutations,
  actions,
  getters
}
3. 在Vue项目中使用

main.js

代码语言:javascript
代码运行次数:0
运行
复制
import Vue from 'vue'
import App from './App.vue'
import store from './store'

new Vue({
  store, // 注入store
  render: h => h(App)
}).$mount('#app')

组件中使用示例

代码语言:vue
复制
<template>
  <div class="user-profile">
    <div v-if="isAuthenticated">
      <img :src="userAvatar" alt="User avatar" />
      <p>{{ userInfo?.name }}</p>
      <button @click="handleLogout">Logout</button>
    </div>
    <div v-else>
      <button @click="handleLogin">Login</button>
    </div>
  </div>
</template>

<script>
import { mapState, mapGetters, mapActions } from 'vuex'

export default {
  computed: {
    // 映射user模块的状态
    ...mapState('user', ['userInfo', 'token']),
    // 映射user模块的getters
    ...mapGetters('user', ['isAuthenticated', 'userAvatar', 'hasPermission'])
  },
  methods: {
    // 映射user模块的actions
    ...mapActions('user', ['login', 'logout', 'getUserInfo']),
    
    async handleLogin() {
      try {
        const result = await this.login({ username: 'admin', password: '123456' })
        console.log('Login success', result)
      } catch (error) {
        console.error('Login failed', error)
      }
    },
    
    async handleLogout() {
      await this.logout()
      console.log('Logout success')
    }
  },
  mounted() {
    // 页面加载时获取用户信息
    if (this.isAuthenticated) {
      this.getUserInfo()
    }
  }
}
</script>
4. 封装要点说明
  1. 模块化设计:将不同领域的状态分离到不同模块,保持代码清晰
  2. 命名空间:启用namespaced: true避免模块间命名冲突
  3. 持久化存储:通过插件实现关键状态的本地存储
  4. 自动导入:使用require.context自动导入模块,减少手动配置
  5. 统一接口:通过mapState、mapGetters等辅助函数提供一致的访问方式
  6. 异步处理:所有异步操作放在actions中,保持mutations的同步性

这种封装方式既保留了Vuex的核心功能,又提供了更好的可维护性和扩展性,适合中大型Vue项目使用。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Vue结合Vuex封装状态管理库
    • 1. 目录结构设计
    • 2. 核心实现
    • 3. 在Vue项目中使用
    • 4. 封装要点说明
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档