zoukankan      html  css  js  c++  java
  • Vuex 状态管理

    安装:

    npm install vuex --save
    npm install es6-promise --save  //依赖promise

    绑定:

    import Vue from 'vue'
    import Vuex from 'vuex'
    
    Vue.use(Vuex)
    
    import 'es6-promise/auto'

    Vuex是啥?

      Vuex是Vue应用程序开发的状态管理模式,即用于存储大量Vue组件都是使用的共享的数据,并且都可以对数据进行相关的操作,实现响应式数据。(就好像是类的原型,所有的实例对象都可以操作)

    为啥要使用Vuex进行状态的管理呢?

      当很多个组件都要使用同一个数据对象的时候,使用原来的父向子传递数据的方式,需要一级一级的实现数据的调用,如果使用vuex可以实现直接使用。

     Vuex 是单一状态树:

      也就是说整个应用程序中只是使用一个store实例对象,所有的数据都保存在该store对象上(类似于单例模式)

     

     Vuex的特点:

      1.Vuex的状态储存是响应式的,也就是说,当在某个组件中使得数据改变了,则其他的组件中的该数据也会更新。

      2.你不能直接改变 store 中的状态,只能使用commit体骄傲mutation实现数据改变

    Vuex目录结构:

      

     Store的创建:

    const store = new Vuex.Store({
      state: {
        count: 0  //组件中的获取方式 this.$store.state.count
      },
      mutations: { increment (state) { //调用方式:this.$store.commit('increment') state.count++ } }
     ,
     actions,getters,moudles
    })

     state 

      保存着多个组件中共享的状态或是数据

    this.$store.state.count //this.$store 就是生成的store对象 获取一个状态时
    
    //获取多个组件的时候

    computed:mapState({ count:state
    =>state.counter, //可以直接使用state不需要再通过$store来使用 countAlias:'counter', //这里调用的是state中的counter数据 countPlusLocalState(state){ //可将store中的 数据和当前组件中的数据一起使用 return state.counter+ this.counter } })
    //简写形式
     computed:mapState([
            'counter' //counter是state中的数据 类似于router:router 简化成 router的使用
            //如果当前组件中存在和state属性相同的key就会覆盖state中的数据调用本地数据
       ]) 
    //mapState和局部计算属性的混用
    computed: {
      localComputed () { /* ... */ },
      // 使用对象展开运算符将此对象混入到外部对象中
      ...mapState({
        // ...
      })
    }
     

     Getter:

      类似于store 的计算属性,当他的依赖值发生变化的时候被重新计算

      

    //通过属性访问

    const getters = { //store中设置 doneTodos:state=>{ return state.info.filter(item=>item.age>8) //对state进行公共的处理的数据 }, donTodosCount:()=>{ // state.info.filter(item=>item.age>8).length 是2 有问题 return getters.doneTodos.length //这样写的数据是1 } }
    {{this.$store.getters.doneTodos}} //组件中的调用方式
    {{ this.$store.getters.donTodosCount}} //这里有问题
     //通过方法访问
        geTAgeById:(state) => (id) => {
            return state.info.find(item =>item.id == id);
        }
     {{this.$store.getters.geTAgeById(1)}} //通过方法调用getters
    

     

    //组件中调用多个getter计算属性
     computed:{
    
            ...mapState({
            count:state=>state.counter, //可以直接使用state不需要再通过$store来使用
            countAlias:'counter', //这里调用的是state中的counter数据
            countPlusLocalState(state){
                return state.counter+this.coutner
            },
    //简写 ,也可使用{} ...mapGetters([
    "doneTodos", "donTodosCount", "geTAgeById", //计算方法也可以直接这样使用 ]) }) }
    {{doneTodos}}
    {{donTodosCount}}
    {{geTAgeById(1)}} //计算方法调用
    

      

    Mutation:

      提交commit是更新Vuex中state的唯一方法。只能执行同步方法。如果执行异步方法,vue开发工具就无法跟踪数据。

      注意:1.只有修改store中state一些的数据有效,对于新生产的state数据或是属性,并不影响。

      2.当需要在对象上添加新的属性时,

    Vue.set(obj,'newProp',124);
    或是
    satte.obj = {...state.obj,newProp:123} //以旧换新
    

      3.可以使用常量来替换Mutation事件的类型

    const INCREMENT = ‘increment’;
    使用
    [ INCREMENT] (state){
      //code  
    }
    

      


    const mutations = { increment:(state)=>{ state.counter++; }, increment1:function(state,payload){ //payload也可是对象 state.counter +=payload; } }
    methods:{
          increment:function(){ //注意this指向问题
              this.$store.commit("increment")
          } ,
          increment1:function(){
              //参数也可以是对象
              this.$store.commit("increment1",5);
          //或是 this.$store.commit({
          // type:"increment1"
            amount:10
          })
      } 
    },

    //多个mutation被使用时
    methods: {
        ...mapMutations([
          'increment', // 将 `this.increment()` 映射为 `this.$store.commit('increment')`
    
          // `mapMutations` 也支持载荷:
          'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.commit('incrementBy', amount)`
        ]),
        ...mapMutations({
          add: 'increment' // 将 `this.add()` 映射为 `this.$store.commit('increment')`
        })
      }
     

    Action:

      Action和mutation基本相同,但是iaction提交的是mutation 不是直接变更状态 ,可以执行异步操作。

       

    const actions = {
        increment:function(context){ //context 和 store实例对象有相同的方法和属性,但不是同一个
            context.commit("increment")
        }
    }

    //传递参数
    store.dispatch('incrementAsync', {
      amount: 10
    })
    
    // 以对象形式分发
    store.dispatch({
      type: 'incrementAsync',
      amount: 10
    })
     
      asyncIncrement:function(){
              this.$store.dispatch("increment"); //使用dispath调用 actions方法
          }
    
    //多个异步actions
    
    methods: {
        ...mapActions([
          'increment', // 将 `this.increment()` 映射为 `this.$store.dispatch('increment')`
    
          // `mapActions` 也支持载荷:
          'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.dispatch('incrementBy', amount)`
        ]),
        ...mapActions({
          add: 'increment' // 将 `this.add()` 映射为 `this.$store.dispatch('increment')`
        })
      }
    
    //组合action :通过Promise或是 async语法糖

    Module:

      由于store是单一树的情况,可能出现大量数据都保存在state中的情况,于是可以将其分成多个模块onst moduleA = {

      state: { ... },
      mutations: { ... },
      actions: { ... },
      getters: { ... }
    }
    
    const moduleB = {
      state: { ... },
      mutations: { ... }, //这里 mutations中写的函数的state参数的是模块局部的状态
      actions: { ... }
    } const store = new Vuex.Store({ modules: { a: moduleA, b: moduleB } }) store.state.a // -> moduleA 的状态 调用的时候和之前的基本相同。 store.state.b // -> moduleB 的状态
    {{this.$store.state.moduleQ.msg}}
       

      

    const moduleA = {
      // ...
      actions: {
        incrementIfOddOnRootSum ({ state, commit, rootState }) {
      //rootState 表示根节点中的state状态
    if ((state.count + rootState.count) % 2 === 1) { commit('increment') } } } }
    {{this.$store.getters.add}}
    //对于子modules中的getters mutations actions都是直接这样调用

     开启严格模式: 

    const store = new Vuex.Store({
        state,
        mutations,
        actions,
        getters,
        modules,
        strict: true//开启严格模式
    });

    Vuex 的Moldle的命名空间,插件


      

      

  • 相关阅读:
    opengl编程指南
    Binder机制1---Binder原理介绍
    [Android]使用platform密钥来给apk文件签名的命令
    IntentFilter
    最高分是多少
    Spring注入
    Bean容器的初始化
    Spring中的Junit
    IOC
    接口及面向接口编程
  • 原文地址:https://www.cnblogs.com/panjingshuang/p/12028876.html
Copyright © 2011-2022 走看看