Vue 3 Vuex

目录

一. state

1. Vuex 的状态存储是响应式的

2. 在template 中使用state

3. 在script 中使用state

4. state 的映射:如何在template 中不需要通过$store.state 取值,直接通过state 中的名字来取值

1. 在options API 的computed 计算属性中使用mapState() 映射函数

2. 在composition API 的computed 计算属性中使用mapState() 映射函数(不推荐)

3. 在composition API 中通过toRefs (推荐)(直接对state 解构,并且包裹ref )

二. getters (类似于computed)

1. getters 的基本使用

2. 在template 中使用getters

3. 在script 中使用getters

4. 在当前getters 中获取其他的getters

5. getters 支持返回一个函数,可以对getters 传入参数

6. getters 的映射:如何在template 中不需要通过$store.getters 取值,直接通过getters 中的名字来取值

1. options API 中使用mapState()

 2. composition API 中使用mapState()(不推荐)

3. 在composition API 中通过toRefs(直接对getters 解构,并且包裹ref )

4. 在composition API 中通过computed 对单个getter 进行监听(推荐)

三. mutations ( 更改vuex 中store 中的状态的唯一方法是提交mutation )

1. 基本使用

2. 给mutation 传递参数

3. 使用常量编写mutation 的名字

4. mutaions 的映射:直接通过mutaions 中的名字来调用方法

1. options API 中使用mapMutations()

2. composition API 中使用mapMutations()

5. mutations 中不要执行异步操作(方便devtool 中记录mutations 的日志)

四. actions (异步操作)

1. 基本使用

2. actions 的分发操作

3. mapActions 辅助函数

1. 在options 中使用mapActions 辅助函数

2. 在composition 中使用mapActions 辅助函数

4. 使用基本的做法,不使用mapActions

5. 在actions 中进行异步操作

五. modules

1. 基本使用( 模块中的state )

2. 默认获取getters mutations actions 时不需要加模块名称,但是存在命名冲突问题

3. 使用namespaced: true 获取getters mutations actions

4. 在module 中修改root 的state


一. state

1. Vuex 的状态存储是响应式的

import { createStore } from 'vuex'

const store = createStore({
    state: () => ({
        counter: 100
    })
})

export default store

2. 在template 中使用state

<h2>{{ $store.state.counter }}</h2>

3. 在script 中使用state

import { useStore } from 'vuex'

const store = useStore()

console.log(sotre.state.counter)

4. state 的映射:如何在template 中不需要通过$store.state 取值,直接通过state 中的名字来取值

1. 在options API 的computed 计算属性中使用mapState() 映射函数

import { createStore } from 'vuex'

const store = createStore({
    state: () => ({
        counter: 100,
        name: "why"
    })
})

export default store

1. 数组写法

<h2>{{ counter}}</h2>
<h2>{{ name }}</h2>

<script>
import { mapState } from 'vuex'

export default {
    computed: {
        // 数组写法
        ...mapState(["counter", "name"])
    }
}
</script>

2. 对象写法(当有state 和 data 中的数据存在命名冲突时,可以通过对象写法修改state 中数据的名字)

      
<h2>{{ sCouner}}</h2>
<h2>{{ sName}}</h2>

<script>
import { mapState } from 'vuex'

export default {
    computed: {
        // 对象写法
        ...mapState({
            sCouner: state => state.sCounter,
            sName: state => state.sName 
        })
    }
}
</script>

2. 在composition API 的computed 计算属性中使用mapState() 映射函数(不推荐)

import { createStore } from 'vuex'

const store = createStore({
    state: () => ({
        counter: 100,
        name: "why"
    })
})

export default store
<h2>{{ cCounter }}</h2>
<h2>{{ cName }}</h2>

<script setup>
import { computed } from 'vue'
import { mapState, useStore } from 'vuex'

const store = useStore()
const cCounter = computed(counter.bind({ $store: store }))
const cName = computed(name.bind({ $store: store }))
</script>

3. 在composition API 中通过toRefs (推荐)(直接对state 解构,并且包裹ref )

