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

    正文概述 掘金(HMGDCR598)   2021-01-03   475

    一:什么是Vuex?

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

    二:vuex的核心

    • Store:仓库,Store 是使用 Vuex应用程序的核心,每个应用仅有一个Store,它是一个容器,包含着应用中的大部分状态,当然我们不能直接改变Store中的状态,我们要通过提交Mutations的方式改变状态。
    • State:状态,保存在Store中,因为Store是唯一的,所以State也是唯一的,称为单一状态树,这里的状态是响应式的。
    • Getter:相当于Vuex中的计算属性,方便从一个属性派生出其他的值,它内部可以对计算的结果进行缓存,只有当依赖的状态发生改变的时候,才会重新计算。
    • Mutation:状态的变化必须要通过提交Mutation来完成。
    • Actions:与Mutation类似,不同的是可以进行异步的操作,内部改变状态的时候都需要改变Mutation
    • Module:模块,由于使用的单一状态树让所有的状态都会集中到一个比较大的对象中,应用变得很复杂的时候,Store对象就会变得相当臃肿,为了解决这些问题Vuex允许我们将Store分割成模块,每个模块拥有自己的StateMutationActionsGetter,甚至是嵌套的子模块。

    三:vuex的基本结构

    // store/index.js
    
    import Vue from 'vue'
    import Vuex from 'vuex'
    import ModuleHead from './modules/head' // 引入的module模块
    //挂载Vuex
    Vue.use(Vuex)
    
    //创建VueX对象
    const store = new Vuex.Store({
        state:{
            name:'helloVueX'
        },
        mutations: {
    
        },
        actions: {
    
        },
        modules: {
            ModuleHead
        }
    })
    
    export default store
    
    // main.js
    
    import Vue from 'vue'
    import App from './App.vue'
    import 'style/comment.css'
    import router from 'route/index' 
    
    import store from 'store/index' // 引入store文件
    
    // ElementUI的引入
    import ElementUI from 'element-ui';
    import 'element-ui/lib/theme-chalk/index.css';
    Vue.use(ElementUI);
    Vue.config.productionTip = false
    
    new Vue({
      render: h => h(App),
      router,
      store // 使用store
    }).$mount('#app')
    
    

    四:vuex的使用

    1)state的使用
    // demo.vue
    <template>
      <div>
          <!-- 基础设施C -->
         <span>$store.state获取vuex的值:{{$store.state.name}}</span>
      </div>
    </template>
    
    <script>
    export default {
    
    }
    </script>
    
    <style>
    
    </style>
    

    每次使用变量都要前面写$store.state很是麻烦,所以这里使用Vuex内部提供的mapState的函数,会帮我们生成状态对应的计算属性

    <template>
      <div>
          <!-- 基础设施C -->
          <span>mapState获取vuex的值:{{name}}</span>
      </div>
    </template>
    
    <script>
    import {mapState} from 'vuex'
    export default {
      computed:{
        ...mapState(['name'])
      }
    }
    </script>
    
    <style>
    
    </style>
    

    当然啦,我们也可以给获取的state的值取别名的,和上面方法差不多,不同的是,mapState参数是对象,键是别名,值是内容。

    <template>
      <div>
          <!-- 基础设施C -->
          <span>mapState获取vuex的值并设置别名:{{my_name}}</span>
      </div>
    </template>
    
    <script>
    import {mapState} from 'vuex'
    export default {
      computed:{
        ...mapState({my_name:'name'}) // 参数是对象,键是别名,值是state对象里的值
      }
    }
    </script>
    
    <style>
    
    </style>
    
    2)Getter的使用

    Vuex中的getter就相当于组件中的计算属性,如果想要对state的数据进行简单的处理在展示,可以使用getter

    // store/index.js
    
    import Vue from 'vue'
    import Vuex from 'vuex'
    import ModuleHead from './modules/head'
    //挂载Vuex
    Vue.use(Vuex)
    
    //创建VueX对象
    const store = new Vuex.Store({
        state:{
            name:'helloVueX',
            my_name: '老哥'
        },
        getters:{ 
            mapData({my_name}) { // 参数是state对象,这里把my_name解构出来了
                return `我是经过改造的${my_name}`
            }
        },
        mutations: {
    
        },
        actions: {
    
        },
        modules: {
            ModuleHead
        }
    })
    
    export default store
    
    <template>
      <div>
          <!-- 基础设施C -->
          <span>{{$store.getters.mapData}}</span>
      </div>
    </template>
    
    <script>
    export default {
      computed:{
      }
    }
    </script>
    
    <style>
    
    </style>
    

    同样那样引用过于麻烦,那么和mapState一样,使用内部的mapGetters,也是将其映射到组件的计算属性,其用法和mapState一样,也可以为了避免冲突使用对象设置别名

    <template>
      <div>
          <!-- 基础设施C -->
          <span>mapGetters取值:{{mapData}}</span>
          <br>
          <span>mapGetters取值并取别名:{{another_name}}</span>
      </div>
    </template>
    
    <script>
    import {mapGetters} from 'vuex'
    export default {
      computed:{
        ...mapGetters(['mapData']),
        ...mapGetters({ another_name:'map_data'})
      }
    }
    </script>
    
    <style>
    
    </style>
    
    3)Mutation的使用

    状态的修改必须提交MutationMutation必须是同步执行的。

    // store/index.js
    
    import Vue from 'vue'
    import Vuex from 'vuex'
    import ModuleHead from './modules/head'
    //挂载Vuex
    Vue.use(Vuex)
    
    //创建VueX对象
    const store = new Vuex.Store({
        state:{
            name:'helloVueX',
            my_name: '老哥',
            age:0
        },
        getters:{
            mapData({my_name}) {
                return `我是经过改造的${my_name}`
            },
            map_data({my_name}) {
                return `${my_name}有别名的`
            }
        },
        mutations: {
            // 第一个参数是store,
            //此处需要对store对象的值进行修改,不可以解构里面的变量,要写全
            // 不能写成addStoreAge({age},payload)的形式
            // 第二个参数是提交的参数
            addStoreAge(store,payload) {
                store.age += payload
            },
            desStoreAge(store,payload) {
                if (store.age > 0) {
                    store.age -= payload
                }
            }
        },
        actions: {
    
        },
        modules: {
            ModuleHead
        }
    })
    
    export default store
    
    // demo.vue
    
    <template>
      <div>
          <!-- 基础设施C -->
          <button @click="$store.commit('desStoreAge',2)">减2</button>
          <input v-model="$store.state.age"/>
          <button @click="$store.commit('addStoreAge',2)">加2</button>
          
      </div>
    </template>
    
    <script>
    export default {
      computed:{
      }
    }
    </script>
    
    <style>
    
    </style>
    

    同样那样引用过于麻烦,那么和mapState一样,使用内部的mapMutations ,使用map方法将当前的mutation映射到methods中,其依旧会返回一个对象,这个对象中存储的是mutation中映射的方法

    <template>
      <div>
          <!-- 基础设施C -->
          <button @click="des(2)">减2</button>
          <input v-model="age"/>
          <button @click="add(2)">加2</button>
          
      </div>
    </template>
    
    <script>
    import {mapMutations,mapState} from 'vuex'
    export default {
      computed:{
        ...mapState(['age'])
      },
      methods:{
        // ...mapMutations(['desStoreAge','addStoreAge'])
        ...mapMutations({des:'desStoreAge',add:'addStoreAge'}) // 起别名
      }
    }
    </script>
    
    <style>
    
    </style>
    
    4)Actions的使用

    如果有异步的修改,需要使用actions,在actions中可以执行异步操作,当异步操作结束后,如果需要更改状态,还需要提交Mutation

    // store/index.js
    
    import Vue from 'vue'
    import Vuex from 'vuex'
    import ModuleHead from './modules/head'
    //挂载Vuex
    Vue.use(Vuex)
    
    //创建VueX对象
    const store = new Vuex.Store({
        state:{
            name:'helloVueX',
            my_name: '老哥',
            age:0
        },
        getters:{
            mapData({my_name}) {
                return `我是经过改造的${my_name}`
            },
            map_data({my_name}) {
                return `${my_name}有别名的`
            }
        },
        mutations: {
            // 第一个参数是store,
            //此处需要对store对象的值进行修改,不可以解构里面的变量,要写全
            // 不能写成addStoreAge({age},payload)的形式
            // 第二个参数是提交的参数
            addStoreAge(store,payload) {
                store.age += payload
            },
            desStoreAge(store,payload) {
                if (store.age > 0) {
                    store.age -= payload
                }
            }
        },
        actions: {
            // 第一个参数是context上下文,这个对象中有state,commit,getters等成员
            // 第二个参数是payLoad
            addStoreAgeAsync({commit},payload) {
              setTimeout(() => { // 延迟两秒,模拟异步操作
                commit('addStoreAge',payload)
              }, 2000);
            },
            desStoreAgeAsync({commit},payload) {
                setTimeout(()=> {
                    commit('desStoreAge',payload)
                },2000)
            }
        },
        modules: {
            ModuleHead
        }
    })
    
    export default store
    
    <template>
      <div>
          <!-- 基础设施C -->
          <button @click="$store.dispatch('desStoreAgeAsync',2)">减2</button>
          <input v-model="age"/>
          <button @click="$store.dispatch('addStoreAgeAsync',2)">加2</button>
          
      </div>
    </template>
    
    <script>
    import {mapState} from 'vuex'
    export default {
      computed:{
        ...mapState(['age'])
      },
      methods:{
    }
    </script>
    
    <style>
    
    </style>
    

    结果是:点击按钮2秒后,值才会被修改

    同样的,actions也有对应的mapActions,不需要使用如上面的方法dispatch

    <template>
      <div>
          <!-- 基础设施C -->
          <button @click="des(2)">减2</button>
          <input v-model="age"/>
          <button @click="add(2)">加2</button>
          
      </div>
    </template>
    
    <script>
    import {mapState,mapActions} from 'vuex'
    export default {
      computed:{
        ...mapState(['age'])
      },
      methods:{
        // ...mapActions(['desStoreAgeAsync','addStoreAgeAsync'])
        ...mapActions({des:'desStoreAgeAsync',add:'addStoreAgeAsync'})
      }
    }
    </script>
    
    <style>
    
    </style>
    
    5)Modules的使用

    模块可以让我们把单一状态树拆分成多个模块,每个模块都可以拥有自己的statemutationactiongetter甚至嵌套子模块。

    模块定义

    store文件夹中,创建一个modules文件夹,里面每一个js文件就是一个模块,下面是每一个模块的定义格式

    vuex的使用

    // head.js,这里定义值
    
    let headData = [
        {
            lable: '基础设施1',
            value: 'infrastructureA',
            path: 'tab_a'
        },
        {
            lable: '基础设施2',
            value: 'infrastructureB',
            path: 'tab_b'
        },
        {
            lable: '基础设施3',
            value: 'infrastructureC',
            path: 'tab_c'
        },
        {
            lable: '基础设施4',
            value: 'infrastructureD',
            path: 'tab_d'
        },
        {
            lable: '基础设施5',
            value: 'infrastructureE',
            path: 'tab_e'
        }
    ]
    export  {
        headData
    }
    

    注意:子模块需要使用命名空间namespaced: true,否则是找不到的

    // modules/head/index.js // 子模块
    
    import {headData} from './head'
    let head_store = {
        // 命名空间
        namespaced: true,
    
        state:{
            headData,
            name: null,
            userInfo: null
        },
    
        mutations: {
    
            login(state,payload) {
                state.name= payload.my_name
            },
    
            saveInfo(state,payload) {
                console.log('异步修改state:',state)
                console.log('异步修改payload:',payload)
                state.userInfo= payload
            }
        },
        actions: {
    
            //异步修改
            asyncSaveInfo({commit},data) {
                commit('saveInfo',data)
            }
    
        },
        modules: {
            
        }
    }
    export default head_store
    
    // store/index.js
    
    import Vue from 'vue'
    import Vuex from 'vuex'
    import ModuleHead from './modules/head'
    //挂载Vuex
    Vue.use(Vuex)
    
    //创建VueX对象
    const store = new Vuex.Store({
        state:{
            name:'helloVueX',
            my_name: '老哥',
            age:0
        },
        getters:{
            mapData({my_name}) {
                return `我是经过改造的${my_name}`
            },
            map_data({my_name}) {
                return `${my_name}有别名的`
            }
        },
        mutations: {
            // 第一个参数是store,
            //此处需要对store对象的值进行修改,不可以解构里面的变量,要写全
            // 不能写成addStoreAge({age},payload)的形式
            // 第二个参数是提交的参数
            addStoreAge(store,payload) {
                store.age += payload
            },
            desStoreAge(store,payload) {
                if (store.age > 0) {
                    store.age -= payload
                }
            }
        },
        actions: {
            // 第一个参数是context上下文,这个对象中有state,commit,getters等成员
            // 第二个参数是payLoad
            addStoreAgeAsync({commit},payload) {
              setTimeout(() => { // 延迟两秒,模拟异步操作
                commit('addStoreAge',payload)
              }, 2000);
            },
            desStoreAgeAsync({commit},payload) {
                setTimeout(()=> {
                    commit('desStoreAge',payload)
                },2000)
            }
        },
        modules: {
            ModuleHead // 引入子模块
        }
    })
    
    export default store
    

    使用子模块headData的数据

    <template>
      <div>
          <!-- 基础设施C -->
          <p v-for="(item,index) in $store.state.ModuleHead.headData" :key="index">
            {{item.lable}}
          </p>
          
      </div>
    </template>
    
    <script>
    export default {
      computed:{
      },
      methods:{
      }
    }
    </script>
    
    <style>
    
    </style>
    

    vuex的使用

    同样的,我们也可以使用mapStatemapMutations

    <template>
      <div>
          <!-- 基础设施C -->
          <p v-for="(item,index) in headData" :key="index">
            {{item.lable}}
          </p>
          
      </div>
    </template>
    
    <script>
    import {mapState} from 'vuex'
    export default {
      computed:{
        ...mapState('ModuleHead',['headData'])
      },
      methods:{
      }
    }
    </script>
    
    <style>
    
    </style>
    

    五:Vuex严格模式

    所有的状态变更必须提交mutation,但是如果在组件中获取到$store.state.msg进行修改,语法层面没有问题,却破坏了Vuex的约定,且devTools也无法跟踪到状态的修改,开启严格模式之后,如果在组件中直接修改state,会报错。

    import Vue from 'vue'
    import Vuex from 'vuex'
    import ModuleHead from './modules/head'
    //挂载Vuex
    Vue.use(Vuex)
    
    //创建VueX对象
    const store = new Vuex.Store({
        strict: true, // 开启严格模式
        state:{
            name:'helloVueX',
            my_name: '老哥',
            age:2
        },
        getters:{
            mapData({my_name}) {
                return `我是经过改造的${my_name}`
            },
            map_data({my_name}) {
                return `${my_name}有别名的`
            }
        },
        mutations: {
            // 第一个参数是store,
            //此处需要对store对象的值进行修改,不可以解构里面的变量,要写全
            // 不能写成addStoreAge({age},payload)的形式
            // 第二个参数是提交的参数
            addStoreAge(store,payload) {
                store.age += payload
            },
            desStoreAge(store,payload) {
                if (store.age > 0) {
                    store.age -= payload
                }
            }
        },
        actions: {
        },
        modules: {
            ModuleHead
        }
    })
    
    export default store
    
    <template>
      <div>
          <!-- 基础设施C -->
          <button @click="$store.state.age -= 2">des</button>
          <input v-model="age"/>
          <button @click="$store.state.age += 2">add</button>
          
      </div>
    </template>
    
    <script>
    import {mapState} from 'vuex'
    export default {
      computed:{
        ...mapState(['age'])
      },
      methods:{
      }
    }
    </script>
    
    <style>
    
    </style>
    

    vuex的使用

    注意:

    • strict:false是非严格模式,默认是false,可以直接通过$store.state.age来进行修改
    • 不要在生产环境开启严格模式,因为严格模式会深度检测状态树,会影响性能。在开发模式中开启严格模式,在生产环境中关闭严格模式
    export default new Vuex.Store({
     strict: process.env.NODE_ENV !== 'production',
     state: {
      ...
    }
    

    vuex插件

    会在每个 mutation 完成后调用,接收 mutation 和经过 mutation 后的状态作为参数

    vuex的使用 vuex的使用

    代码如下:

    // plugin.js
    
    export function my_plugin(store) {
        store.subscribe((mutation,state) => {
            console.log('mutation==',mutation.type)  
            console.log('state==',state) 
        })
    }
    
    // store/index.js
    
    import Vue from 'vue'
    import Vuex from 'vuex'
    import ModuleHead from './modules/head'
    import {my_plugin} from './Plugin'
    //挂载Vuex
    Vue.use(Vuex)
    
    //创建VueX对象
    const store = new Vuex.Store({
        strict: true,
        plugins:[my_plugin],
        state:{
            name:'helloVueX',
            my_name: '老哥',
            age:2
        },
        getters:{
            mapData({my_name}) {
                return `我是经过改造的${my_name}`
            },
            map_data({my_name}) {
                return `${my_name}有别名的`
            }
        },
        mutations: {
            // 第一个参数是store,
            //此处需要对store对象的值进行修改,不可以解构里面的变量,要写全
            // 不能写成addStoreAge({age},payload)的形式
            // 第二个参数是提交的参数
            addStoreAge(store,payload) {
                console.log('触发addStoreAge')
                store.age += payload
            },
            desStoreAge(store,payload) {
                console.log('触发desStoreAge')
                if (store.age > 0) {
                    store.age -= payload
                }
            }
        },
        actions: {
        },
        modules: {
            ModuleHead
        }
    })
    
    export default store
    

    vuex的使用


    起源地下载网 » vuex的使用

    常见问题FAQ

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

    发表评论

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

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

    联系作者

    请选择支付方式

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