🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
>[success] # Vuex 1. 组件之间传值的方式有很多,可以通过各种办法进行父传子,子传父,兄弟组件和非相关组件的传值通信,但是会出现一个问题如果多个组件之间要共享状态(数据)多个组件之 间互相传值很难跟踪数据的变化,如果出现问题很难定位问题 2. `vuex ` 目的就是可以将**组件的共享状态抽取出来,以一个全局单例模式管理** 从而进行状态管理,解决复杂组件通信,数据共享 3. 在 `vue ` 中我们数据流程触发如图 * 在组件中我们定义`data`或者在`setup`中返回使用的数据,这些数据我们称之为**state** * 在模块`template`中我们可以使用这些数据,模块最终会被渲染成 `DOM`,我们称之为**View**; * 在模块中我们会产生一些行为事件,处理这些行为事件时,有可能会修改`state`,这些行为事件我们称之为`actions`; ![](https://img.kancloud.cn/e1/c4/e1c403ebc74aab9bbca9c5b4d4789b2a_546x482.png) 4. `vuex` ,将各个组件需要通信的`state` 从内部状态抽离出来,以一个全局单例的方式来管理,vuex 也是遵循流的单向流的形式 * 所有的共享状态都放在 `vuex `的 `state` * vue 需要渲染的的页面将vuex 提供 state 渲染到页面上 * 但当页面数据改变 或者 需要记录的时候 vuex 不推荐直接修改状态,而是如果是异步数据需要触发 `action` 通过它来触发 `Mutations` 在改变`state` * 即使你是非异步数据也是要通过 `Mutations` 在改变`state` 这么做的目的是为了`Mutations` 模块进行数据记录变更同步给`vuetools `工具帮助我们可以更方便追踪数据 ![](https://img.kancloud.cn/3d/48/3d485cd3f432f984de60852baf3d6a47_734x589.png) >[info] ## vuex 使用 1. 安装 `npm install vuex` 2. 开发时候一般会起名一个 `store` 文件夹,创建一个**vuex store** ![](https://img.kancloud.cn/98/18/981843f4d7ab4ec86fc5f5b8a35338f7_275x50.png) ~~~ // 创建vuex import { createStore } from "vuex"; const store = createStore({ state: () => { return { name: "wwww", age: 12, }; }, }); export default store; ~~~ 3. 将创建的`vuex `到如进`vue` 对象上 ~~~ import { createApp } from "vue"; import App from "./App.vue"; import router from "./router"; import store from "./store"; createApp(App).use(router).use(store).mount("#app"); ~~~ 4. 开始使用,展示效果 ![](https://img.kancloud.cn/28/70/2870dffc305b8ce7b91521c3ac7508d7_210x78.png) ~~~html <template> <div class="about">{{ name }} --- {{ age }}</div> <!-- 因为已经绑定到vue 对象上因此可以通过$store去使用 --> <div class="about">{{ $store.state.name }} --- {{ $store.state.age }}</div> </template> <script setup> import { toRefs } from "vue"; import { useStore } from "vuex"; const store = useStore(); const { name, age } = toRefs(store.state); </script> ~~~ >[info] ## vuex 疑问 1. **项目必须使用vuex么**?首先`vuex `并不是必备的,官网也给了相应的意见如果您不打算开发大型单页应用,使用 `Vuex`可能是繁琐冗余的。确实是如此——如果您的应用够简单,您最好不要使用`Vuex`。一个简单的 `store `模式就足够您所需了。但是,如果您需要构建一个中大型单页应用,您很可能会考虑如何更好地在组件外部管理状态,`Vuex `将会成为自然而然的选择。 2. 直接不用 `createStore` 直接导出一个对象作为**全局通用属性,和使用vuex 区别在哪里**?Vuex的状态存储是响应式的,**当Vue组件从store中读取状态的时候,若store中的状态发生变化,那么相应的组件也会被更新**;通过`mutation` 去改变状态时候`vuetools `管理工具可以帮助我们记录更改方便开发 >[info] ## vuex 特点 1. 用一个对象就包含了全部的应用层级的状态,采用的是SSOT,**Single Source of Truth,也可以翻译成单一数据源**,每个应用将仅仅包含一个 `store` 实例 2. **单一状态树的优势**你的状态信息是保存到多个Store对象中的,那么之后的管理和维护等等都会变得特别困难,单一状态树能够让我们最直接的方式找到某个状态的片段; >[info] ## 简单的vuex 模型 ~~~ let _Vue = null class Store { constructor (options) { const { state = {}, getters = {}, mutations = {}, actions = {} } = options this.state = _Vue.observable(state) this.getters = Object.create(null) Object.keys(getters).forEach(key => { Object.defineProperty(this.getters, key, { get: () => getters[key](state) }) }) this._mutaions = mutations this._actions = actions } commit (type, payload) { this._mutaions[type](this.state, payload) } dispatch (type, payload) { this._actions[type](this, payload) } } function install (Vue) { _Vue = Vue _Vue.mixin({ beforeCreate () { if (this.$options.store) { _Vue.prototype.$store = this.$options.store } } }) } export default { Store, install } ~~~