Vuex概述

vuex是一个vue的状态管理工具,状态就是数据(多组件共享数据)。

优势:

  • 共同维护一份数据,数据集中化管理
  • 响应式变化
  • 操作简洁(vuex提供了一些辅助函数)

vuex的使用

安装vuex插件

yarn add vuex@3

创建vuex模块文件

新建store/index.js专门存放vuex

创建仓库

import Vue from 'vue'import Vuex from 'vuex'Vue.use(Vuex)const store = new Vuex.Store()export default store

main.js导入挂载

import Vue from 'vue'import App from './App.vue'import store from '@/store/index'Vue.config.productionTip = falsenew Vue({render: h => h(App),store}).$mount('#app')

state状态

1.提供数据

state提供唯一的公共数据源,所有共享的数据都要统一放到Store中的stare中储存。

在state对象中可以添加我们要共享的数据。

const store = new Vuex.Store({state: {title: '大标题',count: 100}})

2.使用数据

  1. 通过store直接访问
  2. 通过辅助函数(简化)

获取store:

  1. this.$store
  2. import 导入 stroe

直接访问

数据:{{ $store.state.count }}

辅助函数mapstate

mapstate是辅助函数,帮助我们把store中的数据自动映射到组件的计算机属性中。

导入mapState

import { mapState } from 'vuex'

通过对象的方式映射

computed: {...mapState(['count', 'title'])}

在模板中使用

数据:{{ count }}

mutations

1.定义mutations对象,对象中存放修改state的方法

import Vue from 'vue'import Vuex from 'vuex'Vue.use(Vuex)const store = new Vuex.Store({state: {title: '大标题',count: 100},mutations: {addcount (state) {state.count += 1},subcount (state) {state.count -= 1}}})export default store

2.组件中提交调用mutations

数据:{{ this.$store.state.count }}

export default {name: 'Son1Component',methods: {handleAdd () {this.$store.commit('addcount')}}}

mutations传参语法

提交mutations是可以传递参数的’this.$store,commit(‘xxx’,参数)’

1.提供mutation函数(带参数—提交载荷payload)

import Vue from 'vue'import Vuex from 'vuex'Vue.use(Vuex)const store = new Vuex.Store({state: {title: '大标题',count: 100},mutations: {addcount (state, n) {state.count += n},subcount (state, n) {state.count -= n}}})export default store

数据:{{ this.$store.state.count }}

export default {name: 'Son1Component',methods: {handleAdd (n) {this.$store.commit('addcount', n)}}}

传递多个参数时,可以包装成一个对象传递

handleAdd (n) {this.$store.commit('addcount', {count: n,msg: 'haha'})}
addcount (state, obj) {state.count += obj.countconsole.log(obj.msg)}

input的实时输入更新

输入框渲染

监听输入获取内容

