Maison > interface Web > js tutoriel > le corps du texte

Introduction détaillée aux documents chinois de vuex

亚连
Libérer: 2018-06-12 16:21:35
original
9593 Les gens l'ont consulté

Vuex est un modèle de gestion d'état développé spécifiquement pour les applications Vue.js. Il stocke et gère de manière centralisée l'état de tous les composants de l'application. Cet article présente la documentation d'utilisation de Vuex à tous les amis qui en ont besoin peuvent s'y référer

Qu'est-ce que Vuex ?

Vuex est un modèle de gestion d'état développé spécifiquement pour les applications Vue.js. Il utilise un stockage centralisé pour gérer l'état de tous les composants de l'application et utilise les règles correspondantes pour garantir que l'état change de manière prévisible. Vuex est également intégré à l'extension devtools de l'outil de débogage officiel de Vue, fournissant des fonctions de débogage avancées telles que le débogage de voyage dans le temps sans configuration, l'importation et l'exportation d'instantanés d'état, etc.

Installer

Référence CDN de téléchargement direct

  <script src="/path/to/vue.js"></script>
  <script src="/path/to/vuex.js"></script>
Copier après la connexion

npm

npm install vuex --save
Copier après la connexion

Dans un système de packaging modulaire, vous devez installer Vuex explicitement via Vue.use(). ​

import Vue from &#39;vue&#39;
  import Vuex from &#39;vuex&#39;
  Vue.use(Vuex)
Copier après la connexion

Vuex est un modèle de gestion d'état développé spécifiquement pour les applications Vue.js. Il stocke et gère de manière centralisée l'état de tous les composants de l'application.

La gestion de l'état comprend les états partiels suivants :

L'état pilote la source de données de l'application

la vue mappe l'état aux vues de manière réaliste ;

  actions Répondre aux changements d'état provoqués par la saisie de l'utilisateur sur la vue.

Aidez-nous à gérer le statut partagé pour les applications d'une seule page de taille moyenne et grande.

 state

  Arbre d'état unique, Vuex utilise un arbre d'état unique pour contenir tous les états au niveau de l'application avec un seul objet.

  Obtenez l'état de Vuex dans le composant Vue.

Étant donné que le stockage d'état de Vuex est réactif, le moyen le plus simple de lire l'état à partir de l'instance du magasin

est de renvoyer un certain état dans une propriété calculée.

Créer un composant Counter

 const Counter = {
        template: &#39;<p>{{ count }}</p>&#39;
        computed: {
          count (){
            return store.state.count
          }
        }
      }
Copier après la connexion

Chaque fois que store.state.count change, les propriétés calculées seront récupérées et le DOM concerné sera mis à jour

