Vuex 学习笔记 01
Vuex 介绍
1. 什么是 Vuex
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 + 库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
说明:Vuex 是 vue 组件之间数据传递的方式,任意组件都可以使用
2. 什么是状态管理模式
状态自管理应用包含以下几个部分:
- 状态(State): 驱动应用的数据源;
- 视图(View): 以声明方式将状态映射到视图;
- 操作(Actions): 响应在视图上的用户输入导致的状态变化。
安装、使用 Vuex
1. 安装 Vuex
// npm 安装
npm install vuex@next --save
// yarn 安装
yarn add vuex@next --save
2. 在项目的 src 文件下面创建 store 文件夹,store 文件夹下面 创建 store.js 文件 和 moudeles 文件夹。store.js 中的代码:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex) // 将vuex安装到vue上
const store = new Vuex.Store({
modules:{
app
}
})
export default store; // 将 store 暴露出去
3. 在项目的 src 目录下 store 目录下的 moudeles 文件夹下面创建 app.js 文件,代码如下:
const app = {
state:{ // 全局状态 },
mutations:{ // 修改状态的方法 },
actions:{ // 异步提交mutation的方法 },
getters:{ // 对store 的数据进行加工处理 类似计算属性 }
}
export default app; // 将 app 暴露出去
4. 在 main,js 文件中全局注册使用
import store from './store'
new Vue({
store, // 全局使用
render:(h)=>h(App)
}).$mount("#app")
核心概念
1. State
- Vuex 使用单一状态树——是的,用一个对象就包含了全部的应用层级状态。
- 说明:state 就是储存数据的仓库、容器
获取 state 数据
- 直接获取: this.$store.store.xxx
- mapState 辅助函数
- 引入辅助函数: import { mapState } from 'Vuex'
- 在计算属性中获取 state
- computed: { ...mapState({ 'user' }) }
- 使用 {{ user }}
- 传参获取:computed: mapState({})
// store.js 文件代码
const store = {
state:{ user:'smaleLing' // 全局状态 },
}
export default store;
// Home.Vue 文件代码 html 代码
<template>
<h1>store里面的state用户名是:{{ $store.state.user }}</h1> // 直接获取全局状态数据
<h1>store里面的state用户名是:{{ user }}</h1> // 对象展开运算符获取全局状态数据
/**
*<h1>store里面的state用户名是:{{ user1 }}</h1> // 辅助函数获取全局状态数据
*<h1>store里面的state用户名是:{{ user2 }}</h1> // 辅助函数获取全局状态数据
*<h1>store里面的state用户名是:{{ user3 }}</h1> // 辅助函数获取全局状态数据
**/
</template>
// Home.Vue 文件代码 js 代码
<script>
import { mapState } from 'Vuex' // 引入辅助函数
export default {
data() {
return {
msg:'data的数据'
}
},
computed:{
...mapState({ 'user' }) // 对象展开运算符
},
/**
* computed: mapState({
* // 箭头函数可使代码更简练
* user1: state => state.user,
*
* // 传字符串参数 'user' 等同于 `state => state.user`
* user2: 'user',
*
* // 为了能够使用 `this` 获取局部状态,必须使用常规函数
* user3 (state) {
* return state.user + this.msg
* }
**/
}
</script>
2. Mutation
- 更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。
- 说明:mutations 里面装着一些改变数据方法的集合,就是把处理数据逻辑方法全部放在 mutations 里面,使得数据和视图分离。
- 重要的原则: mutation 必须是同步函数
操作 mutation
- 直接操作: this.$store.commit('mutation函数名')
- 传递参数: this.$store.commit('mutation函数名','参数')
- mapMutations 辅助函数
- 引入辅助函数: import { mapMutations } from 'Vuex'
- 在方法中操作 mutation
- methods: { ...mapMutations(['add','sub']) }
- 使用 this.add() this.sub(num) num 是传的参数
//store.js
const store ={
state: {
count: 1
},
mutations: {
// 注册事件:type:add,handler 第一个参数是 state;
add (state) {
// 变更状态
state.count++
},
// 注册事件:type:sub,handler 第一个参数是 state, 第二个参数是 patload
sub (state,payload) {
state.count = payload - state
}
}
}
export default store;
// Home.Vue 文件代码 html 代码
<template>
<button @click="add">+</button>
<button @click="sub">-</button>
<button @click="addMutations">辅助函数+</button>
<button @click="subMutations">辅助函数-</button>
</template>
// Home.Vue 文件代码 js 代码
<script>
import { mapMutations } from 'Vuex'
export default {
methods:{
...mapMutations(['add','sub'])
add(){
// 调用 type(store里面函数名),触发 handler(state)
this.$store.commit('increment');
},
sub(){
// 调用 type(store里面函数名),触发 handler(state), 传参 payload
this.$store.commit('sub',20);
// 对象风格提交方式
/**
* this.$store.commit({
* type: 'sub',
* payload: 20
* })
**/
},
addMutations(){
this.add()
},
subMutations(){
this.sub(20) // 直接传参
}
}
}
</script>
Action
Action 类似于 mutation,不同在于:
- Action 提交的是 mutation,而不是直接变更状态。
- Action 可以包含任意异步操作,也可以是同步操作。
操作 action
- 直接操作: this.$store.dispatch('action函数名')
- mapActions 辅助函数
- 引入辅助函数: import { mapActions } from 'Vuex'
- 在方法中操作 action
- methods: { ...mapActions(['add','sub']) }
- 使用 this.add() this.sub(num) num 是传的参数
//store.js
const store ={
state: {
count: 1
},
mutations: {
// 注册事件:type:add,handler 第一个参数是 state;
add (state) {
// 变更状态
state.count++
},
// 注册事件:type:sub,handler 第一个参数是 state, 第二个参数是 patload
sub (state,payload) {
state.count = payload - state
}
},
actions: {
// 定义异步操作 context 是最大的 store
asyncAdd (context) {
setTimeout(()=>{
context.commit('add')
},500)
},
// 定义异步操作 payload 是传的参数
asyncSub (context,payload) {
setTimeout(()=>{
context.commit('sub',payload)
},500)
}
}
}
export default store;
// Home.Vue 文件代码 html 代码
<template>
<button @click="add">+</button>
<button @click="sub">-</button>
<button @click="addActions">辅助函数+</button>
<button @click="subActions">辅助函数-</button>
</template>
// Home.Vue 文件代码 js 代码
<script>
import { mapActions } from 'Vuex'
export default {
methods:{
...mapActions(['asyncAdd','asyncSub'])
add(){
// 触发 dispatch 直接调用 actions
this.$store.dispatch('asyncAdd');
},
sub(){
// 触发 dispatch 直接调用 actions payload:20 传到 actions 的参数
this.$store.dispatch('asyncSub',20);
// 对象风格触发方式
/**
* this.$store.dispatch({
* context: 'asyncSub',
* payload: 20
* })
**/
},
addActions(){
this.asyncAdd()
},
subActions(){
this.asyncSub(20) // 直接传参
// 对象风格提交方式: store.dispatch({payload: 20})
}
}
}
</script>
Getter
- store 中的 state 中派生出一些状态
- Vuex 允许我们在 store 中定义 'getter'(可以认为是 store 的计算属性)
- 说明:对 state 里面的数据进行加工处理
使用 getter
- 直接使用: this.$store.getters.属性
- mapGetters 辅助函数
- 引入辅助函数: import { mapGetters } from 'Vuex'
- 在计算属性中使用 getter
- : computed: { ...mapGetters(['todoCount']) }
// store.js 文件代码
const store = {
state:{
user:'smaleLing',
sex:'female'
},
getters:{
updateInfo:(state) => {
const info = '名字:' + state.user + '性别:' + state.sex
return info
}
}
}
export default store;
// Home.Vue 文件代码 html 代码
<template>
<h1>用户信息:{{ $store.getters.updateInfo }}</h1> // 直接使用 getter
<h1>用户信息:{{ updateInfo }}</h1> // 使用 mapGetters 辅助函数
</template>
// Home.Vue 文件代码 js 代码
<script>
import { mapGetters } from 'Vuex' // 引入辅助函数
export default {
computed:{
...mapGetters(['updateInfo']) // 对象展开运算符
},
}
</script>
Module
- Vuex 允许我们将 store 分割成模块(module) 。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块。
- 随着项目的复杂度增大,为了方便管理vuex,一般会将其按功能分割成不同的模块(module),方便日后管理。
- 如果希望你的模块具有更高的封装度和复用性,你可以通过添加 namespaced: true 的方式使其成为带命名空间的模块
项目结构
src
└── store
├── index.js // 组装模块并导出 store
├── mutations.js // 根级别的 mutation
├── actions.js // 根级别的 action
├── getters.js // 根级别的 getters
└── modules
├── login.js // 登录模块
└── users.js // 用户模块
// index.js 代码
import Vue from 'vue'
import Vuex from 'vuex'
import mutations from './mutations'
import actions from './actions'
import getters from './getters'
import login from './modules/login'
import users from './modules/users'
Vue.use(Vuex)
const store = new Vuex.Store({
// 根节点
mutations,
getters,
actions,
// 模块
modules: {
users,
login
}
})
export default store;
// login.js 代码
const login = {
state:{ // 全局状态 },
mutations:{ // 修改状态的方法 },
actions:{ // 异步提交mutation的方法 },
getters:{ // 对store 的数据进行加工处理 类似计算属性 }
}
export default login;
// users.js 代码
const login = {
state:{ // 全局状态 },
mutations:{ // 修改状态的方法 },
actions:{ // 异步提交mutation的方法 },
getters:{ // 对store 的数据进行加工处理 类似计算属性 }
}
export default users;
- @Title: Vuex 学习笔记 01
- @Content: Vue
- @Autor: ling.wang
- @StudyDate: 2022-02-22 ~ 2022-02-22
- @WritingDate: 2022-02-23