一 Vuex是什么
1.1 首先学习Vuex是什么的概念
概念: Vuex是vue项目中实现大范围数据共享的技术方案
作用:是能够方便高效地实现组件之间的数据共享
好处:1 数据存取一步到位,不需要层层传递,2 数据流动清晰,3 存储的在Vuex中的数据都是响应式的
1.2 什么样的数据适合存储到Vue中
那种需要频繁,大范围的数据共享,就可以存储到Vuex当中
二 安装Vuex
1 安装依赖包 :npm i vuex@3.6.2(V2的版本)
2 导入包 impoft Vuex from 'Vuex'
3 安装插件 Vue.use(Vuex)
4 创建store =new Vuex.Store({ })
5 挂载Vue实例
new Vue({
store // 2. 注入Vue实例
})
开发中我们一般都抽离main.js中的Vuex
新建src/store/index.js
import Vue from 'vue'
// 1 导入
import Vuex from 'vuex'
//2 安装插件
Vue.use(Vuex)
// 3 创建Store对象
const store = new Vuex.Store({
state: {
count: 0
}
})
export default store
在mian.js中导入store文件
import Vue from 'vue'
import App from './App.vue'
import '@/assets/css/bootstrap.css'
// 导入store
import store from './store'
Vue.config.productionTip = false
new Vue({
// 挂载到vue实例
store,
render: h => h(App),
}).$mount('#app')
三 认识核心成员1 State
3.1 概念:什么是State
- 概念:
State本质上就是Object对象 - 作用:
用来存储全局共享的数据
3.2 State定义公共数据的格式
new Vuex.store({
state: {
属性名: 属性值
}
})
3.3 组件访问State数据的第一种方式
- 在组件中,通过
this.$store.state.属性名来访问。
export default {
name: 'Left',
methods:{
add(){
this.$store.state.count++
}
}
}
- 在模板中,则可以省略
this而直接写成:{{$store.state.属性名}}
<p>count 值:{{$store.state.count}}</p>
3.4 组件访问State数据的第二种方式,mapState 辅助函数来映射数据
//直接就可以使用了
<p>利用辅助函数来渲染值:{{str}},{{count}}</p>
<script>
import {mapState} from 'vuex'
export default {
name: 'kk',
computed:{
// 把需要的全局数据,映射为当前组件的计算属性
// 返回值就是一个对象,展开这个对象的中的值
...mapState(['count','str'])
}
}
</script>
三 认识核心成员2 Mutation
概念:变异。 它是Vuex中用来修改公共数据的唯一入口。因为在Vuex中是不能直接修改数据的的值,因为直接修改Vuex是监测不到的,如果这个共享数据多个组件使用,一旦出了问题,我们排查起来就很困难。所以我们要知道是哪个地方修改了这个值,就必须同Mutation来修改。
两个参数- 参数一:所有的mutations的函数,第一个参数一定是state
- 参数二:接收传过来的值
方法1 commit方法:
1:在vuex中定义Mutation方法
mutations:{
// 重点:所有的mutations的函数,第一个参数一定是state
// 重点:第二个参数payload(载荷),是传过来的值
addCount(state,payload){
state.count+=payload.num
}
}
2:在组件中调用Mutation方法
<button class="btn btn-primary" @click="$store.commit('addCount',5)">+5</button><br>
<button class="btn btn-primary" @click="$store.commit('addCount',{num:10})">+10</button><br>
方法2:辅助函数mapMutations
组件中methods中映射,然后调用
<button class="btn btn-primary" @click="addCount({num:20})">20</button><br>
<script>
import {mapMutations} from 'vuex'
export default {
name: 'Left',
methods:{
...mapMutations(['addCount'])
}
}
</script>
vuex中定义
import Vue from 'vue'
// 1 导入
import Vuex from 'vuex'
Vue.use(Vuex)
// 2 创建Store对象
const store = new Vuex.Store({
state: {
count: 1,
str:'假如生活欺骗了你'
},
mutations:{
// 重点:所有的mutations的函数,第一个参数一定是state
addCount(state,payload){
state.count+=payload.num
}
}
})
export default store
三 认识核心成员3 Action
概念:对于异步变更数据Mutation是无法监测到的(请求,定时器等)这时需要Action来处理,所以Action本质上是JavaScript函数,专门用来处理Vuex中的异步操作。
用法
- 两个参数:
- 参数1:上下文对象context(形参),用于调用其他成员的方法。
- 参数2:载荷payload(形参),用于传参
vuex中定义
import Vue from 'vue'
// 1 导入
import Vuex from 'vuex'
Vue.use(Vuex)
// 2 创建Store对象
const store = new Vuex.Store({
state: {
count: 1,
str:'假如生活欺骗了你'
},
mutations:{
// 重点:所有的mutations的函数,第一个参数一定是state
addCount(state,payload){
state.count+=payload.num
}
},
actions:{
// 在actions做异步的操作,然后交给mutations修改
// 怎么交个mutations呢,commit
// 怎么调用commit
// 接收形参:上下文对象($store)
// 通过dispatch方法,调用指定名称Action方法
addCountAsync(context,payload){
console.log(payload,"这是payload数据");
console.log(context,"这是contex数据");
setTimeout(()=>{
context.commit('addCount',payload)
},1000)
}
}
})
export default store
上下文对象 context(形参),中就可以调用commit的方法
组件用dispatch方法调用
<button class="btn btn-primary" @click="$store.dispatch('addCountAsync',{num:30})">异步加30</button><br>
actions的mapActions辅助函数
<button class="btn btn-primary" @click="addCountAsync({num:100})">异步加100</button><br>
组件中methods中映射,然后调用
<script>
import {mapActions, mapMutations,} from 'vuex'
export default {
name: 'Left',
methods:{
...mapMutations(['addCount']),
...mapActions('[addCountAsync]')
}
}
</script>
四 认识核心成员4 Getters
- 概念:Getter本质上JavaScript的函数,用来统计全局属性的状态值
- 作用:他是Vuex的
全局计算属性,当Store数据源发生变化时,getter的返回值会自动更新。
import Vue from 'vue'
// 1 导入
import Vuex from 'vuex'
Vue.use(Vuex)
// 2 创建Store对象
const store = new Vuex.Store({
state: {
count: 1,
str:'假如生活欺骗了你',
books: [
{
"name": "javasript技术内幕",
"price": 100,
"isAllDone": false
},
{
"name": "数学之美",
"price": 44,
"isAllDone": false
},
{
"name": "认知天性",
"price": 40,
"isAllDone": false
}
]
},
getters:{
isAllDone(state,payload){
return state.books.every(item=>item.isAllDone)
}
}
})
export default store
<h1>{{$store.getters.isAllDone}}</h1>
总结:现在多个地方用到isAllDone的状态,只要Vuex的isAllDone改变了,组件用到的这个值,也就跟着改变了。
computed 中使用辅助函数mapGetters,将Getters中的变量映射到当前的组件中使用
<h1>{{isAllDone}}</h1>
import {mapGetters} from 'vuex'
export default {
name: 'Left',
computed:{
...mapGetters(['isAllDone'])
}
}
五 认识核心成员5 Module
场景:很多个组件的state,mutations,actions。getters,都掺杂在一起,结构混乱,不利于维护。所以衍生出了Module,每个组件的Vuex数据都划分成独立的模块,每个模块拥有自己的state,mutations,actions,getters
用法:新建模块,在moude导入模块,注册模块,namespaced开启命名空间
访问方法
访问数据和修改数据的调整
-
访问模块中的数据,要加上模块名
获取数据项: {{$store.state.模块名.数据项名}} 获取getters: {{$store.getters['模块名/getters名']}} -
访问模块中的mutations/actions:
- 如果namespaced为true,则需要额外去补充模块名
- 如果namespaced为false,则不需要额外补充模块名
$store.commit('mutations名') // namespaced为false $store.commit('模块名/mutations名') // namespaced为true
用斜线来分割,斜线前是模块名,斜线后是方法名
<button class="btn btn-warning" @click="$store.commit('count/updata')">调用</button>
总结:划分module下访问数据和方法总结
不用辅助函数的访问store
//模块名count
//数据名:str1
<h2>{{$store.state.count.str1}}</h2>
使用辅助函数mapState来调用
<template>
<div class="right-container">
<h3>Right 组件</h3>
<!--1 module模块下调用数据 -->
<h1>{{str}}</h1>
<hr>
<!-- 2 module模块下调用方法 -->
<button class="btn btn-warning" @click="$store.commit('count/updata')">调用</button>
</div>
</template>
<script>
import{mapState}from'vuex'
export default {
name: 'Right',
computed:{
// 参数1:访问模块名
// 参数2:访问的数据名
...mapState('count',['str'])
}
}
</script>
<style>
</style>
六 总结四个核心成员在模块下的用法
模块
// 定义count模块
export default {
// 开启命名空间
namespaced:true,
// 简写
state:()=>({
str:'假如生活欺骗了你',
str1:'不要悲伤,不要心急'
}),
mutations: {
updata(){
console.log("count模块下mutations被调用了");
}
},
actions: {
test(){
console.log("count下actions方法调用了");
}
},
getters:{
gettData(state){
return state.str+'因为他明天还会继续欺骗你'
}
},
}
组件
<template>
<div class="right-container">
<h3>Right 组件</h3>
<!--1 module模块下辅助函数调用数据 -->
<h1>{{str}}</h1>
<!-- modeule模块下普通调用 -->
<h2>{{$store.state.count.str1}}</h2>
<hr>
<!-- 2 module模块下调用方法 -->
<!-- Mutations调用 -->
<button class="btn btn-warning" @click="$store.commit('count/updata')">Mutations普通调用</button>
<button class="btn btn-warning" @click="updata">Mutations辅助调用</button>
<!--Actions调用 -->
<button class="btn btn-warning" @click="$store.dispatch('count/test')">Actions普通调用</button>
<button class="btn btn-warning" @click="test">Actions辅助调用</button>
<!-- getter -->
<h1>{{gettData}}</h1>
</div>
</template>
<script>
import{mapState,mapMutations,mapActions,mapGetters}from'vuex'
export default {
name: 'Right',
computed:{
// 参数1:访问模块名
// 参数2:访问的数据名
...mapState('count',['str']),
...mapGetters('count',['gettData'])
},
methods:{
...mapMutations('count',['updata']),
...mapActions('count',['test'])
}
}
</script>
<style>
</style>