1.前言
我们分析推导出
vuex
的目录结构
2. store概念
每一个 Vuex 应用的核心就是 store
(仓库)。
“store”基本上就是一个容器,它包含着你的应用中大部分的状态
(state)
。Vuex
和单纯的全局对象有以下两点不同:1.
Vuex
的状态存储是响应式
的。当Vue
组件从store
中读取状态的时候,若store
中的状态发生变化,那么相应的组件也会相应地得到高效更新。2.你不能直接改变
store
中的状态。改变store
中的状态的唯一途径就是显式地提交(commit) mutation
。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。
3.创建 store
src/store/index.js
state 就是我们需要管理的状态 ,其实也就是需要共享的数据
里面写个
num:8
先体验下
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Store({ state: { num:8 }, mutations: { } })
main.js
import store from './store new Vue({ router, // 提供了一种机制将状态 注入到每个组件 store, render: h => h(App) }).$mount('#app')
4. 组件访问 store
<p>1-访问store 状态:{{$store.state.num }}</p> <!-- 一般通过计算属性来获取 --> <p>2-访问store 状态:{{getStoreNum }}</p>
因我们把 store在 main.js 注入到 Vue实例对象了
所以这里可以访问 this.data this.$router
一个性质
但是 直接获取是不建议的
通常用计算属性来获取
5. 组件内 点击 修改 store 状态
// 注意不要这样写
this.$store.state.num++
参见 上面的 基本概念 第二条
改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation
<button @click="changeStoreNum()">修改 store num +</button>
正确写法
methods: { changeStoreNum(){ this.$store.commit("increment",3) } },
.commit(参数1,参数2)
参数1 和
store
里面mutations
的属性对应起来额外的参数.. 即 mutation 的 载荷(payload):
在大多数情况下,载荷应该是一个对象,这样可以包含多个字段并且记录的 mutation 会更易读
mutations: { increment (state, payload) { state.count += payload.amount } }
store.commit('increment', { amount: 10 })
但是现在还没有 increment
,需要在store
添加内容
mutations: { increment (state,m) { state.num += m } },
第一个参数
state
就是默认的store
的状态这里的
m
就是形参,具体是commit
调用的时候 传过来的
6. 计算属性修改 store
组件内 计算属性
这里可以不写 return
computed:{ getStoreMsg(){ this.$store.commit("modifyMsg","修改了^_^") }, }
store
state: { num:8, msg:"计算属性修改的", }, mutations: { modifyMsg(state,s){ state.msg = s }, increment (state,m) { state.num += m } },
组件 使用这个属性
<p>计算属性修改:{{$store.state.msg}}</p>
7. 辅助函数
当一个组件需要获取多个状态的时候,将这些状态都声明为计算属性会有些重复和冗余。为了解决这个问题,我们可以使用 mapState 辅助函数帮助我们生成计算属性,让你少按几次键:
引入 辅助函数mapState
// 在单独构建的版本中辅助函数为 Vuex.mapState import { mapState } from 'vuex'
辅助函数 state写 直接写
count1(state){ return state.count1 +"---------^_^" },
箭头函数的写法
count2:(state)=>{ return state.count2 +"---------😄" },
如果箭头函数只有一个参数,函数体只有一行代码,可以省略{} return也可省
count3:state=>state.count3 +" ⛽️💪",
访问
<p>辅助函数1-直接使用 : {{ count1 }}</p> <p>辅助函数2-箭头函数 : {{ count2 }}</p> <p>辅助函数3-精简写法 : {{ count3 }}</p>
store,js
state: { num:8, msg:"计算属性修改的", count1:"count1", count2:"count2", count3:"count3", },
8. 上述写法 有个问题 不能和我们自己写的计算属性共存
对象展开运算符
computed:{ ...mapState(["count1","count2","count3"]), // 自己的 getStoreNum(){ return this.$store.state.num }, getStoreMsg(){ console.log("计算--------------------------") this.$store.commit("modifyMsg","修改了") }, getMsg(){ return this.msg.split("").reverse().join("") } }
9.组件仍然保有局部状态
使用 Vuex 并不意味着你需要将所有的状态放入 Vuex。虽然将所有的状态放到 Vuex 会使状态变化更显式和易调试,但也会使代码变得冗长和不直观。如果有些状态严格属于单个组件,最好还是作为组件的局部状态。你应该根据你的应用开发需要进行权衡和确定。