再学VueX

115 阅读3分钟

一.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}}

注意:store是固定写法,表示定义的newVuex.store()对象,相当于store是固定写法,表示定义的new Vuex.store()对象,相当于route

  1. 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>

    

结论:

  1. 修改state状态必须通过mutations
  2. **mutations**只能执行同步代码,类似ajax,定时器之类的代码不能在mutations中执行
  3. 执行异步代码,要通过actions,然后将数据提交给mutations才可以完成
  4. state的状态即共享数据可以在组件中引用
  5. 组件中可以调用action