vuex复习笔记

vuex学习笔记、vuex笔记

阅读量:696

点赞量:0

评论量:0
Learn
标签
标签: JavascriptTypescriptVue
摘要
vuex学习笔记、vuex笔记
正文

vue经典的状态管理工具。

安装

// vue2
npm install vuex

// vue3
npm install vuex@next

使用

// Vue3
import { createStore } from 'vuex'
const store = createStore({})
app.use(store)

// vue2
import Vuex from 'vuex'
const store = new Vuex.Store({})
Vue.use(Vuex)

store的核心属性

state:状态值

getters: 从 store 中的 state 中派生出一些状态

mutation:更改状态的同步方法

action:与mutation类似,可以为异步方法,通过mutation更改状态,而不是直接更改。

modules:嵌套模块,同样可以包含这5个核心属性,用于大项目数据较大时使用。

定义核心属性

// type.ts
export interface RootState {
  count: number
}
export interface AModuleState {
  a: number
}
export interface BModuleState {
  b: number
}
export interface State extends RootState {
  a: AModuleState
  b: BModuleState
}

// store.tsexport const key: InjectionKey<Store<State>> = Symbol()
export const store = createStore<RootState>({
  state: {
    count: 0
  },
  getters: {
    // 四个参数
    double(state, getters, rootState, rootGetters) {
      console.log({ state, getters, rootState, rootGetters })
      return state.count * 2
    }
  },
  mutations: {
    // 两个参数
    increment(state, payload) {
      state.count++
    }
  },
  actions: {
    // 两个参数
    increment(
      { dispatch, commit, state, getters, rootState, rootGetters },
      payload
    ) {
      commit('increment')
    }
  },
  modules: {
    a,
    b
  }
})

// modules/a.ts
import { Module } from 'vuex'
import { AModuleState, RootState } from '../type'
const a: Module<AModuleState, RootState> = {
  state: {
    a: 1
  },
  getters: {
    getA(state, getters, rootState) {
      return state.a + rootState.count
    }
  }
}
export default a

// modules/b.ts
import { Module } from 'vuex'
import { BModuleState, RootState } from '../type'
const b: Module<BModuleState, RootState> = {
  state: {
    b: 1
  },
  getters: {
    getB(state, getters, rootState) {
      return state.b + rootState.count
    }
  }
}
export default b

使用

1、组合式API中使用

<script setup lang="ts">
import { useStore } from '@/vuex-store'
import { computed } from 'vue';
const store = useStore()
const count = computed(() => store.state.count)
</script>
<template>
  <div>
    <h1>404</h1>
    <p>root->count:{{ count }}</p>
    <p>root->double:{{ store.getters.double }}</p>
    <p>a->a:{{ store.state.a.a }}</p>
    <p>b->getB:{{ store.getters.getB }}</p>
    <button @click="store.commit('increment')">累加</button>
    <button @click="store.dispatch('increment')">累加</button>
  </div>
</template>

2、选项式API中使用

<template>
  <div>
    <h1>404</h1>
    <p>{{ count }}-{{ double }}-{{ getA }}-{{ getB }}</p>
    <button @click="increment">累加</button>
    <button @click="increment1">累加</button>
  </div>
</template>

<script lang="ts">
import { mapState, mapGetters, mapActions, mapMutations } from 'vuex';
import { defineComponent } from 'vue';
export default defineComponent({
  computed: {
    ...mapState(['count']),
    ...mapGetters(['double', 'getA', 'getB'])
  },
  methods: {
    ...mapActions(['increment']),
    ...mapMutations({
      increment1: 'increment'
    })
  }
})
</script>

store订阅mutation

store.subscribe((mutation, state) => {
  console.log('mutation操作', mutation, state)
})

store订阅action

store.subscribeAction((action, state) => {
  console.log('action操作', action, state)
})
store.subscribeAction(
  {
    before(action, state) {
      console.log('action操作前', action, state)
    },
    after(action, state) {
      console.log('action操作完成', action, state)
    },
    error(action, state, error) {
      console.log('action错误', action, state, error)
    }
  },
  { prepend: true }
)

配合vue中的v-modle实现双向绑定

1、组合式API

const count = computed({
  get () {
    return store.state.count
  },
  set (value) {
    store.commit('updateCount', value)
  }
})

2、选项式API

computed: {
  message: {
    get () {
      return this.$store.state.obj.message
    },
    set (value) {
      this.$store.commit('updateMessage', value)
    }
  }
}

关于命名空间

默认情况下,模块内部的 action 和 mutation 仍然是注册在全局命名空间的。使用 namespaced: true 添加命名空间。使用root: true  将命名空间内的属性添加到根。

1、选项式API组件中使用

// 直接通过嵌套名使用
...mapGetters([
  'some/nested/module/someGetter',
  'some/nested/module/someOtherGetter',
])

// 定义公共父模块
...mapGetters('some/nested/module', [
  'someGetter',
  'someOtherGetter',
])

// 使用createNamespacedHelpers创建基于某个命名空间辅助函数
import { createNamespacedHelpers } from 'vuex'
const { mapGetters, mapActions } = createNamespacedHelpers('some/nested/module')
...mapGetters([
  'someGetter',
  'someOtherGetter',
])

2、组合式Api组件中使用

const store = useStore()
store.commit('a/addA')

组合式API中使用,和选项式API通过this.$store使用方法一样,如果嫌命名空间太长,不好操作,可自己封装一个createNamespacedHelpers函数。

动态注册模块

store.registerModule('myModule', {
  // ...
})

// 注册嵌套模块 `nested/myModule`
store.registerModule(['nested', 'myModule'], {
  // ...
})

结语

一个广泛使用的Vue状态管理库,功能强大。做小项目练手的话,可以看看新兴的pinia

发布于: 2/21/2023, 6:34:26 PM
最后更新: 12/3/2024, 3:29:55 AM