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.使用数据
- 通过store直接访问
- 通过辅助函数(简化)
获取store:
- this.$store
- 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
- getters函数的第一个参数是state
- getters函数必须要有返回值
getters: {filterList (state) {return state.list.filter(item => item > 5)}}
访问getters
- 通过store访问getters
- 通过辅助函数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状态管理工具的代替品
优点:
- 提供更简单的API(去掉了mutation)
- 提供符合,组合式风格的API(和Vue3新语法统一)
- 去掉了modules的概念,每一个store都是一个对立的模块
- 配合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)