搜索
首页web前端js教程vuex之详细介绍中文文档

Vuex 是一个专为Vue.js应用程序开发的状态管理模式,集中式存储管理应用的所有组件状态。本文给大家介绍了vuex使用文档,需要的朋友参考下吧

Vuex是什么?

Vuex 是一个专为 Vue.js应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 也集成到Vue 的官方调试工具 devtools extension,提供了诸如零配置的 time-travel调试、状态快照导入导出等高级调试功能。

安装

直接下载CDN 引用

  <script src="/path/to/vue.js"></script>
  <script src="/path/to/vuex.js"></script>

npm 

npm install vuex --save

在一个模块化的打包系统中,您必须显式地通过Vue.use() 来安装Vuex。  

import Vue from &#39;vue&#39;
  import Vuex from &#39;vuex&#39;
  Vue.use(Vuex)

  Vuex 是一个专为Vue.js 应用程序开发 的状态管理模式,集中式存储管理应用的所有组件状态。

  状态管理包含以下几个部分状态:

     state 驱动应用的数据源;

      view 以生命方式将 state 映射到视图。

       actions  响应在view 上的用户书输入导致的状态变化。

 帮助我们管理共享状态,中大型单页面应用。

   state

    单一状态树 ,Vuex使用单一状态树用一个对象就包含了全部的应用层级状态。

    在Vue 组件中获得Vuex 状态。

    由于Vuex的状态存储是响应式的,从store 实例中读取状态最简单的方法

    就是在计算属性中返回某个状态。

    创建一个Counter 组件   

 const Counter = {
        template: &#39;<p>{{ count }}</p>&#39;
        computed: {
          count (){
            return store.state.count
          }
        }
      }

  每次 store.state.count 变化的时候,都会重新求取计算属性,并且触发更新相关的DOM

    Vuex 通过 store 选项,提供了一种机制将状态从根组件『注入』到每一个子组件中(需调用 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;
      })

   通过在根实例中注册 store 选项,该store 实例会注册入到跟组件下的所有子组件,且子组件能通过 this.$store 访问到。更新 counter 的实现:     

 const Counter = {
        template : &#39;<p>{{ count }}</p>&#39;,
        computed: {
          count this.$store.state.count
          }
      }

    mapState 辅助函数

      当一个组件需要获取多个状态时候,将这些状态都声明为计算属性会有些冗余。

      为了解决这个问题,我们可以使用 mapState 辅助函数帮助我们生成计算属性。      

// 在单独构建的版本中辅助函数为 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
                }
            })
         }

    当映射的计算属性的名称与 state 的子节点名称相同时,我们也可以给 mapState 传一个字符串数组。          

computed: mapState([
            // 映射 this.count 为 store.state.count
            &#39;count&#39;
          ])

    组件仍然保有局部状态。

    Getters

      有时候我们需要从store 中的state 中 的state 中派生一些状态,列如对列表进行过滤并计算。 

    computed: {
        doneTodosCount() {
            return this.$store.state.todos.filter(todo => todo.done).length
        }
      }

    Vuex 允许我们再store 中定义getters (可以认为是stroe 的计算属性)

      Getters 接受state 作为其第一个参数。        

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)
              }
            }
          })

    Getters 会暴露为store.getters 对象:   

 store.getters.doneTodos // [{id:1,text: &#39;...&#39;,done:true}]

    Getter 也可以接受其他getters 作为第二个参数:     

getters: {
          doneTodosCount: (state,getters) => {
            return getters.doneTodos.length
          }
      }
    store.getters.doneTodosCount // -> 1

      我们可很容易的在任何组件中使用       

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

    mapGetters 辅助函数

    mapGetters 辅助函数仅仅是 store 中的getters 映射到局部计算属性。      

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

   如果你想讲一个getter 属性另取名字,使用对象性时

