在大型应用程序中,状态管理经常变得复杂,因为多个组件之间分散的多个状态以及它们之间的交互。 人们常常忽视Vue实例中的真实来源是原始数据对象–Vue实例只是代理对其的访问。 因此,如果您有一段应该由多个实例共享的状态,则应避免将其复制并通过identity进行共享。
如果您想要组件共享状态,推荐使用的方法是Vuex。 在深入研究之前查看它的文档。搭配使用Vue dev-tools的浏览器扩展(如Time Travel调试)时它有很好的特性。
我们不会详细介绍如何配置或使用Vuex,因为它有很棒的文档。 相反,我们只是告诉你在Quasar项目中使用它时文件夹结构的样子。
.
└── src/
└── store/ # Vuex Store
├── index.js # Vuex Store 定义
├── <folder> # Vuex Store 模块...
└── <folder> # Vuex Store 模块...
默认情况下,如果您在使用Quasar CLI创建项目文件夹时选择使用Vuex,它将设置使用Vuex模块。 /src/store
的每个子文件夹代表一个Vuex模块。
如果在项目创建期间没有选择Vuex选项,但希望稍后添加它,则只需添加一个Vuex模块(请参见下面的示例)。
TIP
如果在您的网站应用程序中Vuex模块太多,您可以更改/src/store/index.js
并避免导入任何模块。
添加一个Vuex模块
Quasar CLI通过$ quasar new
命令轻松添加Vuex模块。
$ quasar new store <store_name>
它会在上面的命令中创建一个名为“store_name”的/src/store
文件夹。 它将包含您需要的所有样板。
假设您要创建一个“showcase”Vuex模块。 你运行$ quasar new store showcase
。 然后您会注意到新创建的/src/store/showcase
文件夹,其中包含以下文件:
.
└── src/
└── store/
├── index.js # Vuex Store定义
└── showcase # "showcase"模块
├── index.js # 将模块粘合在一起
├── actions.js # actions模块
├── getters.js # getters模块
├── mutations.js # mutations模块
└── state.js # state模块
我们已经创建了新的Vuex模块,但我们还没有通知Vuex使用它。 所以我们编辑/src/store/index.js
并添加一个引用:
import Vue from 'vue'
import Vuex from 'vuex'
// 首先导入模块
import showcase from './showcase'
Vue.use(Vuex)
export default function (/* { ssrContext } */) {
const Store = new Vuex.Store({
modules: {
// 然后我们引用它
showcase
},
// 启用严格模式(增加开销!)
// 仅适用于开发模式
strict: process.env.DEV
})
/*
如果我们需要一些HMR魔术,我们会处理
下面的热点更新。 注意我们实现这个
用“process.env.DEV”代码 - 所以这不会
进入我们的生产版本(也不应该)。
*/
if (process.env.DEV && module.hot) {
module.hot.accept(['./showcase'], () => {
const newShowcase = require('./showcase').default
Store.hotUpdate({ modules: { showcase: newShowcase } })
})
}
return Store
}
现在我们可以在我们的Vue文件中使用这个Vuex模块。 这是一个简单的例子。假设我们配置了state的 drawerState
属性并增加了 updateDrawerState
变动(mutation)。
// src/store/showcase/mutations.js
export const updateDrawerState = (state, opened) => {
state.drawerState = opened
}
// src/store/showcase/state.js
// 如果使用SSR,请务必使用函数返回状态
export default function () {
return {
drawerState: true
}
}
在Vue文件中
<template>
<div>
<q-toggle v-model="drawerState" />
</div>
</template>
<script>
export default {
computed: {
drawerState: {
get () {
return this.$store.state.showcase.drawerState
},
set (val) {
this.$store.commit('showcase/updateDrawerState', val)
}
}
}
}
</script>
存储代码拆分
您可以利用预取功能来对Vuex模块进行代码拆分。