一.VueX基本概述:学习VueX首先它是它的应用场景就是多组件共享数据,vuex是vue官方专为 Vue.js 应用程序开发的一种状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化,vuex是vue的一个插件(类似于:vue-router也是一个插件)。
二.特点:一般情况下,只有多个组件均需要共享的数据,才有必要存储在vuex中,对于某个组件中的私有数据,依旧存储在组件自身的data中;不要把全部的数据放在vuex中, 除非要在多个组件之间共享;与eventBus相比:相同点:独立于组件体系,不同点:具有数据响应式的特点。
三.使用:
1.工程化安装 npm install vuex
2.在主入口文件main.js中引入
```
import Vue from 'vue'
import App from './App.vue'
// 在入口文件中引入store
import store from './store/index.js'
Vue.config.productionTip = false
// 挂载到vue的实例上
new Vue({
store: store,
render: h => h(App),
}).$mount('#app')
```
3.五个核心概念:state,mutations,getters,actions,moudules
state:定义数据,它的值是一个对象,用来装所有的公共数据,它的设置方式类似于组件中data数据项的设置方式
1.直接使用this.$store.state.xxx
获取:在代码中:
this.$store.state.xxx
获取:在视图中,可以省略this.
{{$store.state.xxx}}
注意:route
- mapState函数使用,映射使用
原理:用mapState函数把公共数据(vuex.store)映射到组件内部计算属性(computed)中
步骤:
1.按需导入mapState函数
// mapState就是vuex中的一个辅助函数,就是个工具函数,mapState(['msg']): 调用这个函数,传入实参['msg']
import{ mapState} from 'vuex
2.数据映射为计算属性:computed:{ ...mapState(['全局数据名称']) }
export default {
name: 'a',
computed: {
// let res = mapState(['msg'])
// console.log(res) // res的结果是一个对象{msg:function(){}}
//把这个对象展开,合并到computed这个对象中
...mapState(['msg'])
}
}
3.直接使用:{{ msg}}
*用mapState时取别名:
computed: {
...mapState({'新名字': 'vuex.store.state.xxx中的名字'})
// ...mapState({'youname': 'laowang'})用的时候可以用新名youname
}
mapState()中的参数支持两种写法[], {}
mutations:修改数据,存在的意义:在vue中,不推荐直接在组件内部通过this.$store.state.全局数据名称=新值来修改vuex数据,而推荐使用mutation来修改。
直接使用:
state:{
citys:['北京', '上海', '重庆']
}
mutations:{
参数1:必须,表示当前的state
参数2:可选,调用函数add时传入的数据
add1(state, cityName) {
// 在函数内部,修改state中的数据
state.citys.push(cityName)
}
}
在组件内调用:
methods: {
a() {
// 通知vuex这里有个提交,提交的名字是add1提交的数据是新增城市广东
this.$store.commit('mutation的名字add1,'要传递的参数 广东')
}
}
使用mapMutations:就是把mutations中的属性映射到组件的methods上成为当前组件的方法来使用。
// 1.导入mapMutations
import { mapMutations } from 'vuex'
//2.映射
mothods相当于有了两个函数,一个hClick,一个add1
export default {
name: 'b',
methods: {
hClick () {
// 把mapMutations(['xxx']结果合并到methods对象中,相当于给methods添加了一个方法
...mapMutations(['add1'])
}
}
3.使用:this.add1()
用mapMutations取别名:
methods: {
...mapMutations({'新名字':'在vuex中mutations的名字'})
}
getters:需要从现有的state中加工派生计算一些新的数据,类似组件内的计算属性
定义:
getters: {
cityNumber (state) {
return state.citys.length
}
}
使用:
直接使用:this.$store.getters.xxx
mapGetters用法:computed: {
...mapGetters(['xxx'])
mapGetters({'newName': 'xxx'})
}
actions:间接调用mutations来修改数据,可以包含异步请求
步骤:发送ajax获取数据,间接调用mutations来修改state中的数据
mutations:{
addCity(state, newCity){
state.citys.push(newCity)
}
}
actions: {
// context:可以理解为当前的vuex的实例
getCitys(context,params){
axios({url:'',mrthods:'GET'}).then(res =>
// 调用mutations
context.commit({
type: 'addCity'
})
)
}
}
调用:
直接使用:created () {
this.$store.dispatch('actions的名字getCitys')
}
mrthods: {
...mapActions: mapActions(['getCitys'])
...mapActions({newName: 'getCitys'})
}
modules:拆分复杂数据
定义两个模块 user和setting
modules: {
user: {
state: {
token: '12345'
},
mutations:{},
getters: {},
actions:{}
},
setting: {
state: {
name: 'Vuex实例'
},
mutations:{},
getters: {},
actions:{}
}
注意: 1.访问模块中的数据,要加上模块名
{{ $store.state.模块名. 数据项名}} ==> {{ $store.state.user.token}}
2.访问模块中的mutations不需要额外补充模块名,这种方式不推荐,可以用namespaced命名空间
3.命名空间namespaced:
user: {
// 高封闭性
namespaced: true,
state: {
token: '12345'
},
mutations: {
// 这里的state表示的是user的state
updateToken (state) {
state.token = 123
}
}
},
调用:
1.直接调用-带上模块的属性名路径:
test () {
this.$store.dispatch('user/updateToken') // 直接调用方法
}
2.辅助函数-带上模块的属性名路径
methods: {
...mapMutations(['user/updateToken']),
test () {
this['user/updateToken']()
}
}
<button @click="test">修改token</button>
3.createNamespacedHelpers创建基于某个命名空间辅助函数
import { mapGetters, createNamespacedHelpers } from 'vuex'
const { mapMutations } = createNamespacedHelpers('user')
<button @click="updateToken">修改token2</button>
结论:
- 修改state状态必须通过
mutations - **
mutations**只能执行同步代码,类似ajax,定时器之类的代码不能在mutations中执行 - 执行异步代码,要通过actions,然后将数据提交给mutations才可以完成
- state的状态即共享数据可以在组件中引用
- 组件中可以调用action