<h2>{{ sCounter }}</h2>
<h2>{{ name }}</h2>

<script setup>
    import { toRefs } from 'vue'
    import { useStore } from 'vuex'

    const store = useStore()
    // 起别名 添加默认值   counter: sCounter = 0
    const { counter: sCounter = 0, name } = toRefs(store.state)
   
</script>

二. getters (类似于computed)

1. getters 的基本使用

import { createStore } from 'vuex'

const store = createStore({
    state: () => ({
        counter: 100,
        users: [
            {id: 1, name: "aaa", age: 20},
            {id: 2, name: "bbb", age: 30},
            {id: 3, name: "aaa", age: 40}
        ]
    }),
    
    getters: {
        doubleCounter(state) {
            return state.counter++
        },
        totalAge(state) {
            return state.users.reduce(( preValue, item ) => {
                return preValue + item.age
            }, 0)
        }
    }
})

export default store

2. 在template 中使用getters

<h2> {{ $store.getters.doubleCounter }} </h2>
<h2> {{ $store.getters.totalAge }} </h2>

3. 在script 中使用getters

import { useStore } from 'vuex'

const store = useStore()

console.log( sotre.getters.doubleCounter )

4. 在当前getters 中获取其他的getters

import { createStore } from 'vuex'

const store = createStore({
    state: () => ({
        counter: 100
        users: [
            {id: 1, name: "aaa", age: 20},
            {id: 2, name: "bbb", age: 30},
            {id: 3, name: "aaa", age: 40}
        ]
    }),
    
    getters: {
        totalAge(state) {
            return state.users.reduce(( preValue, item ) => {
                return preValue + item.age
            }, 0)
        },
        message(state, getters) {
            return `counter: ${state.counter} firendsTotalAge: ${getters.totalAge}`
        }
    }
})

export default store

5. getters 支持返回一个函数,可以对getters 传入参数

import { createStore } from 'vuex'

const store = createStore({
    state: () => ({
        counter: 100
        users: [
            {id: 1, name: "aaa", age: 20},
            {id: 2, name: "bbb", age: 30},
            {id: 3, name: "aaa", age: 40}
        ]
    }),
    
    getters: {

        getFriendById(state) {
            return function(id) {
                const friend = state.users.find(item => item.id === id)
                return friend
            }
        }

    }
})

export default store
<h2> {{ $store.getters.getFriendById(1) }} </h2>

6. getters 的映射:如何在template 中不需要通过$store.getters 取值,直接通过getters 中的名字来取值

1. options API 中使用mapState()

<h2>{{ doubleCounter }}</h2>
<h2>{{ totalAge }}</h2>
<h2>{{ message }}</h2>
<h2>{{ getFriendsById }}</h2>

<h2>{{ DoubleCounter }}</h2>
<script>
    import { mapGetters } from 'vuex'

    export default {
        computed: {
            // 数组语法
            ...mapGetters(["doubleCounter", "totalAge", "message", "getFriendsById"])

            // 对象语法(可以用来添加getters 的别名)
            ...mapGetters({
                DoubleCounter: "doubleCounter"
            })
        }
    }
</script>

 2. composition API 中使用mapState()(不推荐)

<h2>{{ doubleCounter }}</h2>
<h2>{{ totalAge }}</h2>
<h2>{{ message }}</h2>
<h2>{{ getFriendsById }}</h2>

import { computed } from 'vue'
import { mapGetters, useStore } from 'vuex'

const store = useStore()
const { message: messageFn } = mapGetters(["message"])
const message = computed(messageFn.bind({ $store:store }))

3. 在composition API 中通过toRefs(直接对getters 解构,并且包裹ref )

<h2>{{ message }}</h2>

import { toRefs } from 'vue'
import { useStore } from 'vuex'

const store = useStore()
const { message } = toRefs( store.getters )

4. 在composition API 中通过computed 对单个getter 进行监听(推荐)

const message = computed( () => store.getters.message )

三. mutations ( 更改vuex 中store 中的状态的唯一方法是提交mutation )

1. 基本使用

import { createStore } from 'vuex'