. Vuex Grâce à l'option store, un mécanisme est fourni pour "injecter" l'état du composant racine dans chaque sous-composant (besoin d'appeler Vue.use(Vuex)) : ​​

 const app = new Vue({
        el:&#39;#app&#39;,
        // 把 store 对象提供给 “store” 选项,这可以把 store 的实例注入所 有的子组件
        store,
        components: {Counter},
      template: &#39;
        <p class="app">
          <counter></counter>
        </p>
        &#39;
      })
Copier après la connexion

En enregistrant le store dans l'option de l'instance racine, l'instance du magasin sera enregistrée dans tous les sous-composants du composant et les sous-composants seront accessibles via this.$store. Mettre à jour l'implémentation du compteur :   

 const Counter = {
        template : &#39;<p>{{ count }}</p>&#39;,
        computed: {
          count this.$store.state.count
          }
      }
Copier après la connexion

 fonction auxiliaire mapState

 Lorsqu'un composant doit obtenir plusieurs états, déclarez-y ces états. il y a une certaine redondance pour les propriétés calculées.

Pour résoudre ce problème, nous pouvons utiliser la fonction d'assistance mapState pour nous aider à générer des propriétés calculées.   

// 在单独构建的版本中辅助函数为 Vuex.mapState
      import { mapState } from &#39;vuex&#39;
        export default {
          computed: mapState({
            // 箭头函数可以使代码更简洁
              count: state => state.count,
            // 传字符串参数 ‘count&#39; 等同于 ‘state => state.count&#39;
              countAlias: &#39;count&#39;,
            // 为了能够使用 ‘this&#39; 获取局部状态,必须使用常规函数
              countPlusLocalState(state) {
                  return state.count + this.localCount
                }
            })
         }
Copier après la connexion

  Lorsque le nom de l'attribut calculé mappé est le même que le nom du nœud enfant de l'état, nous pouvons également transmettre un tableau de chaînes à mapState.     

computed: mapState([
            // 映射 this.count 为 store.state.count
            &#39;count&#39;
          ])
Copier après la connexion

  Les composants conservent toujours l'état local.

 Getters

Parfois, nous devons dériver un état à partir de l'état dans le magasin, comme filtrer et calculer la liste.

    computed: {
        doneTodosCount() {
            return this.$store.state.todos.filter(todo => todo.done).length
        }
      }
Copier après la connexion

Vuex nous permet de définir des getters dans le magasin (peuvent être considérés comme des propriétés calculées du magasin)

Les getters acceptent l'état comme premier paramètre.

const store = new Vuex.Store({
            state: {
              todos:[
                {id:1, text: &#39;...&#39; ,done: true},
                {id:2,text:&#39;...&#39;,done: false}
              ]
            },
          getters: {
            doneTodos: state => {
                return state.todos.filter(todo=> todo.done)
              }
            }
          })
Copier après la connexion

Les getters sont exposés en tant qu'objets store.getters :

 store.getters.doneTodos // [{id:1,text: &#39;...&#39;,done:true}]
Copier après la connexion

Les getters peuvent également accepter d'autres getters comme seconds paramètres :

getters: {
          doneTodosCount: (state,getters) => {
            return getters.doneTodos.length
          }
      }
    store.getters.doneTodosCount // -> 1
Copier après la connexion

Nous pouvons C'est facile à utiliser dans n'importe quel composant

 computed: {
          doneTodosCount() {
            return this.$store.getters.doneTodosCount
        }
      }
Copier après la connexion

Fonction d'assistance MapGetters

La fonction d'assistance mapGetters est simplement un getter mappé à une propriété calculée locale dans le magasin.

import {mapGetter} form &#39;vuex&#39;
      export default {
        computed: {
          // 使用对象展开运算符将 getters 混入
          ...mapGetters([
              ‘doneTodosCount&#39;,
              &#39;anotherGetter&#39;
            ])
          }
        }
Copier après la connexion

Si vous souhaitez donner un autre nom à une propriété getter, utilisez les propriétés de l'objet

mapGetters({
         // 映射 this.doneCount 为 store.getters.doneTodosCount
          doneCount: &#39;doneTodosCount&#39;
      })
Copier après la connexion

La seule façon de changer l'état dans le magasin Vuex est via des mutations

Soumettez simplement la mutation

dans Vuex. Très similaire à un événement, chaque mutation a un type d'événement de chaîne et une fonction de rappel. Cette fonction de rappel est l'endroit où nous effectuons réellement les changements d'état. Et il acceptera l'état comme premier paramètre. ​​

const store = new Vue.Store({
        state: {
            count: 1
        },
      mutations: {
          inctement (state) {
          state.count++
        }
      }
    })
Copier après la connexion

Cette fonction est appelée lorsqu'une mutation de type incrément est déclenchée. "Pour réveiller un

                                    ulate in'. Passer des paramètres supplémentaires, la charge utile de la mutation :​​​​​​​​​​​​​​

mutations: {
      increment (state,payload) {
        state.count += payload.amount
        }
      }
      store.commit(&#39;increment&#39;, {
        amount:10
    })
Copier après la connexion

  对象风格的提交方式

    提交mutation 的另一种方式直接使用包含 type 属性的对象:    

 store.commit({
        type: &#39;increment&#39;,
        amount:10
      })
Copier après la connexion

  当使用对象风格的提交方式,整个对象作为载荷传给mutation 函数,因此handler保持不变:     

 mutations: {
        increment (state, payload) {
          state.count += payload.amount
        }
       }
Copier après la connexion

  Mutations 需遵守vue 的响应规则

    既然Vuex的store 中的状态是响应式的,那么当我们变更状态时,监视状态的vue更新 ,这也意味值Vue 中的mutation 也需要与使用 Vue 一样遵守一些注意事项。

      1. 最好提前在你的store 中初始化好所有的所需要的属性。

      2.当需要在对象上提交新属性时,你应该使用        

Vue.set(obj, &#39;newProp&#39;, 123)
Copier après la connexion

      使用新对象代替老对象 state.obj= {...state.obj ,newProp: 123}

      使用常量替代 Mutation 事件类型

      使用常量替代 mutation 事件类型在各种 Flux 实现中是很常见的模式     

export const SOME_MUTATION = &#39;SOME_MUTATION&#39;;
      import Vuex from &#39;vuex&#39;
      import {SOME_MUTATION } from &#39;./mutation-types&#39;
      const store = new Vuex.Store({
          state: {...}
          mutations: {
            // 我们可以使用 ES2015 风格的计算属性命名功能来使用一个常量作为函数名
            [SOME_MUTATION] (state) {
            // mutate state
            }
          }
      })
Copier après la connexion

mutation 必须是同步函数

    一条重要的原则是记住 mutation 必须是同步函数。       

 mutations: {
          someMutation (state) {
            api.callAsyncMethod(() => {
                state.count++
            })
          }
        }
Copier après la connexion

在组件中提交 Mutations

    你可以在组件中使用 this.$store.commit('xxx') 提交 mutation,或者使使用 mapMutations辅助函数将组建中的methods 映射为 store.commit 调用 (需要在根节点注入 store)    

import {mapMutations} from &#39;vuex&#39;
      expor default {
        methods: {
          mapMutations([
              methods: {
                mapMutations([
                  &#39;increment&#39; // 映射 this.increment() 为 this.$store.commit(&#39;increment&#39;)
          ]),
        mapMutations({
              add: &#39;increment&#39; // 映射 this.add() 为 this.$store.commit(&#39;increment&#39;)
          })
        }
      ])
      }
    }
Copier après la connexion

Actions

    在mutation 中混异步调用会导致你的程序很难调试。

Actions

    Action 类似于 mutation,不同在于。

    Action 提交的是 mutation ,而不是直接变更状态。

    Action 可以包含任意异步操作。

    注册一个简单的 action    

const store = new Vuex.Store({
      state: {
          count:0
      },
    mutations: {
      increment (state) {
        state.count++
      }
    },
    actions: {
        increment (context){
          context.commit(&#39;increment&#39;)
          }
        }
    })
Copier après la connexion

Action 函数接受一个与store 实例具有相同方法和属性的context 对象,因此你可以调用 context.commit 提交一个mutation,或者通过 context.state 和context.getters 来获取 state 和 getters 当我们在之后介绍到Modules时,你就知道 context 对象为什么不是store 实例本身了。   

actions: {
      increment({commit}){
        commit(&#39;increment&#39;)
      }
    }
Copier après la connexion

分发 Action

    Action 通过 store.dispatch 方法触发:     

store.dispatch(&#39;increment&#39;)
Copier après la connexion

    我们可以在 action 内部执行异步操作。   

 actions: {
      incrementAsync({commit}){
        setTimeout(() => {
          commit(&#39;increment&#39;)
        },1000)
        }
      }
Copier après la connexion

  Actions 支持同样的载荷方式和对象方式进行分发    

 // 以载荷形式分发
    store.dispatch(&#39;incrementAsync&#39;,{
      amount:10
    })
    // 以对象形式分发
      store.dispatch({
        type: &#39;incrementAsync&#39;,
        amount:10
      })
Copier après la connexion

在组件中分发 Action

    你在组件中使用 this.$store.dispatch(&#39;xxx&#39;) 分发 action,或者使用map Actions辅助函数将组件的methods 映射为store.dispatch 调用   

import {mapActions } from 'vuex'
      export default{
        methods:([
          'increment' // 映射 this.increment() 为 this.$store.dispatch(&#39;increment&#39;)
        ])
      mapActions({
          add: 'inctement' // 映射 this.add() 为 this.$store.dispatch(&#39;increment&#39;)
        })
      }
Copier après la connexion

组合 Actions

    Action 通常是异步的,那么如何知道 action 什么时候结束。

    你需要明白 store.dispatch 可以处理被处触发的action 的回调函数返回的Promise并且 store.dispatch 仍旧返回Promise   

actions: {
        actionA({commit}){
        return new Promise((resolve)=>{
            setTimeout (() => {
              commit(&#39;someMutation&#39;)
              resolve()
            },1000)
          })
        }
      }
Copier après la connexion

  现在你可以     

store.dispatch(&#39;actionA&#39;).then(()=>{
        //...
      })
Copier après la connexion

  在另一个 action 中也可以  

actions: {
      actionB({dispath,commit}){
        return dispatch(&#39;actionA&#39;).then(() => { 
        commit(&#39;someOtherMutation&#39;)
      })
    }
    }
Copier après la connexion

  我们利用async/ await   

// 假设 getData() 和 getOther() 返回的是一个 Promis
    actions:{
        async actionA ({commit}){
          commit(&#39;gotData&#39;,await getData())
        },
        async actionB({dispatch,commit}){
          await dispatch(&#39;actionA&#39;) // 等待 actionA 完成
          commit(&#39;goOtherData&#39;, await getOtherData())
        }
      }
Copier après la connexion

    Modules

      使用单一状态树,当应用变的很大的时候,store 对象会变的臃肿不堪。

      Vuex 允许我们将store 分割到模块。每一个模块都有自己的state, mutation,action, getters, 甚至是嵌套子模块从上到下进行类似的分割。     

const moduleA = {
          state: {...},
        mutations: {...}
        actions: {...}
        getters:{...}
        }
    const moduleA = {
        state: {...},
        mutations: {...}
        actions: {...}
      }
    const store = new Vuex.Store({
      modules: {
          a:moduleA,
          b:moduleB
        }
      })
    store.state.a // -> moduleA 的状态
    store.state.b // -> moduleB 的状态
Copier après la connexion

模块的局部状态

    对于模块内部的 mutation 和 getter, 接收的第一个参数是模块的局部状态。  

 const moduleA = {
          state: {count:0},
          mutations: {
            increment (state) {
                // state 模块的局部状态
                state.count++
            }
          },
      getters: {
        doubleCount (state) {
        return state.count * 2
        }
      }
    }
Copier après la connexion

  同样对于模块内部的action, context.state 是局部状态,根节点的窗台石context.rootState:    

const moduleA = {
          actions: {
          incrementIfOddOnRootSum ({state, commit ,rootState}) {
            if((state.count + rootState.count) %2 ===1){
                commit(&#39;increment&#39;)
          }
         }
        }
      }
Copier après la connexion

对于模块内部的getter,跟节点状态会作为第三个参数:     

const moduleA = {
          getters: {
            getters: {
              sumWithRootCount (state,getters,rootState) {
                      return state.count + rootState.count
                }
              }
          }
        }
Copier après la connexion

命名空间

    模块内部的action, mutation , 和 getter 现在仍然注册在全局命名空间 这样保证了多个模块能够响应同一 mutation 或 action. 也可以通过添加前缀 或者 后缀的

      方式隔离各个模块,以免冲突。     

// 定义 getter, action , 和 mutation 的名称为常量,以模块名 ‘todo&#39; 为前缀。
        export const DONE_COUNT = &#39;todos/DONE_COUNT&#39;
        export const FETCH_ALL = &#39;todos/FETCH_ALL&#39;
        export const TOGGLE_DONE = &#39;todos/TOGGLE_DONE&#39;
          import * as types form &#39;../types&#39;
    // 使用添加了解前缀的名称定义, getter, action 和 mutation
     const todosModule = {
        state : {todo: []},
        getters: {
          [type.DONE_COUNT] (state) {
          }
      }
    actions: {
        [types.FETCH_ALL] (context,payload) {
       }
      },
    mutations: {
        [type.TOGGLE_DONE] (state, payload)
      }
    }
Copier après la connexion

模块动态注册

    在store 创建之后,你可以使用 store.registerModule 方法注册模块。     

store.registerModule(&#39;myModule&#39;,{})
Copier après la connexion

      模块的状态将是 store.state.myModule.

      模块动态注册功能可以使让其他Vue 插件为了应用的store 附加新模块

      以此来分割Vuex 的状态管理。

    项目结构

      Vuex 并不限制你的代码结构。但是它规定了一些需要遵守的规则:

        1.应用层级的状态应该集中到单个store 对象中。

        2.提交 mutation 是更改状态的唯一方法,并且这个过程是同步的。

        3.异步逻辑应该封装到action 里面。

          只要你遵守以上规则,如何组织代码随你便。如果你的 store 文件太大,只需将 action、mutation、和 getters 分割到单独的文件对于大型应用,我们会希望把 Vuex 相关代码分割到模块中。下面是项目结构示例

├── index.html
├── main.js
├── api │ 
  └── ... # 抽取出API请求
├── components
│ ├── App.vue
│ └── ...
└── store 
  ├── index.js  # 我们组装模块并导出 store 的地方 
  ├── actions.js  # 根级别的 action 
  ├── mutations.js  # 根级别的 mutation 
  └── modules  
     ├── cart.js  # 购物车模块  
    └── products.js # 产品模块
Copier après la connexion

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

使用vue2.0如何实现前端星星评分功能组件

有关Vue打包map文件的问题

使用Node.js实现压缩和解压缩功能

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal