uni-app 内置 Vuex 但需手动初始化并挂载:创建 src/store/index.js,用 new Vuex.Store() 导出实例,在 main.js 中通过 new Vue({ store }) 挂载,否则 this.$store 为 undefined。

uni-app 项目里直接用 Vuex,不需要额外安装,但必须手动初始化 store 并挂载到 Vue 实例;不配 store,this.$store 就是 undefined。
创建 store/index.js 并正确导出 Store 实例
uni-app 内置了 Vuex,但不会自动创建 store。你得自己建 store 目录和 index.js,且必须用 new Vuex.Store({}) 显式构造实例并导出。
- 路径必须是
src/store/index.js(或store/index.js,取决于你项目根目录结构),其他位置如store/main.js不会被自动识别 - 必须调用
Vuex.Store构造函数,写成export default { state: {...} }是无效的 —— 这只是个普通对象,不是 Vuex store - 如果用了模块化(
modules),每个模块文件(如modules/user.js)必须默认导出一个对象,且该对象需含state(不能是函数)、mutations等标准字段
最小可用示例:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: { token: '' },
mutations: {
setToken(state, token) {
state.token = token
}
}
})
在 main.js 中挂载 store 到 Vue 实例
uni-app 的入口是 main.js,这里必须把 store 实例传给 new Vue() 的 store 选项,否则所有组件访问 this.$store 都会报错。
立即学习“前端免费学习笔记(深入)”;
- 确保
import store from './store'路径正确;常见错误是写成import store from '@/store'却没配别名 - 不能漏掉
store字段:错误写法new Vue({ render: h => h(App) })—— 缺失挂载,$store不可用 - H5 和小程序端行为一致,但 App 端若用 nvue 页面,
$store仍可用,前提是该页面由 vue 页面引入或通过uni.navigateTo正常跳转
main.js 关键片段:
import Vue from 'vue'
import App from './App.vue'
import store from './store' // ← 路径必须对
Vue.config.productionTip = false
const app = new Vue({
store, // ← 必须显式传入
render: h => h(App)
})
app.$mount('#app')
组件中使用 this.$store 读写状态
挂载成功后,所有 .vue 组件都能通过 this.$store 访问,但要注意响应式限制和调用时机。
- 在
data或computed中直接读this.$store.state.xxx是响应式的;但不要在data里缓存this.$store.state整体对象,否则后续 state 更新不会触发重渲染 - 修改状态必须走
commit:写this.$store.state.count = 1不触发更新,也不符合 Vuex 规则 - 异步操作(如登录请求)必须封装在
actions里,再由 actioncommitmutation;直接在组件 methods 里发请求 + commit 属于反模式,难以追踪和复用 - 大型项目建议用
mapState/mapMutations辅助函数简化写法,但注意它们返回的是函数/对象,需用...mapState(['token'])展开到computed中
模块化拆分时 modules 命名与调用细节
当 state 逻辑变多,拆成 modules 是必须的,但模块命名直接影响后续访问路径。
- 模块对象的 key 名就是命名空间:比如
modules: { user: userModule },那它的 state 就要通过this.$store.state.user.xxx访问 - 开启命名空间(
namespaced: true)后,commit和dispatch必须加前缀,如this.$store.commit('user/setToken', token);不加会找不到 mutation - 模块内
getters默认注册在全局,若开启命名空间,需在模块内显式写namespaced: true,否则mapGetters无法按模块映射 - 动态注册模块(
store.registerModule)在 uni-app 小程序端存在兼容风险,首次加载就应静态声明全部 modules
模块定义示例(store/modules/user.js):
export default {
namespaced: true,
state: { profile: null },
mutations: {
setProfile(state, profile) {
state.profile = profile
}
}
}
真正容易被忽略的是:Vuex 在 uni-app 中没有运行时校验机制,写错模块路径、漏掉 namespaced: true、或在 main.js 挂载前就访问 $store,都不会报明确错误,只会静默失效 —— 最稳妥的方式是在 App.vue 的 created 钩子里打印 this.$store 确认是否为 Store 实例。


