const store = createStore({
    state: () => ({
        name: "why"
    }),
    
    metutions: {
        changeName(state) {
            state.name = "coder"
        }    
    }
  
})

export default store
// Vue 3
const store = useStore()
function change() {
    store.commit("changeName")
}

// Vue 2
function change() {
    this.$store.commit("changeName")
}

2. 给mutation 传递参数

import { createStore } from 'vuex'

const store = createStore({
    state: () => ({
        name: "why",
        age: 18
    }),
    
    metutions: {
        // payload 是自己起的
        // 传递过来的参数通过payload 接收
        changeInfo(state, payload) {
            state.name = payload.newName
            state.age= payload.newAge
        }    
    }
  
})

export default store
function change() {
    // (mutation 的函数名, 传递的参数)
    store.commit("changeInfo", {
        newName: "coder",
        newAge: 20   
    })

    // 传递的参数可以是一个基本数据类型,也可以是对象
    store.commit("changeName", "coder")
}

3. 使用常量编写mutation 的名字

export const CHANGE_NAME = "changeInfo"
import CHANGE_INFO from './mutation_types.js'

mutations: {
    [CHANGE_INFO](state, payload) {
        state.name = payload.newName
        state.age= payload.newAge
    }    
}
import CHANGE_INFO from './mutation_types.js'

function change() {
    store.commit( CHANGE_INFO , {
        newName: "coder",
        newAge: 20   
    })
}

4. mutaions 的映射:直接通过mutaions 中的名字来调用方法

1. options API 中使用mapMutations()

import { mapMutations } from 'vuex'

export default {
    methods: {
        ...mapMutations("changeName", CHANGE_INFO)
    }
}
<button @click="changeName('coder')"></button>

// 调用时不能使用常量,需要使用常量的值
// const CHANGE_NAME = "changeInfo"
<button @click="changeInfo({name: 'coder', age: 20})"></button>

2. composition API 中使用mapMutations()

import { mapMutations, useStore } from 'vuex'
import { CHANGE_INFO } from '@store/mutation_types'

const store = useStore()
const mutations = mapMutations(['changeName', CHANGE_INFO])
const newMutations = {}
Object.keys(mutations).forEach(key => {
    newMutations[key] = mutations[key].bind({ $store: store })
})
const { changeName, changeInfo } = newMutations

5. mutations 中不要执行异步操作(方便devtool 中记录mutations 的日志)

四. actions (异步操作)

1. 基本使用

  1. actions 提交的是mutations, 而不是直接变更状态
  2. actions 可以包含任意异步操作
  3. 参数:context, context 是一个store 实例均有相同方法和属性的context 对象,所以可以从其中获取到commit 方法来提交一个mutation ,或者通过context.state 和context.getters 来获取state 和getters
mutations: {
    increment(state) {
        state.counter++
    }
},
actions: {
    // payload 是传递过来的参数
    incrementAction(context, payload) {
        console.log(context.commit)
        console.log(context.state)
        console.log(context.getters)
        context.commit("increment", payload)
    }
}
<h2>{{ $store.state.counter }}</h2>
<button @click="actionBtnClick"></button>

methods: {
    actionBtnClick() {
        // 不传递参数
        this.$store.dispatch("incrementAction")

        // 传递参数
        this.$store.dispatch("incrementAction", "aaa")
    }
}

2. actions 的分发操作

add() {
    this.$store.dispatch("increment")
}
// 携带参数
add() {
    this.$store.dispatch("increment", { count: 100 })
}
add() {
    // 以对象的形式分发
    this.$store.dispatch({
        type: "increment",
        count: 100
    })
}

3. mapActions 辅助函数

1. 在options 中使用mapActions 辅助函数

// 没有参数
<h2>{{ $store.state.counter }}</h2>
<button @click="incrementAction"></button>

// 携带参数
<h2>{{ $store.state.name}}</h2>
<button @click="changeNameAction("aaa")"></button>


import { mapActions } from 'vuex'
methods {
    ...mapActions(["increment", "changeNameAction"])
}

2. 在composition 中使用mapActions 辅助函数

