本教程使用的是vue3
1.核心概念
- 官网地址:https://vuex.vuejs.org/
- 安装(固定)
- 配置项(固定)
2. 图示关系
单一定义store对象,里面5个配置项,在任意组件可以使用.
3.案例准备
准备两个组件AddItem.vue
、SubItem.vue
、Main.vue
展示效果如下:
AddItem
代码
<template>
<div>
<h3>AddItem组件</h3>
<p>已知库存数:0</p>
<button>库存数+1</button>
</div>
</template>
<script>
export default {
name: "AddItem"
}
</script>
<style scoped>
</style>
SubItem
代码
<template>
<div>
<h3>SubItem组件</h3>
<p>已知库存储0</p>
<button>库存1</button>
</div>
</template>
<script>
export default {
name: "SubItem"
}
</script>
<style scoped>
</style>
Main
代码:
<template>
<div id="app">
<h1>根组件</h1>
<span>库存总数:</span>
<input type="text">
<div style="border:1px solid black;width: 300px">
<AddItem></AddItem>
</div>
<hr>
<div style="border: 1px solid black;width: 300px;">
<sub-item></sub-item>
</div>
</div>
</template>
<script>
import AddItem from "@/views/vuexlearn/AddItem";
import SubItem from "@/views/vuexlearn/SubItem";
export default {
name: "main",
components: {SubItem, AddItem}
}
</script>
<style scoped>
#app{
width: 300px;
margin: 20px auto;
border:1px solid #ccc;
padding: 4px;
}
</style>
4.vuex-store准备
目标
- 创建store仓库
- 注入到vue项目中
4.1store概念
每个Vuex应用的核心strore(仓库),包含5个核心概念
- state:存储数据
- getters:相当于计算属性,会对计算结果进行缓存
- mutations:同步请求
- actions:异步请求
- modules:模块
4.2vuex目录
与路由模块router/index.js-类似,维护项目目录的整洁,新建src/store/index.js
当然,这个步骤并不是必需的
4.3使用步骤
- 1工程中-下载
vuex
// 使用npm下载
npm install vuex@3.5.1
// 使用yarn下载
yarn add vuex
- 2.
store/index.js
-创建定义导出store
对象
import {createStore} from 'vuex'
//创建数据仓库
export default createStore({
state:{},
getter:{},
mutations:{},
actions:{},
modules{}
})
- 3.main.js-导入注入到vue中
import {createApp} from 'vue'
import App from './App.vue'
//引进数据仓库
import createStore from './store/index.js'
const app = createApp(App)
app.use(createStore)
app.mount('#app')
5.vuex-state数据源
目标
- 定义state
- 直接使用state
- 辅助函数mapstate
state是唯一的数据源,统一存储
5.1 定义state
在 store/index.js
中定义state
语法:
//创建数据仓库
export default createStore({
//数据仓库的内容,名称不能乱写
state:{变量名:初始值}
})
具体代码:
//创建数据仓库
export default createStore({
//数据仓库的内容,名称不能乱写
state:{name:'马云',company:'阿里巴巴'}
})
5.2 使用state的使用方法
- 方式1:组内-直接使用
语法:
this.$store.state.变量名
- 方式2:组件内-映射使用(推荐)
语法:
<script>
import {useStore} from "vuex";
export default {
name: "SubItem",
setup(){
const store=useStore();
let count=store.state.count;
return{
count
}
}
}
</script>
6.getter方法的使用
6.1 定义getter
import {createStore} from 'vuex'
//创建数据仓库
const store = createStore({
//数据仓库的内容,名称不能乱写
state: {name: '马云', company: '阿里巴巴', count: 100},
getters: {
newName(state){
return state.name+"您好"
}
}
})
export default store
6.2 使用getter
- 方法1:直接调用
<template>
<div>
<h3>SubItem组件</h3>
<p>{{$store.getters.newName}}</p>
<p>{{$store.getters['newName']}}</p>
</div>
</template>
- 方法2:间接调用
import {useStore} from "vuex";
export default {
name: "SubItem",
setup(){
const store=useStore();
console.log(store.getters.newName);
return{
count
}
}
}
7.mutations方法的使用
7.1定义mutations
import {createStore} from 'vuex'
//创建数据仓库
const store = createStore({
//数据仓库的内容,名称不能乱写
state: {name: '马云', company: '阿里巴巴', count: 100},
getters: {
newName(state){
return state.name+"您好"
}
},
//同步调用
mutations: {
trigger(state) {
console.log('我是被actions调用的')
state.name = '马化腾'
},
exchange(state, val) {
state.company = val
},
updatecount(state){
state.count=10000
}
}
})
export default store
7.2 使用mutations
<template>
<div>
<h3>SubItem组件</h3>
<p>已知库存储{{count}}</p>
<button>库存1</button>
<button @click="mutationFn">改变数字</button>
</div>
</template>
<script>
import {useStore} from "vuex";
export default {
name: "SubItem",
setup(){
const store=useStore();
const mutationFn=()=>{
store.commit("updatecount")
}
return{
mutationFn
}
}
}
</script>
8.使用actions
8.1 定义actions方法
在使用actions方法的时候,必须先要调用mutations方法
import {createStore} from 'vuex'
//创建数据仓库
const store = createStore({
//数据仓库的内容,名称不能乱写
state: {name: '马云', company: '阿里巴巴', count: 100},
getters: {
newName(state){
return state.name+"您好"
}
},
//--------------------使用以下方法调用数据仓库里的数据-------------------------------
//同步调用
mutations: {
trigger(state) {
console.log('我是被actions调用的')
state.name = '马化腾'
}
},
//异步调用:必须要调用同步调用
actions: {
sub(store) {
//使用commit调用同步调用
store.commit('trigger');
}
},modules: {}
})
export default store
8.2使用actions方法
<template>
<div>
<h3>AddItem组件</h3>
<p>{{$store.state.name}}</p>
<button @click="changename">修改名字</button>
</div>
</template>
<script>
import {useStore} from "vuex";
//直接使用
export default {
name: "AddItem",
setup(){
const store=useStore();
const changename=()=>{
store.dispatch("sub")
}
return{
changename
}
}
}
</script>
9.Vuex模块处理
如果我们把所有状态都存储到state中,后期的维护会变来得困难,Store也会变的非常臃肿,为了解决这个问题Vuex允许我们将store分隔成模块.每一个模块都有自己的State,Mutation,Actions,Getter等.
在store中创建模块A和模块B,并且在index中注册模块
- 开启命名空间的模块化
modulesA
代码
export default {
namespaced:true,//开启命名空间
state: {
name: '马云',
company: '阿里巴巴',
count: 100
},
getter: {
newName(state) {
return state.name + "您好"
}
},
mutations: {
trigger(state) {
console.log('我是被actions调用的')
state.name = '马化腾'
},
exchange(state, val) {
state.company = val
},
updatecount(state) {
state.count = 10000
}
},
actions: {
sub(store) {
//使用commit调用同步调用
store.commit('trigger');
}
}
}
模块化在组件中进行调用:
AddItem
代码:
<template>
<div>
<h3>AddItem组件</h3>
<p>模块A开启的命名空间</p>
<p>{{$store.state.moudleA.name}}</p>
<p>已知库存数:{{$store.state.moudleA.count}}</p>
<p>{{$store.getters["moduleB/newName"]}}</p>
<button @click="btn">修改count</button>
<button>库存数+1</button>
</div>
</template>
<script>
import {useStore} from "vuex";
//直接使用
export default {
name: "AddItem",
setup(){
const store=useStore();
const btn=()=>{
store.commit('moudleA/updatecount');
}
return {btn}
}
}
</script>
- 关闭命名空间的模块化
moduleB
代码:
export default {
namespaced:false,//没有开启命名空间,除开state外,其他的都是注册在全局下的
state: {
username:"moudleB"
},
getter: {
newName(state) {
return state.name + "已经被修改"
}
},
mutations: {
update(state, val) {
state.username =val;
}
},
actions: {
exchange(store,val) {
//使用commit调用同步调用
store.commit('update',val);
}
}
}
模块化在组件中进行调用:
moudleB
代码:
<template>
<div>
<h3>SubItem组件</h3>
<p>username:{{username}}</p>
<button @click="btn">修改用户名</button>
<button @click="btn2">修改用户名-异步</button>
</div>
</template>
<script>
import {useStore} from "vuex";
import moudleB from "@/store/modules/moduleB";
export default {
name: "SubItem",
setup(){
const store=useStore();
const username=store.state.moudleB.username;
const btn=()=>{
//同步调用
console.log('进入btn')
store.commit('update','马化腾')
}
const btn2=()=>{
//异步调用
console.log('进入btn')
store.dispatch('exchange','刘强东')
}
return{
username,
btn,btn2
}
}
}
</script>
- 总结
调用state中的数据的时候,都需要使用格式$store.state.module.参数名
,如果开启了命名空间,则其他方法也得这么调用,未开启命名空间的则直接调用即可,因为他进行了全局注册.