Vue的状态管理Vux


一、介绍

  • Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 + 库
  • 当我们的应用遇到多个组件共享状态(共享状态:多个组件维护1个变量)时,单向数据流的简洁性很容易被破坏。多个组件互相传参将会非常繁琐,并且对于兄弟组件间的状态传递无能为力
  • vuex就是把多个组件共享状态(数据)抽取出来以一个全局单例模式管理,把共享的数据函数放进vuex中,任何组件都能获取状态或者触发行为

二、install

npm install vuex@next --save

三、store

1、介绍

  • 每一个 Vuex 应用的核心就是 store(仓库)。“store”基本上就是一个容器,它包含着你的应用中大部分的状态 (state)。Vuex 和单纯的全局对象有以下两点不同:
    1. Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新
    2. 你不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation

2、创建并全局引入

  • 创建src/store/index.js

  • main.js中全局注册

// 引入创建的store/index.js
import store from './store'

// store注入到vue根实例
createApp(App).use(store)

3、单一状态树

  1. index.js
import {
   createStore} from 'vuex'

export default createStore({
   
    // 1、共享的状态(数据),相似于data
    state: () => ({
   
        user: {
   
            name: 'kimi',
            age: 18,
            honor: [
                '1-三好学生',
                '1-优秀班干部',
                '2-优秀班干部'
            ]
        }
    }),
    // 2、有时候我们需要从 state 中派生出一些状态,如果有多个组件需要用到此属性,我们要么复制这个函数,或者抽取到一个共享函数然后在多处导入它,无论哪种方式都不是很理想
    // 只能读取state中的状态
    getters: {
   
        /**
         * 使用state - 获取个人荣誉的数量
         *
         * @param state 上面的state
         * @returns
         */
        getUserHonorNum(state) {
   
            return state.user.honor.length
        },
        /**
         * 使用getters
         *
         * @param state
         * @param getters
         * @returns
         */
        getUserAvgHonorNum(state, getters) {
   
            return getters.getUserHonorNum / 3
        },
        /**
         * 传入自定义参数
         *
         * @param state
         * @param getters
         * @returns
         */
        getUserAvgHonorNumber: (state, getters) => (year) => {
   
            return getters.getUserHonorNum / year
        }
    },
    // 3、更改 Vuex 的 store 中的状态(数据)的唯一方法是提交 mutation
    // mutation中必须是同步函数
    mutations: {
   
        /**
         * 使用state - 年龄+1
         *
         * @param state
         */
        setAgeIncrement(state) {
   
            state.user.age++
        },
        /**
         * 传入自定义参数 - 单个
         *
         * @param state
         * @param age
         */
        setAge(state, age) {
   
            state.user.age = age
        },
        /**
         * 传入自定义参数 - 多个(需使用对象)
         *
         * @param state
         * @param user
         */
        setUser(state, user) {
   
            state.user = user
        }
    },
    // 4、actions类似于mutation都是修改state中的状态,但是actions提交的是mutation,而不是直接变更state中的状态
    // actions可以包含任意异步操作
    actions: {
   
        /**
         * 年龄+1,异步操作,2秒之后再执行
         *
         * @param context 与store实例具有相同方法和属性的对象(context.getters、context.commit、context.dispatch),但并不是store实例本身
         */
        setAgeIncrement(context) {
   
            setTimeout(() => {
   
                context.commit('setAgeIncrement')
            }, 2000)
        },
        /**
         * 传入自定义参数 - 单个
         *
         * @param context
         * @param age
         */
        setAge(context, age) {
   
            context.commit('setAge', age)
        },
        /**
         * 传入自定义参数 - 多个(需使用对象)
         *
         * @param context
         * @param user
         */
        setUser(context, user) {
   
            context.commit('setUser', user)
        },
        /**
         * actions中的函数也可以调用actions中的其他函数
         *
         * @param context
         */
        setAgeAdd(context) {
   
            context.dispatch('setAgeIncrement').then(() => {
   
                context.commit('setAgeIncrement')
            })
        }
    },
    // 5、由于使用单一状态树,应用的所有状态会集中到一个比较大的对象(store/index.js会变得很大),store对象就会变的很臃肿,为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)
    modules: {
   
        
    }
})
  1. 组件中使用
<script setup>
import {
   useStore} from 'vuex'
const store = useStore()

//1、访问state
store.state.user

//2、访问getters
store.getters.getUserHonorNum
store.getters.getUserAvgHonorNumber(6)  //传入自定义参数

//3、修改state中的状态,调用mutations中的函数
store.commit('setAgeIncrement')
store.commit({
   type: 'setAgeIncrement'})//对象风格的提交方式
store.commit('setAge', 30)//传入自定义参数 - 单个
store.commit('setUser', {
   name: 'sally', age: 20})//传入自定义参数 - 多个

//4、修改state中的状态,调用actions中的函数(分发Action,Action通过store.dispatch方法触发,异步操作所以是回调方法)
store.dispatch('setAgeAdd').then(() => {
   

})
//对象风格的提交方式
store.dispatch({
   type: 'setAgeIncrement'}).then(() => {
   

})
//传入自定义参数 - 单个
store.dispatch('setAge', 20).then(() => {
   

})
//传入自定义参数 - 多个
store.dispatch('setUser', {
   name: 'sally', age: 20}).then(() => {
   

})
</script>

4、多模块状态树(无命名空间)

  • 由于使用单一状态树,应用的所有状态会集中到一个比较大的对象(store/index.js会变得很大),store对象就会变的很臃肿,为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)
  • 不带命名空间时,模块内部的getter、mutation、action仍然是注册在全局命名空间的。必须注意,不要在不同的、无命名空间的模块中定义两个相同的 getter 从而导致错误
  1. 创建user模块(store/modules/user.js)
