最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • Vue基础-Vuex

    正文概述 掘金(普通上班族)   2020-12-05   530

    Vuex

    Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

    这是官网给出的解释,看起来很绕。其实通俗的来讲,Vuex就是跟我们的vue项目提供了一个仓库用来存储所有组件的状态/数据等等,仓库只有一个入口和出口,并且有人看管,出入还需要登记记录,这样我们只要看记录就知道谁取了数据,对数据做了什么事。这样我们就把组件共享的状态都抽离了出来,交给Vuex实例来管理,方便我们管理一个大型项目。所以,Vuex主要是用来解决以下问题:

    • 管理项目所有组件的状态
      • 多个视图依赖于同一状态
      • 来自不同视图的行为需要变更同一状态

    通过这样一番操作,我们的组件树就变成了一个单一且庞大的视图,不管在视图树的哪个细枝末节,任何组件都能获取到他的状态和触发行为。并且,通过预设定规则,我们可以强制组件状态间保持独立,代码也就变得更加结构化且易于维护。

    安装

    npm install vuex --save
    

    使用

    import Vue from 'vue'
    import Vuex from 'vuex'
    
    Vue.use(Vuex) //类似koa,通过这种中间件的方式,使用Vuex
    
    const store = new Vuex.Store({  //实例化一个唯一的Vuex.Store实例
      state: {  //用来存放所有组件依赖的、我们需要统一管理的状态
        count: 0
      },
      mutations: {  //用来存放所有组件中需要用到的、我们需要统一管理的、用来改变状态的行为
        increment (state) {
          state.count++
        }
      }
    })
    

    通过这种方式,我们创建了一个最简单的Vuex仓库的实例(一个项目中只能有唯一的Store实例),通过这种单一状态树,我们才能做到强制的管理所有组件的状态。

    state

    上面我们已经实例化了一个状态仓库store,其中的store.state就是用来存放所有状态的单一状态树,那么我们要如何在组件中获取到需要的状态呢。最简单的办法就是用计算属性computed来获取。

    通过计算属性获取

    // 创建一个 Counter 组件
    const Counter = {
      template: `<div>{{ count }}</div>`,
      computed: {
        count () {
          return store.state.count 
        }
      }
    }
    

    通过计算属性中的store.state.count我们就拿到了需要的count数据,如果数据发生了变化,也会自动计算count的计算属性值。但是这样,会让每个组件都依赖全局变量store。所以,Vue提供了一种将store注入到所有子组件当中的方式:

    const app = new Vue({
      el: '#app',
      // 把 store 对象提供给 “store” 选项,这可以把 store 的实例注入所有的子组件
      // store:store,
      store,
      components: { Counter },
      template: `
        <div class="app">
          <counter></counter>
        </div>
      `
    })
    

    这样,就把store对象注入到了所有子组件内部,这样子组件就可以通过this.$store访问到。

    const Counter = {
      template: `<div>{{ count }}</div>`,
      computed: {
        count () {
          return this.$store.state.count
        }
      }
    }
    

    通过以上两种利用计算属性直接监听store.state的方式,就轻松的取到了我们需要的状态信息。但是试想一下,这是只有一个状态,用计算属性写起来还算清晰,但是如果我们组件里面有20个状态需要获取,难道我们要写20个computed的方法吗?显然,虽然可以这么干,但是太不优雅和美观了。

    所以,vuex给我们提供了一种函数方法,优雅的解决这个问题——mapState辅助函数。

    通过mapState辅助函数获取

    mapState辅助函数返回的是一个对象,通过对象运算展开符...,我们就可以吧这个对象传递给该组件,与本地局部状态一起使用。

    computed: {
      // 使用对象展开运算符将此对象混入到外部对象中
      ...mapState({
        'count','...','...'
      })
    }
    

    Getters

    先回想以下使用computed计算属性的最初原因是什么——是我们需要对响应式数据进行一些派生的处理,比如,count++,列表循环等等。我们把这些处理派生逻辑行为的方法都放到了computed里面,进行集中管理。同理,vuex也给我们提供了一种集中管理state派生状态的方法:Getters

    它和计算熟悉一样:

    • 会缓存
    • 会响应数据状态的变化
    • 集中管理所以派生方法

    初始化

    在初始化store对象的时候,Getters接收state作为第一个参数传入,以下是使用方法:

    const store = new Vuex.Store({
      state: {
        todos: [
          { id: 1, text: '...', done: true },
          { id: 2, text: '...', done: false }
        ]
      },
    // 初始化getters
      getters: {
        doneTodos: state => {
          return state.todos.filter(todo => todo.done)
        },
        ...:...,
      }
    })
    

    getter通用暴露给了外部一个store.getters的对象进行访问。

    通过属性访问

    通过属性可以直接获取到我们需要的值store.getters.doneTodes,因此我们就可以在子组件中方便的获取到:

    computed: {
      doneTodosCount () {
        return this.$store.getters.doneTodos
        // return store.getter.doneTodos
      }
    }
    

    通过方法访问

    我们可以让getters返回一个回调函数,实现给getters的传参,这一般在查询数组是非常好使。

    getters: {
      // ...
      getTodoById: (state) => (id) => {
        return state.todos.find(todo => todo.id === id)
      }
    }
    

    通过mapGetters辅助函数获取

    同样,Vuex也给我们提供了一个回调函数,优雅的获取getters。

    import { mapGetters } from 'vuex'
    
    export default {
      // ...
      computed: {
      // 使用对象展开运算符将 getter 混入 computed 对象中
        ...mapGetters([
          'doneTodosCount',
          'anotherGetter',
          // ...
        ])
      }
    }
    

    mutation

    mutation给我们提供了唯一一个变更state状态的方法,通过这个我们就可以监控到所有组件变更state的行为。

    mutation类似于事件监听,每个matation提供了一个字符串的事件类型(Type)和一个回调函数(Handle)。回调函数是用来改变state状态的地方,并且state将会作为函数的第一个参数传入:

    const store = new Vuex.Store({
      state: {
        count: 1
      },
      mutations: {
        increment (state) {
          // 变更状态
          state.count++
        }
      }
    })
    

    调用mutation

    我们调用mutation的时候,不能使用对象进行操作:store.mutations.increament,因为Vuex给我们规定了一个唯一的提交更新的入口: store.commit('increament')

    提交payload

    每个mutation的第二个参数是payload,也就是传入的参数:

    mutations: {
      increment (state, n) {
        state.count += n
      }
    }
    

    这样在外部调用的时候,可以通过payload传入参数:store.commit('increament',10),这样就实现了参数的传入。

    需要注意的一点是:mutation是一个同步函数,如果需要在处理过程中调用异步方法,那么就需要用到下面讲的:action

    action

    actionmutation声明和调用的方式都很类似,唯一不同的是:

    • action内部是支持调用异步方法的。
    • action提交的是mutation,而不是直接更改state

    声明action

    const store = new Vuex.Store({
      state: {
        count: 0
      },
      mutations: {
        increment (state) {
          state.count++
        }
      },
      actions: {
        increment (context) {
          context.commit('increment')
        }
      }
    })
    

    同样的,action也支持设置payload来传入参数,这里就不展开来了。

    调用action

    同样的action提供了dispatch发的方式进行调用:store.dispatch('increment')。或者,可以使用action提供的辅助函数mapActions进行调用:

    import { mapActions } from 'vuex'
    
    export default {
      // ...
      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')`
        })
      }
    }
    

    以上,便是Vuex的基本用法,主要包括:如何初始化、state、getter、mutation、action的用法。


    起源地下载网 » Vue基础-Vuex

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元