美文网首页WebVue
Vuex-Vue状态管理模式

Vuex-Vue状态管理模式

作者: 瑟闻风倾 | 来源:发表于2020-05-26 12:56 被阅读0次

    参考:Vuex详解

    1. Vuex及其作用

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

    作用:如果在一个项目开发中频繁的使用组件传参的方式来同步data中的值,一旦项目变得很庞大,管理和维护这些值将是相当棘手的工作。为此,Vue为这些被多个组件频繁使用的值提供了一个统一管理的工具——VueX。在具有VueX的Vue项目中,我们只需要把这些值定义在VueX中,即可在整个Vue项目的组件中使用。

    2. VueX中的核心内容(核心成员)

    在VueX对象中,不仅有state,还有用来操作state中数据的方法集,以及当我们需要对state中的数据进行加工的方法集等等成员。成员列表如下:

    • state:存放状态
    • getters:对state成员进行筛选过滤
    • mutations:对state成员进行操作的方法集,比如对该数据的增、删、改等操作。
    • actions:异步操作
    • modules:模块化状态管理

    2.1 state—增删改state中的成员

    为了配合Vue的响应式数据,我们在Mutations的方法中,应当使用Vue提供的方法来进行操作。如果使用delete或者xx.xx = xx的形式去删或增,则Vue不能对数据进行实时响应。

    • Vue.set:为某个对象设置成员的值,若不存在则新增。如对state对象中添加一个age成员:
    Vue.set(state,"age",15)
    
    • Vue.delete:删除成员。如将刚刚添加的age成员删除:
    Vue.delete(state,'age')
    

    2.2 getters—对state中的成员进行筛选过滤

    getters中的方法有两个默认参数:([state] , [getters])

    • state:当前VueX对象中的状态对象
    • getters:当前getters对象,用于将getters下的其他getter拿来用
    • 在getters中自定义方法
    getters:{
        nameInfo(state){
            return "姓名:"+state.name
        },
        fullInfo(state,getters){
            return getters.nameInfo+'年龄:'+state.age
        }  
    }
    
    • 在组件中调用该方法
    this.$store.getters.fullInfo
    

    2.3 mutations—对state成员进行操作

    (1) mutations基本使用方法

    mutations中的方法有默认的两个形参:([state] , [payload])

    • state:当前VueX对象中的state
    • payload:该方法被调用时传递的参数
    • 在mutations中自定义方法:我们可在index.js的mutations成员中自定义一个方法,用于修改name值
    import Vue from 'vue'
    import Vuex from 'vuex'
    
    Vue.use(Vuex)
    
    const store = new Vuex.store({
        state:{
            name:'helloVueX'
        },
        mutations:{
            //es6语法,等同edit:funcion(){...}
            edit(state){
                state.name = 'jack'
            }
        }
    })
    
    export default store
    
    • 调用mutations中的方法:在组件中(如在App.vue的某个method中)通过如下方式去调用mutations中的方法
    this.$store.commit('edit')
    

    (2) mutation传值

    在实际生产过程中,会遇到需要在提交某个mutation时需要携带一些参数给方法使用。

    • 携带单个参数进行提交:
    this.$store.commit('edit',15)
    
    • 携带多个参数进行提交:推荐把它们放在一个对象进行提交
    this.$store.commit('edit',{age:15,sex:'男'})
    

    this.$store.commit({
        type:'edit',
        payload:{
            age:15,
            sex:'男'
        }
    })
    
    • 接收挂载的参数:在index.js的mutations成员中自定义的方法
    edit(state,payload){
        state.name = 'jack'
        console.log(payload) // 15或{age:15,sex:'男'}
    }
    

    2.4 actions—异步操作

    mutations只能处理同步函数,直接在mutation方法中进行异步操作,将会引起数据失效。所以提供了Actions来专门进行异步操作,最终提交mutation方法。actions和mutations的区别:

    • Actions 提交的是 mutations,而不是直接变更状态。也就是说,actions会通过mutations,让mutations帮他提交数据的变更。
    • Action 可以包含任意异步操作。ajax、setTimeout、setInterval不在话下。

    Actions中的方法有两个默认参数:([context] , [payload])

    • context:上下文(相当于箭头函数中的this)对象
    • payload:挂载参数
    • 在actions中自定义异步方法:如在两秒中后执行edit方法(由于setTimeout是异步操作,所以需要使用actions)。
    actions:{
        edit(context,payload){
            setTimeout(()=>{
                context.commit('edit',payload)
            },2000)
        }
    }
    
    • 在组件中调用该异步方法
    this.$store.dispatch('edit',{age:15})
    

    拓展:由于是异步操作,所以我们可以对异步操作封装为一个Promise对象,上面的异步方法可优化为:

    actions:{
        edit(context,payload){
            return new Promise((resolve,reject)=>{
                setTimeout(()=>{
                    context.commit('edit',payload)
                    resolve()
                },2000)
            })
        }
    }
    

    3. VueX工作流程

    工作流程.png
    • 异步操作与actions:Vue组件如果调用某个VueX的方法过程中需要向后端请求时或者说出现异步操作,需要dispatch VueX中actions的方法,以保证数据的同步。actions的存在就是为了让mutations中的方法能在异步操作中起作用
    • 如果没有异步操作:那么就可以直接在组件内提交状态中的mutations中,使用自定义的方法来对state成员进行操作,最后被修改后的state成员会被渲染到组件的原位置当中去。注意,不建议在组件中直接对state中的成员进行操作,因为直接修改(如:this.$store.state.name = 'hello')成员,不能被VueDevtools所监控到。

    在Vue项目开发中,需要监控项目中得各种值,为了提高效率,Vue提供了一款浏览器扩展——VueDevtools。请参考:安装Vue开发工具VueDevtools

    4. 安装与使用

    4.1 安装Vuex依赖

    • npm安装Vuex
    npm i vuex -s
    
    • 在项目的根目录下新增一个store文件夹,在该文件夹内创建index.js。项目的src文件夹如下
    │  App.vue
    │  main.js
    │
    ├─assets
    │      logo.png
    │
    ├─components
    │      HelloWorld.vue
    │
    ├─router
    │      index.js
    │
    └─store
           index.js
    

    拓展:如果把整个store都放在index.js中是不合理的,所以需要拆分。比较合适的目录格式如下。对应的内容存放在对应的文件中,和以前一样,在index.js中存放并导出store。state中的数据尽量放在index.js中;而modules中的Astore局部模块状态如果多的话也可以进行细分。

    store:.
    │  actions.js
    │  getters.js
    │  index.js
    │  mutations.js
    │  mutations_type.js   ##该项为存放mutaions方法常量的文件,按需要可加入
    │
    └─modules
    │   Astore.js
    

    4.2 使用

    (1) 创建vuex对象并初始化store:index.js

    import Vue from 'vue'
    import Vuex from 'vuex'
    
    //挂载Vuex:在创建Vue实例之前
    Vue.use(Vuex)
    
    //创建VueX对象
    const store = new Vuex.Store({
        state:{
            //存放组件之间共享的数据:存放的键值对就是所要管理的状态
            name:'helloVueX'
        },
        mutations:{
            //显式的更改state里的数据
       },
       getters:{
           //获取数据的方法
        },
       actions:{
             //
        }
    })
    
    export default store
    

    (2) 将store挂载到当前项目的Vue实例:main.js

    import Vue from 'vue'
    import App from './App'
    import router from './router'
    import store from './store'
    
    Vue.config.productionTip = false
    
    /* eslint-disable no-new */
    new Vue({
      el: '#app',
      router,
      store,  //store:store 和router一样,将我们创建的Vuex实例挂载到这个vue实例中
      render: h => h(App)
    })
    
    

    (3) 在组件中使用Vuex

    • 如在App.vue中,将state中定义的name在h1标签中显示
    <template>
        <div id='app'>
            name:
            <h1>{{ $store.state.name }}</h1>
        </div>
    </template>
    
    • 或者在组件方法中使用
    methods:{
        add(){
          console.log(this.$store.state.name)
        }
    },
    ...
    
    
    
    

    相关文章

      网友评论

        本文标题:Vuex-Vue状态管理模式

        本文链接:https://www.haomeiwen.com/subject/xyzeahtx.html