import { useStore, mapActions } from 'vuex'

const store = useStore()
const actions = mapActions(["incrementAction", "changeNameAction"])
const newActions = {}
Object.keys(actions).forEach(key => {
    newActions[key] = actions[key].bind({ $store: store })
})
const {incrementAction, changeNameAction} from = newActions

4. 使用基本的做法,不使用mapActions

function increment() {
    store.dispatch("incrementAction")
}

5. 在actions 中进行异步操作

state: {
    banner: []
}

mutations: {
    changeBanner(state, banners) {
        state.banner = banners
    }
}

actions: {
    async fetchHomeMultidataAction(context) {
        //1. 返回promise 给promise 设置then
        fetch("http://123.207.32.32:8080/home/mutidata").then(
            res => { console.log(res.data) }
        ) 

        // 2. promise 的链式调用
        fetch("http://123.207.32.32:8080/home/mutidata").then(
            res => res.json()
        ).then(data => {
            console.log(data)
        })
        
        // 3.await/async
        const res = await fetch("http://123.207.32.32:8080/home/mutidata")
        const data = await res.json()
        console.log(data)

        // 修改state 中的数据
        context.commit("changeBanner", data.banner)
    }    
}
actions: {
    function fooAction() {
        return new Promise( async (resolve, reject) => {
            const res = await fetch("http://")
            const data = await res.json()
            context.commit("changeBanners", data.banner)   
            context.commit("changeRecommends", data.recommend)  
            resolve(res.data)
        }) 
    }
}

store.dispatch("fooAction").then(res => {
    console.log(res)
})

五. modules

1. 基本使用( 模块中的state )

// store/index.js

import { createStore } from 'vuex'
import homeModule from './modules/home'

const store = createStore({
    state: () => ({}),
    modules: {
        home: homeModule
    }
})

export default store
// store/modules/home.js
export default {
    state: () => ({
        banners: []
    }),
    mutations: {}
}
<h2>{{ $store.state.home.banners }}</h2>

2. 默认获取getters mutations actions 时不需要加模块名称,但是存在命名冲突问题

// store/index.js

import { createStore } from 'vuex'
import countModule from './modules/count'

const store = createStore({
    state: () => ({
        rootCount: 100    
    }),
    modules: {
        count: countModule 
    }
})

export default store
// store/modules/count.js
const counter = {
    state: () => ({
        count: 10
    }),
    getters: {
        doubleCount(state, getters, rootState) {
            return state.count + rootState.count
        }
    },
    mutations: {
        incrementMutation(state) {
            state.count++
        }  
    },
    actions: {
        incrementAction(context) {
            context.commit("incrementMutation")
        }
    }
}

export default counter
// getters mutations actions 默认是不需要跟模块名字
<h2>{{ $store.getters.doubleCount }}</h2>

foo() {
    store.dispatch("incrementAction")
}

3. 使用namespaced: true 获取getters mutations actions

// store/modules/info.js
export default {
        
    namespaced: true
    
    state: () => ({
        name: 'why',
        age: 18    
    }),
    getters: {
        doubleAge(state, getters, rootState, rootGetters) {
            return state.age * 2
        }
    },
    mutations: {
        ageMutation(state) {
            state.age++    
        }
    },
    actions: {
        // context = { commit, dispatch, state, rootState, getters, rootGetters }
        ageAction(context) {
            context.commit("ageMutation")
        }
    }
}
// info 是模块名称
<h2> {{ store.state.info.age }}</h2>

<h2> {{ store.getters["info/doubleAge"]}}

store.commit("info/ageMutation")

store.dispatch("info/ageAction")

4. 在module 中修改root 的state

// 需要再module 中通过actions 进行修改

actions: {
    changeRootAction({commit, dispatch, state, rootState, getters, rootGetters}) {
        // 修改当前module 中的内容
        commit("changeNameMutation", "kobe");

        // 修改root 中的内容
        commit("changeRootNameMutation", "kobe", {root: true})
        
        dispatch("changeRootNameAction", "kobe", {root: true})
    }
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值