Vuex 官网 :开始 | Vuex (vuejs.org)
一、为什么要
vuex官方解释
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 + 库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
在组件之间的传值有哪些?有父子通讯,兄弟组件通讯......但是传参对于多层嵌套就显得非常繁琐,代码维护也会非常麻烦。因此vuex就是把组件共享状态抽取出来以一个全局单例模式管理,把共享的数据函数放进vuex中,任何组件都可以进行使用。
二、什么时候用它
具体来说的话,大体来说分为两类:
1.当一个组件需要多次派发事件时
原因很简单,如果它多次派发事件,必然有其它组件进行接收并调用。为了以后的方便维护,就需要用到vuex了,尤其是中大型项目。
2.跨组件共享数据、跨页面共享数据
简单来说,共享数据,只要看到这种字眼就要想到vuex了。需要共享的数据,就需要保存到vuex中。
三、安装使用
1、使用Vue-cli 帮忙自助生成Vuex 或者 在vue ui 里创建项目 下载安装 vuex
在脚手架 创建项目时勾选vuex的选项系统会自动创建
使用上下间移动,空格选中并回车,完成创建Vue项目 ,组件自动生成并创建vuex实例,
方法二:npm 或Yarn安装
npm install vuex@next --save
yarn add vuex@next --save
四、配置
如果采用脚手架方式进行创建,无需任何操作,可以忽略此步骤
新建store文件->index.js,进行如下配置,在main.js中进行引入
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
//数据,相当于data 存储数据
state: {
},
// 过滤并计算 state的计算属性 在vuex中没有this
getters: {
},
//里面定义方法,操作state方发 更改Vuex中state状态的唯一方法是提交mutations
mutations: {
},
// 操作异步操作mutation
actions: {
},
modules: {
},
})
main.js中 挂载引入
import Vue from 'vue'
import App from '/App.vue'
import router from './router'
import store from './store'
Vue.config.productionTip = false
new Vue({
router,
store,
render:h => h(App)
}).$mount('#app')
五.核心概念
vuex中一共有五个状态 State Getter Mutation Action Module 下面进行详细讲解
5.1 State
提供唯一的公共数据源,所有共享的数据统一放到store的state进行储存,相似与data
在vuex中state中定义数据,可以在任何组件中进行调用
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
//数据,相当于data
state: {
name:"张三",
age:18,
count:0
},
})
调用:
方法一:
在标签中直接使用
<div>{{$store.state.name}}</div> // 输出张三
<p>年龄:{{$store.state.age}}</p> // 输出 年龄:18
方法二:
this.$store.state.全局数据名称
方法三:
从vuex中按需导入mapstate函数 ( mapState为辅助函数 )
import { mapState } from "vuex";
注意:当前组件需要的全局数据,应在Vue实例的计算属性中映射即 computed 属性中
computed: {
...mapState(['name','age'])
}
直接使用
<div>{{$store.state.name}}</div> // 输出张三
<p>年龄:{{$store.state.age}}</p> // 输出 年龄:18
使用辅助函数 mapState 映射
<div>{{ name }}</div> // 输出张三
<p>年龄:{{age}}</p> // 输出 年龄:18
5.2 Mutation
更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的事件类型 (type)和一个回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数:state: {
userInfo: '李四',
age:12}
vuex 实例mutations:{
updateUserInfo(state,payLood) {
state.userInfo = payLood}
}组件 (点击按钮提交修改)用commit修改
methods:{
btn() {
// this.$Store.commit('mutations里的函数名', 载荷)this.$Store.commit('updateUserInfo', {
name: "张三",
age: 18
})}
}
在vuex中定义:
其中参数state参数是必须的,也可以自己传递一个参数,如下代码,进行计数器的加减操作,加法操作时可以根据所传递参数大小进行相加,减法操作没有传参每次减一
state: {
name: "李四",
age: 18,
count: 0
},
mutations: {
addcount(state,num) {
state.count += state.count + num
},
reduce() {
state(state) {
state.count --
}
}
}
在组件中使用:
定义两个按钮进行加减操作
<button @click="btn">count++</button>
<button @click="btn1">count--</button>
methods:{
//加法
btn(){
this.$store.commit("addcount",10) //每次加十
}
//减法
btn1(){
this.$store.commit("reduce")
}
}
方法二:
使用辅助函数进行操作,具体方法同上
methods:{
...mapMutations(["addcount","reduce"]),
btn() {
this.addcount(10)
},
btn1() {
this.reduce()
}
}
也可以直接在@click:btn(10) @click:btn1(10) 进行传参 ,调用
在methods调用该方法 进行参数接收
5.3 Action ——进行异步操作
Action和Mutation相似,一般不用Mutation 异步操作,若要进行异步操作,使用Action原因:为了方便devtools打个快照存下来,方便管理维护。所以说这个只是规范,而不是逻辑的不允许,只是为了让这个工具能够追踪数据变化而已
在vuex中定义:
将上面的减法操作改为异步操作
// 异步操作 mutatons
actions: {
asyncAdd(context) {
// 异步
setTimeout(() => {
context.commit("reduce")
},1000)
}
}
在组件中使用:
方法一:
直接使用 dispatch触发Action函数
this.$store.dispatch("asynAdd")
方法二:
使用辅助函数
...mapActions(['asyncAdd'])
btn2 () {
this.asyncAdd()
}
5.4 Getter
类似于vue中的computed,进行缓存,对于Store中的数据进行加工处理形成新的数据具体操作类似于前几种,这里不做具体说明
getters里的 形参 state 就是 档前vuex实例的state 所以没有this
组件中访问:this.$store.getters.属性名
5.5 Modules
当遇见大型项目时,数据量大,store就会显得很臃肿
为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割:
modules: {
cityModeles: {
namespaced: true,
state: {
cityname:"china"
},
mutations: {
cityfn(state) {
state.cityname = "中国"
}
}
}
}
由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。
为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割:
你可以通过添加
namespaced: true
的方式使其成为带命名空间的模块