mapGetters({
         // 映射 this.doneCount 为 store.getters.doneTodosCount
          doneCount: &#39;doneTodosCount&#39;
      })

          Mutations

        更改Vuex 的store 中的状态的唯一方式就是提交 mutation Vuex 中的mutation

        非常类似于事件,每个 mutation 都有一个字符串的 事件类型 和回调函数。这个回调函数就是我们实际进行状态更改的地方。并且他会接受 state 作为第一个参数。    

const store = new Vue.Store({
        state: {
            count: 1
        },
      mutations: {
          inctement (state) {
          state.count++
        }
      }
    })

   当触发一个类型为 increment 的 mutation 时,调用此函数。”要唤醒一个

     mutation handler,你需要以相应的 type 调用 store.commit 方法      

store.commit(&#39;increment&#39;)

      提交载荷(Payload)

      你可以向store.commit 传入额外的参数,即mutation 的载荷:            

mutations: {
          increment (state, n) {
          state.count += n
        }
      }
      store.commit(&#39;increment&#39;, 10)

   在大多数情况下,载荷应该是一个对象,这样可以包含多个字段并且记录 mutation会更易读。     

mutations: {
      increment (state,payload) {
        state.count += payload.amount
        }
      }
      store.commit(&#39;increment&#39;, {
        amount:10
    })

  对象风格的提交方式

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

 store.commit({
        type: &#39;increment&#39;,
        amount:10
      })

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

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

  Mutations 需遵守vue 的响应规则

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

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

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

Vue.set(obj, &#39;newProp&#39;, 123)

      使用新对象代替老对象  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
            }
          }
      })

mutation 必须是同步函数

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

 mutations: {
          someMutation (state) {
            api.callAsyncMethod(() => {
                state.count++
            })
          }
        }

 在组件中提交 Mutations

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

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

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;)
          }
        }
    })

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

actions: {
      increment({commit}){
        commit(&#39;increment&#39;)
      }
    }

分发 Action

    Action 通过 store.dispatch 方法触发:     

store.dispatch(&#39;increment&#39;)

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

 actions: {
      incrementAsync({commit}){
        setTimeout(() => {
          commit(&#39;increment&#39;)
        },1000)
        }
      }

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

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

 在组件中分发 Action

    你在组件中使用 this.$store.dispatch('xxx') 分发 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;)
        })
      }

组合 Actions

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

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

actions: {
        actionA({commit}){
        return new Promise((resolve)=>{
            setTimeout (() => {
              commit(&#39;someMutation&#39;)
              resolve()
            },1000)
          })
        }
      }

  现在你可以     

store.dispatch(&#39;actionA&#39;).then(()=>{
        //...
      })

  在另一个 action 中也可以  

actions: {
      actionB({dispath,commit}){
        return dispatch(&#39;actionA&#39;).then(() => { 
        commit(&#39;someOtherMutation&#39;)
      })
    }
    }

  我们利用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())
        }
      }

    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 的状态

模块的局部状态

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

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

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

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

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

const moduleA = {
          getters: {
            getters: {
              sumWithRootCount (state,getters,rootState) {
                      return state.count + rootState.count
                }
              }
          }
        }

命名空间

    模块内部的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)
      }
    }

模块动态注册

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