const user = {
   
    state: () => ({
   
        user: {
   
            name: 'kimi',
            age: 18,
            honor: [
                '1-三好学生',
                '1-优秀班干部',
                '2-优秀班干部'
            ]
        }
    }),
    getters: {
   
        /**
         * @param state 该模块中的state
         * @param getters 该模块中的getters
         * @param rootState 所有模块的state
         * @returns
         */
        getUserHonorNum(state, getters, rootState) {
   
            return state.user.honor.length
        }
    },
    mutations: {
   
        /**
         * @param state 该模块中的state
         */
        setAgeIncrement(state) {
   
            state.user.age++
        }
    },
    actions: {
   
        /**
         * @param context 与store实例具有相同方法和属性的对象(如下),但并不是store实例本身
         *  context.state
         *  context.getters
         *  context.commit
         *  context.dispatch
         *  context.rootState:所有模块的state
         */
        setAgeIncrement(context) {
   
            setTimeout(() => {
   
                context.commit('setAgeIncrement')
            }, 2000)
        }
    }
}

export default user
  1. index.js
import {
   createStore} from 'vuex'

//引入user模块
import user from '@/store/modules/user'


export default createStore({
   
    modules: {
   
        user
    }
})
  1. 组件中使用
<script setup>
import {
   useStore} from 'vuex'
const store = useStore()

//1、访问state(模块名.共享数据)
store.state.user.user

//2、不带命名空间时,模块内部的getter、mutation、action仍然是注册在全局命名空间的,所以访问这3个中的函数没有变化
store.getters.getUserHonorNum

5、多模块状态树(有命名空间)

  • 如果希望你的模块具有更高的封装度和复用性,你可以将模块添加带命名空间
  1. 创建user模块(store/modules/user.js)
const user = {
   
    // 带命名空间
    namespaced: true,
    state: () => ({
   
        user: {
   
            name: 'kimi',
            age: 18,
            honor: [
                '1-三好学生',
                '1-优秀班干部',
                '2-优秀班干部'
            ]
        }
    }),
    getters: {
   
        /**
         * @param state 该模块中的state
         * @param getters 该模块中的getters
         * @param rootState 所有模块的state
         * @param rootGetters 所有模块的getters
         * @returns
         */
        getUserHonorNum(state, getters, rootState, rootGetters) {
   
            return state.user.honor.length
        }
    },
    mutations: {
   
        /**
         * @param state 该模块中的state
         */
        setAgeIncrement(state) {
   
            state.user.age++
        }
    },
    actions: {
   
        /**
         * @param context 与store实例具有相同方法和属性的对象(如下),但并不是store实例本身
         *  context.state
         *  context.getters
         *  context.commit
         *  context.dispatch
         *  context.rootState:所有模块的state
         *  context.rootGetters 所有模块的getters
         */
        setAgeIncrement(context) {
   
            setTimeout(() => {
   
                context.commit('setAgeIncrement')
            }, 1000)
        }
    }
}

export default user
  1. index.js
import {
   createStore} from 'vuex'

//引入user模块
import user from '@/store/modules/user'


export default createStore({
   
    modules: {
   
        user
    }
})
  1. 组件中使用
<script setup>
import {
   useStore} from 'vuex'
const store = useStore()

//1、访问state(模块名.共享数据)
store.state.user.user

//2、访问模块中的getters(模块名/函数名)
store.getters['user/getAge']

//3、访问模块中的mutations(模块名/函数名)
store.commit('user/setAgeIncrement')

//4、访问模块中的actions(模块名/函数名)
store.dispatch('user/setAgeIncrement').then(() => {
   
    
})

相关推荐

  1. Vue状态管理Vux

    2024-01-28 17:28:02       56 阅读
  2. VuexVue.js 状态管理

    2024-01-28 17:28:02       34 阅读
  3. Vue状态管理Pinia

    2024-01-28 17:28:02       50 阅读
  4. vue 状态管理

    2024-01-28 17:28:02       41 阅读
  5. vuex状态管理使用

    2024-01-28 17:28:02       41 阅读
  6. 深入理解 VuexVue.js 状态管理模式

    2024-01-28 17:28:02       24 阅读
  7. vue状态管理

    2024-01-28 17:28:02       40 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-01-28 17:28:02       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-01-28 17:28:02       100 阅读
  3. 在Django里面运行非项目文件

    2024-01-28 17:28:02       82 阅读
  4. Python语言-面向对象

    2024-01-28 17:28:02       91 阅读

热门阅读

  1. 对机器学习的认知,感悟。

    2024-01-28 17:28:02       65 阅读
  2. 数据集制作工具和数据处理工具有哪些

    2024-01-28 17:28:02       46 阅读
  3. MySQL进阶45讲【6】全局锁和表锁

    2024-01-28 17:28:02       53 阅读
  4. 实用AI工具介绍

    2024-01-28 17:28:02       46 阅读
  5. Nacos源码解析:String.intern()方法的巧妙应用

    2024-01-28 17:28:02       50 阅读
  6. python04_找出某个区间内的所有素数

    2024-01-28 17:28:02       50 阅读
  7. linux&shell日常脚本命令之ps命令

    2024-01-28 17:28:02       57 阅读
  8. python爬虫框架Scrapy

    2024-01-28 17:28:02       62 阅读
  9. 【Vue】1-5、Source Map

    2024-01-28 17:28:02       51 阅读
  10. C++ easyX小程序(介绍几个函数的使用)

    2024-01-28 17:28:02       63 阅读