zoukankan      html  css  js  c++  java
  • Vuex的基本原理和简单使用

    什么是Vuex,有什么用?

    Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。

    普通的Vue状态自管理在遇到多个视图共同依赖同一状态,或者会改变同一状态时,会遇到难以管理,难以维护的麻烦。为了解决这个麻烦,Vue官方基于全局单例模式提供了Vuex状态管理框架。

    在Vuex框架中,Vue视图,状态,数据之间的关系如下图所示:

    image

    什么时候应该使用Vuex,什么时候不要使用?

    如果您不打算开发大型单页应用,使用 Vuex 可能是繁琐冗余的。确实是如此——如果您的应用够简单,您最好不要使用 Vuex。一个简单的 store 模式就足够您所需了。但是,如果您需要构建一个中大型单页应用,您很可能会考虑如何更好地在组件外部管理状态,Vuex 将会成为自然而然的选择。

    如何使用Vuex

    创建一个Vuex的状态管理仓库

    1. 安装Vuex框架:
      我们通过如下命令为Vue项目中添加Vuex框架
    npm i Vuex
    

    如下图所示:
    image
    2. 在main.js中引入Vuex框架,并通过use命令加载到Vue中

    import Vuex from 'vuex'
    Vue.use(Vuex)
    
    1. 创建一个store仓库,并把store仓库注册到Vue全局中;store仓库包含state(单一状态树,提供响应式数据),getters(store的计算属性),mutations(改变store状态的方法),actions(处理异步操作,触发mutation)
      image
    const store = new Vuex.Store({
      state:{
      },
      mutations:{
      },
      actions:{
      },
      getters:{
      }
    })
    
    new Vue({
      store,
      render: h => h(App),
    }).$mount('#app')
    
    
    mutations

    更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数.

    你不能直接调用一个 mutation handler。这个选项更像是事件注册:“当触发一个类型为 increment 的 mutation 时,调用此函数。”要唤醒一个 mutation handler,你需要以相应的 type 调用 store.commit 方法

    actions

    Action 类似于 mutation,不同在于:

    1. Action 提交的是 mutation,而不是直接变更状态。
    2. Action 可以包含任意异步操作。
    3. Action的分发使用关键字
    1. 为store仓库创建单一状态树State,并创建mutations方法修改state
    const store = new Vuex.Store({
      state:{
        count:0
      },
      mutations:{
        increment(state,n){
          state.count+=n
          console.log(state.count)
        }
      },
      actions:{
      },
      getters:{
          
      }
    })
    
    1. 到此为止,Vue中的组件就可以使用store状态仓库了。因为在main.js中,我们通过new Vue将store仓库注册到Vue全局中,所以我们在模板中可以通过this.$store的方式获取到我们store仓库。下面的示例展示了通过组件的计算属性computed定义count变量并通过模板语法展现store状态仓库中的count值。
    <template>
      <div id="app">
        {{count}}
      </div>
    </template>
    
    <script>
    
    export default {
      name: 'App',
      components: {
        
      },
      computed:{
        count(){
          return this.$store.state.count
        }
      },
      methods:{
      }
    }
    

    效果如下:
    image
    6. 我们当然可以修改store的count值。我们先采用以前的模板事件来修改。

    <template>
      <div id="app">
        {{count}}
        <input type="button" @click="handleClick" value="Count++" />
      </div>
    </template>
    
    <script>
    
    export default {
      name: 'App',
      components: {
        
      },
      computed:{
        count(){
          return this.$store.state.count
        }
      },
      methods:{
        handleClick(){
          return this.$store.state.count++;
        }
      }
    }
    </script>
    

    效果如下:
    image
    7. 但是Vue并不鼓励我们采用这样的方式来修改store的count值。这样管理依然不方便,很有可能造成混乱。按照上面对mutations的介绍,我们可以猜到Vuex鼓励我们通过mutations对store的state进行修改,这样我们对state的修改过程才会被Vuex记录下来。我们先前在初始化state时,同步初始化了mutations:我们创建了一个叫increment的方法,现在我们只需要调用这个方法即可。每一个mutations中的方法本质都是一个回调函数,处理sate状态的逻辑都包含在里面,接收state参数。mutations方法可以多接收一个额外参数(提交荷载),如果希望传入多个数据,则应该组织成对象再传入(示例中仅仅是一个简单的number)

    mutations:{
        increment(state,n){
          state.count+=n
          console.log(state.count)
        }
      },
    
    1. Vuex中的mutations方法不能被直接调用,必须被actions或模板以commit的形式调用。我们先尝试使用模板直接commit的形式调用(假设我们没有异步操作需要处理,完全可以绕过actions)
    <template>
      <div id="app">
        {{count}}
        <input type="button" name="count2" @click="$store.commit('increment',2)" value="Count+2" /> 
      </div>
    </template>
    
    <script>
    
    export default {
      name: 'App',
      components: {
        
      },
      computed:{
        count(){
          return this.$store.state.count
        }
      },
      methods:{
      }
    }
    </script>
    
    <style>
    </style>
    
    
    1. 我们通过click事件直接对store进行了commit操作,commit调用时传入了两个参数,第一个是回调函数名:increment,另一个是提交荷载:一个整数;效果如下:
      image
    2. 到此为止,我们一直是使用的Vue组件的compute属性展示的sotre。如果有多个组件需要用到此属性,我们要么复制这个函数,或者抽取到一个共享函数然后在多处导入它——无论哪种方式都不是很理想。先前介绍过:getters是sotre的computer,那么我们完全可以在sotre的getters中处理展示逻辑。
    const store = new Vuex.Store({
      state:{
        count:0
      },
      mutations:{
        increment(state,n){
          state.count+=n
          console.log(state.count)
        }
      },
      actions:{
      },
      getters:{
        doubleCount(state){
          return state.count * 2
        }
      }
    })
    
    <template>
      <div id="app">
        {{$store.getters.doubleCount}}
        <input type="button" name="count2" @click="$store.commit('increment',2)" value="Count+2" /> 
      </div>
    </template>
    
    <script>
    
    export default {
      name: 'App',
      components: {
      },
      computed:{
      },
      methods:{
      }
    }
    </script>
    
    <style>
    </style>
    

    效果如下:
    image
    11. 我们一直还没有使用到store的actions。根据官网描述,actions与mutation很像,不同的是用来触发(commit)mutation而不是直接修改状态,最重要的是我们可以在actions中处理异步逻辑,调用远程API等等(如下示例中,利用模拟异步等待);前台调用是使用dispatch关键字调用。

    const store = new Vuex.Store({
      state:{
        count:0
      },
      mutations:{
        increment(state,n){
          state.count+=n
          console.log(state.count)
        }
      },
      actions:{
        increment(state,n){
          setTimeout(() => {
            state.commit('increment',n)
          },1000);
        }
      },
      getters:{
        doubleCount(state){
          return state.count * 2
        }
      }
    })
    
    <template>
      <div id="app">
        {{$store.getters.doubleCount}}
        <input type="button" name="count1" @click="$store.dispatch('increment',3)" value="Count+3" /> 
      </div>
    </template>
    
    <script>
    
    export default {
      name: 'App',
      components: {
        
      },
      computed:{
      },
      methods:{
      }
    }
    </script>
    
    <style>
    </style>
    
    

    效果如下:
    image

    组件调用Vuex关键字的方法总结

    image

  • 相关阅读:
    【shell】两种字符串提取场景的实现
    【batch】批处理文件多参数处理和for循环字符串连接
    【Java】「深入理解Java虚拟机」学习笔记(4)- 类文件结构
    【Java】「深入理解Java虚拟机」学习笔记(2)- JVM内存区域
    【Java】「深入理解Java虚拟机」学习笔记(1)
    【Myeclipse】用Myeclipse10.5搭建C/C++开发环境
    【JDK】JDK模块化(1)-为什么要模块化
    【DOS】文件统计命令
    【java】转:Windows系统下面多个jdk版本切换
    【Web】servlet、filter和listener
  • 原文地址:https://www.cnblogs.com/wenpeng/p/12318124.html
Copyright © 2011-2022 走看看