store.registerModule(&#39;myModule&#39;,{})

      模块的状态将是 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 # 产品模块

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

相关文章:

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

有关Vue打包map文件的问题

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

以上是vuex之详细介绍中文文档的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
在JavaScript中替换字符串字符在JavaScript中替换字符串字符Mar 11, 2025 am 12:07 AM

JavaScript字符串替换方法详解及常见问题解答 本文将探讨两种在JavaScript中替换字符串字符的方法:在JavaScript代码内部替换和在网页HTML内部替换。 在JavaScript代码内部替换字符串 最直接的方法是使用replace()方法: str = str.replace("find","replace"); 该方法仅替换第一个匹配项。要替换所有匹配项,需使用正则表达式并添加全局标志g: str = str.replace(/fi

构建您自己的Ajax Web应用程序构建您自己的Ajax Web应用程序Mar 09, 2025 am 12:11 AM

因此,在这里,您准备好了解所有称为Ajax的东西。但是,到底是什么? AJAX一词是指用于创建动态,交互式Web内容的一系列宽松的技术。 Ajax一词,最初由Jesse J创造

10个JQuery Fun and Games插件10个JQuery Fun and Games插件Mar 08, 2025 am 12:42 AM

10款趣味横生的jQuery游戏插件,让您的网站更具吸引力,提升用户粘性!虽然Flash仍然是开发休闲网页游戏的最佳软件,但jQuery也能创造出令人惊喜的效果,虽然无法与纯动作Flash游戏媲美,但在某些情况下,您也能在浏览器中获得意想不到的乐趣。 jQuery井字棋游戏 游戏编程的“Hello world”,现在有了jQuery版本。 源码 jQuery疯狂填词游戏 这是一个填空游戏,由于不知道单词的上下文,可能会产生一些古怪的结果。 源码 jQuery扫雷游戏

如何创建和发布自己的JavaScript库?如何创建和发布自己的JavaScript库?Mar 18, 2025 pm 03:12 PM

文章讨论了创建,发布和维护JavaScript库,专注于计划,开发,测试,文档和促销策略。

jQuery视差教程 - 动画标题背景jQuery视差教程 - 动画标题背景Mar 08, 2025 am 12:39 AM

本教程演示了如何使用jQuery创建迷人的视差背景效果。 我们将构建一个带有分层图像的标题横幅,从而创造出令人惊叹的视觉深度。 更新的插件可与JQuery 1.6.4及更高版本一起使用。 下载

如何在浏览器中优化JavaScript代码以进行性能?如何在浏览器中优化JavaScript代码以进行性能?Mar 18, 2025 pm 03:14 PM

本文讨论了在浏览器中优化JavaScript性能的策略,重点是减少执行时间并最大程度地减少对页面负载速度的影响。

Matter.js入门:简介Matter.js入门:简介Mar 08, 2025 am 12:53 AM

Matter.js是一个用JavaScript编写的2D刚体物理引擎。此库可以帮助您轻松地在浏览器中模拟2D物理。它提供了许多功能,例如创建刚体并为其分配质量、面积或密度等物理属性的能力。您还可以模拟不同类型的碰撞和力,例如重力摩擦力。 Matter.js支持所有主流浏览器。此外,它也适用于移动设备,因为它可以检测触摸并具有响应能力。所有这些功能都使其值得您投入时间学习如何使用该引擎,因为这样您就可以轻松创建基于物理的2D游戏或模拟。在本教程中,我将介绍此库的基础知识,包括其安装和用法,并提供一

使用jQuery和Ajax自动刷新DIV内容使用jQuery和Ajax自动刷新DIV内容Mar 08, 2025 am 12:58 AM

本文演示了如何使用jQuery和ajax自动每5秒自动刷新DIV的内容。 该示例从RSS提要中获取并显示了最新的博客文章以及最后的刷新时间戳。 加载图像是选择

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前By尊渡假赌尊渡假赌尊渡假赌

热工具

Atom编辑器mac版下载

Atom编辑器mac版下载

最流行的的开源编辑器

Dreamweaver Mac版

Dreamweaver Mac版

视觉化网页开发工具

安全考试浏览器

安全考试浏览器

Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一个PHP/MySQL的Web应用程序,非常容易受到攻击。它的主要目标是成为安全专业人员在合法环境中测试自己的技能和工具的辅助工具,帮助Web开发人员更好地理解保护Web应用程序的过程,并帮助教师/学生在课堂环境中教授/学习Web应用程序安全。DVWA的目标是通过简单直接的界面练习一些最常见的Web漏洞,难度各不相同。请注意,该软件中

mPDF

mPDF

mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),