methods: {handInput (e) {this.$store.commit('changecount', e.target.value)}

封装mutation处理函数

changecount (state, newcount) {state.count = newcount}

辅助函数mapMutations

mapMutations和mapState很像,它是把位于mutations中的方法提取了出来,映射到组件methods中

数据:{{ this.$store.state.count }}

import { mapMutations } from 'vuex'export default {name: 'Son1Component',methods: {...mapMutations(['subcount'])}}

actions

处理异步处理,mutations必须是同步的(便于监测数据变化,记录调试)

1.提供action方法

actions: {changecountactions (context, num) {setTimeout(() => {context.commit('changecount', num)}, 1000)}}

在页面中dispath调用

handchange (n) {this.$store.dispatch('changecountactions', n)}

辅助函数mapActions

mapActions是把位于actions中的方法提供了出来,映射到组件methods中

数据:{{ this.$store.state.count }}

import { mapMutations, mapActions } from 'vuex'export default {name: 'Son1Component',methods: {...mapMutations(['subcount']),...mapActions(['changecountactions'])}}

getters

类似于计算属性

除了state之外,有时我们还需要从state中派生出一些状态,这些状态是依赖state的,此时会用到getters。

定义getters

  1. getters函数的第一个参数是state
  2. getters函数必须要有返回值
getters: {filterList (state) {return state.list.filter(item => item > 5)}}

访问getters

  1. 通过store访问getters
  2. 通过辅助函数mapGetters映射
{{ $store.getters.filterList }}

数据:{{ this.$store.state.count }}


{{ filterList }}import { mapMutations, mapActions, mapGetters } from 'vuex'export default {name: 'Son1Component',methods: {...mapMutations(['subcount']),...mapActions(['changecountactions'])},computed: {...mapGetters(['filterList'])}}

Pinia

Pinia是vue的专属的最新状态管理库,是Vuex状态管理工具的代替品

优点:

  1. 提供更简单的API(去掉了mutation)
  2. 提供符合,组合式风格的API(和Vue3新语法统一)
  3. 去掉了modules的概念,每一个store都是一个对立的模块
  4. 配合TypeScript更加友好,提供可靠的类型推断

手动添加Pinia到Vue项目

在实际开发项目时,关于Pinia的配置,可以在创建项目时自动添加

1.使用Vite创建一个空的Vue3项目

2.按照官方文档安装pinia项目中

yarn add pinia# 或者使用 npmnpm install pinia
import './assets/main.css'import { createApp } from 'vue'import {createPinia} from 'pinia'import App from './App.vue'const pinia = createPinia()const app = createApp(App)app.use(pinia).mount('#app')

Pinia基础使用

1.定义store

import { defineStore } from 'pinia'import { ref } from 'vue'export const usecounterstore = defineStore('counter',()=>{const count = ref(100)return {count}})

2.组件使用store

import son1 from "@/components/son1.vue"import son2 from "@/components/son2.vue"import {usecounterstore} from "@/store/counter"const counterstore = usecounterstore()

数据:{{ counterstore.count }}

import { defineStore } from 'pinia'import { ref,computed } from 'vue'export const usecounterstore = defineStore('counter',()=>{// 声明数据stateconst count = ref(100)// 声明操作数据的方法active(普通函数)const addcount = ()=>count.value++const subcount = ()=>count.value--//声明基于数据派生的计算属性getters(computed) const double = computed(() => count.value*2)return {count,addcount,subcount,double}})

active异步实现

import { defineStore } from 'pinia'import { ref,computed } from 'vue'export const usecounterstore = defineStore('counter',()=>{// 声明数据stateconst count = ref(100)// 声明操作数据的方法active(普通函数)const addcount = ()=>count.value++const subcount = ()=>count.value--//声明基于数据派生的计算属性getters(computed) const double = computed(() => count.value*2)return {count,addcount,subcount,double}})
import son1 from "@/components/son1.vue"import son2 from "@/components/son2.vue"import {usecounterstore} from "@/store/counter"import {usechannelstore} from "@/store/channel"const counterstore = usecounterstore()const usestore = usechannelstore()

数据:{{ counterstore.count }}


  • {{ item.name }}

storeToRefs

用于将 Pinia store 实例中的状态属性转换为 ref 对象。

import { defineStore } from 'pinia';const useMyStore = defineStore({id: 'myStore',state: () => ({count: 0,text: 'Hello, Pinia!',}),});// 在组件中使用 storeToRefs 将状态转换为 ref 对象const myStore = useMyStore();const { count, text } = pinia.storeToRefs(myStore);

Pinia持久化

1.安装插件 pinia-plugin-persistedstate

npm i pinia-plugin-persistedstate

2.main.js使用

import persist from ‘pinia-plugin-persistedstate’

app.use(createPinia().use(persist))

import './assets/main.css'import persist from 'pinia-plugin-persistedstate'import { createApp } from 'vue'import {createPinia} from 'pinia'import App from './App.vue'const pinia = createPinia()const app = createApp(App)app.use(pinia.use(persist))app.mount('#app')

3.store仓库中,persist:true开启

import { defineStore } from 'pinia'import { ref,computed } from 'vue'export const usecounterstore = defineStore('counter',()=>{// 声明数据stateconst count = ref(100)// 声明操作数据的方法active(普通函数)const addcount = ()=>count.value++const subcount = ()=>count.value--//声明基于数据派生的计算属性getters(computed) const double = computed(() => count.value*2)return {count,addcount,subcount,double}},{persist:true})

详细见配置 | pinia-plugin-persistedstate (prazdevs.github.io)