# VueX

### 使用Vuex对Vue组件中的状态进行管理，简化了组件间的通信

* 使用`new Vuex.Store`创建一个store
* store对象定义了状态和改变的方法`mutations`
* 使用store的commit调用对应的mutation方法改变store的状态
* 使用store.state.属性名，获取组件的状态

简单使用

```javascript
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state) {
      state.count++
    }
  }
})
```

### 改变状态后，获取对应的值

```javascript
store.commit('increment')

console.log(store.state.count) // -> 1
```

可以在根组件中直接注入store，这时候在子组件中可以通过`this.$store.property`访问对应的stat；类似router的注入

```javascript
//根组件中注入
new Vue({
  el: '#app',
  store: store,
})
```

### 计算属性与state属性重名时

```javascript
computed: mapState([
  // 映射 this.count 为 store.state.count
  'count'
])
```

### getter可以从state属性中派生出数据

访问`store.getters.doneTodos`就可以访问派生数据

```javascript
const store = new Vuex.Store({
  state: {
    todos: [
      { id: 1, text: '...', done: true },
      { id: 2, text: '...', done: false }
    ]
  },
  getters: {
    doneTodos: state => {
      return state.todos.filter(todo => todo.done)
    }
  }
})
```

不仅仅可以派生出数据，还可以返回一个箭头函数，在组件中使用函数对state.数据进行操作

```javascript
getters: {
  // ...
  getTodoById: (state) => (id) => {
    return state.todos.find(todo => todo.id === id)
  }
}
//调用函数
store.getters.getTodoById(2) // -> { id: 2, text: '...', done: false }
```

### 更改state的状态

更改state的唯一办法就是提交mutation，其中更改状态类似于一个事件，使用commit函数更像是触发对应的更改事件；在提交mutation时，还可以给事件传递载荷，参数把；不过在申明的时候就要告诉mutation。

```javascript
mutations: {
  increment (state, n) {
    state.count += n
  }
}
//传递参数
store.commit('increment', 10)
```

### 使用常量代替mutation中的事件名字

在大型项目中非常实用，尤其是多人协作的项目里

### action与mutation

action有利于参数解构，简化代码

使用`state.dispatch`出发对应的action；并且action支持异步操作而mutation不支持异步操作

> `store.dispatch` 可以处理被触发的 action 的处理函数返回的 Promise，并且 `store.dispatch` 仍旧返回 Promise：

```javascript
const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state) {
      state.count++
    }
  },
  actions: {
    increment (context) {
      context.commit('increment')
    }
  }
})
```

## module解决单一状态树问题

当项目变得庞大时，store对象就可能变得十分臃肿；为了解决这个问题Vuex运行我们将store分隔单个模块

```javascript
const moduleA = {
  state: () => ({ ... }),
  mutations: { ... },
  actions: { ... },
  getters: { ... }
}

const moduleB = {
  state: () => ({ ... }),
  mutations: { ... },
  actions: { ... }
}

const store = new Vuex.Store({
  modules: {
    a: moduleA,
    b: moduleB
  }
})

store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态
```

而子模块内部中mutation、gettter函数接收的第一个参数就是子模快store对象，第三个参数则是根节点的store对象；类似路由的嵌套

### 动态的注册模块

```javascript
import Vuex from 'vuex'

const store = new Vuex.Store({ /* 选项 */ })

// 注册模块 `myModule`
store.registerModule('myModule', {
  // ...
})
// 注册嵌套模块 `nested/myModule`
store.registerModule(['nested', 'myModule'], {
  // ...
})
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://zpliu.gitbook.io/booknote/vuex/qi-bu.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
