VueX使用备忘
1. Vuex 介绍
Vuex 是专门为 Vue应用程序开发的状态管理模式,
它采用集中式存储管理应用的所有组件状态,
并以相应的规则保证状态以一种可预测的方式发生变化。
可以理解为:将多个组件共享的变量全部存储在一个对象里面,
然后将这个对象放在顶层的 Vue 实例中,
让其他组件可以使用,它最大的特点是响应式。
一般情况下,我们会在 Vuex 中存放一些需要在多个界面中进行共享的信息。
比如用户的登录状态、用户名称、头像、地理位置信息、商品的收藏、购物车中的物品等,
这些状态信息,我们可以放在统一的地方--Vuex,对它进行保存和管理;
2. Vuex 插件的安装
// 安装时记的带上@版本号, Vue2-vuex3, Vue3-vuex4
// 注意: vue2.x 版本对应 vuex 3 .x 版本,vue3.x版本对应 vuex 4 .x 版本
// 不加@版本号,则默认安装最新的vuex,会造成Vue2等较低版本无法使用vuex功能;
npm install --save vuex@3.6.2
3. Vuex环境的搭建
store 对象中存放的东西是固定的,
主要有:state、mutations、actions、getters、modules
下图为官方给出的vuex状态管理图例:
3-1 src下新建store文件夹,创建 index.js,引入/安装/创建并导出Vuex
import Vue from 'vue'
import Vuex from 'vuex'
Vue. use ( Vuex)
const store = new Vuex. Store ( {
state : {
counter : 1000
} ,
mutations : {
} ,
actions : {
} ,
getters : {
} ,
modules : {
}
} )
export default store
3-2 在 main.js中挂载使用
import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store'
Vue. config. productionTip = false
new Vue ( {
el : '#app' ,
router,
store,
render : h => h ( App)
} )
3-3 Vuex的基本使用
1 . 获取state的状态[ 数据] :state中存放需要共享的状态[ 数据] 信息,
使用时通过 $store .state.counter 即可拿到状态[ 数据] 信息
2 . 修改state的状态[ 数据] :
获取store对象,通过 commit 提交 mutations 中的方法
如:Vue中使用实例:
methods:{
sub ( ) {
this.$store .commit( "decrement" )
} ,
add ( ) {
this.$store .commit( "increment" )
}
}
3 . devtools 开发工具的调试界面,可以跟踪查看每一次事件操作,此处不赘述了
4. Vuex 中各配置项详解及使用实例
4-1 State
单一状态树即单一数据源,
在一个项目中只使用一个store对象,
来存储所有共享的状态信息
4-2 Getters
getters : {
powerCounter ( state ) {
return state. counter * state. counter
} ,
more20stu ( state ) {
return state. students. filter ( s => s. age > 20 )
} ,
more20stuLength ( state, getters ) {
return getters. more20stu. length
} ,
moreAgeStu ( state ) {
return function ( age ) {
return state. students. filter ( s => s. age > age)
}
}
}
< h2> { { $store. getters. powerCounter} } < / h2>
< h2> { { $store. getters. more20stu} } < / h2>
< h2> { { $store. getters. more20stuLength} } < / h2>
< h2> { { $store. getters. moreAgeStu ( 18 ) } } < / h2>
4-3 Mutations
4-3-1 Mutations自定义方法实例
mutations : {
increment ( state ) {
state. counter++
} ,
decrement ( state ) {
state. counter--
} ,
incrementCount ( state, payload ) {
state. counter += payload. count
} ,
addStudent ( state, obj ) {
state. students. push ( obj)
}
}
4-3-2 Vue组件使用mutations的实例
< template>
< div>
< button @click= "addCount(5)" > + 5 < / button>
< button @click= "addCount(10)" > + 10 < / button>
< button @click= "addStudent({id:105, name:'name6', age:29})" > 添加学生< / button>
< / div>
< / template>
< script>
export default {
name : "HelloVuex" ,
methods : {
addCount ( count ) {
this . $store. commit ( {
type : 'incrementCount' ,
count : count
} )
} ,
addStudent ( stu ) {
this . $store. commit ( 'addStudent' , stu)
}
}
}
< / script>
< style>
< / style>
4-4 Actions
4-4-1 实例1
actions : {
aUpdateInfo ( context, payload ) {
setTimeout ( ( ) => {
context. commit ( 'updateInfo' , payload)
console. log ( payload) ;
} , 5000 ) ;
}
}
updateInfo ( ) {
this . $store. dispatch ( 'aUpdateInfo' , '参数' )
}
4-4-2 实例2
actions : {
aUpdateInfo ( context, payload ) {
return new Promise ( ( resolve, reject ) => {
setTimeout ( ( ) => {
context. commit ( 'updateInfo' ) ;
console. log ( payload) ;
resolve ( '11111' )
} , 1000 ) ;
} )
}
}
methods : {
updateInfo ( ) {
this . $store
. dispatch ( 'aUpdateInfo' , '参数' )
. then ( res => {
console. log ( '里面完成了提交' ) ;
console. log ( res) ;
} )
}
}
5. 多组件共享数据实例_天禹老师Vue教程中演示
5-1 实例图形展示
5-2 实例具体代码
5-2-1 实例相关说明
本例有两个组件,分别是,
Count组件, 详见Count. vue。
Person组件,详见Person. vue。
Count组件和Person组件共享以下两个数据[ 存储在state中,名称自定义的] :
sum ,
personList
代码主要涉及如下几个文件,
main. js,本例中不涉及变更。
App. vue,本例不涉及变更。
store/ index. js,本例中,会发生多次变更。
Person. vue,本例中,会发生多次变更。
Count. vue,本例中,会发生多次变更。
5-2-2 main.js
import Vue from 'vue'
import App from './App.vue'
import store from "./store" ;
Vue. config. productionTip = false
const vm = new Vue ( {
render : h => h ( App) ,
store
} ) . $mount ( '#app' ) ;
console. log ( vm) ;
5-2-3 App.vue
< template>
< div id = " app" >
< Count/>
< hr>
< Person/>
</ div>
</ template>
< script>
import Count from './components/Count.vue' ;
import Person from './components/Person.vue' ;
export default {
name : 'App' ,
components : {
Count,
Person
}
}
</ script>
5-2-4 store/index.js
import Vue from "vue" ;
import Vuex from "vuex" ;
Vue. use ( Vuex) ;
const state = {
sum : 0 ,
personList : [
{ id : "001" , name : "张三" }
]
} ;
const getters = {
bigSum ( state ) {
return state. sum* 10 ;
}
}
const actions = {
jiaOdd ( context, value ) {
if ( context. state. sum % 2 ) {
context. commit ( "JIA" , value) ;
}
} ,
jiaWait ( context, value ) {
setTimeout ( ( ) => {
context. commit ( "JIA" , value) ;
} , 500 )
}
} ;
const mutations = {
JIA ( state, value ) {
state. sum += value;
} ,
JIAN ( state, value ) {
state. sum -= value;
} ,
ADD_PERSON ( state, personObj ) {
state. personList. unshift ( personObj) ;
}
} ;
export default new Vuex. Store ( {
state,
getters,
actions,
mutations
} )
5-2-5 Person.vue
< template>
< div>
< h2> 人员列表</ h2>
< h3 style = " color : red" > Count组件的当前和为{{sum}}</ h3>
< input type = " text" placeholder = " 请输入姓名" v-model = " name" />
< button @click = " add" > 添加</ button>
< ul>
< li v-for = " p in personList" :key = " p.id" > {{p.name}}</ li>
</ ul>
</ div>
</ template>
< script>
import { nanoid} from "nanoid" ;
export default {
name : "Person" ,
data ( ) {
return {
name : ""
}
} ,
computed : {
personList ( ) {
return this . $store. state. personList;
} ,
sum ( ) {
return this . $store. state. sum;
}
} ,
methods : {
add ( ) {
const personObj = {
id : nanoid ( ) ,
name : this . name
}
this . $store. commit ( "ADD_PERSON" , personObj) ;
this . name = "" ;
}
}
}
</ script>
< style scoped >
button {
margin-left : 5px;
}
</ style>
5-2-6 Count.vue
< template>
< div class = " count" >
< h2> 当前求和为{{sum}}</ h2>
< h2> 当前求和放大10倍为{{bigSum}}</ h2>
< h3 style = " color : red" > Person组件的总人数为{{personList.length}}</ h3>
< select v-model = " num" >
< option :value = " 1" > 1</ option>
< option :value = " 2" > 2</ option>
< option :value = " 3" > 3</ option>
</ select>
< button @click = " increment(num)" > +</ button>
< button @click = " decrement(num)" > -</ button>
< button @click = " incrementOdd(num)" > 和为奇数时再加</ button>
< button @click = " incrementWait(num)" > 等一等再加</ button>
</ div>
</ template>
< script>
import { mapState, mapGetters, mapActions, mapMutations} from "vuex" ;
export default {
name : 'Count' ,
data ( ) {
return {
num : 1
}
} ,
computed : {
... mapState ( [ "sum" , "company" , "position" , "personList" ] ) ,
... mapGetters ( [ "bigSum" ] )
} ,
methods : {
... mapActions ( {
incrementOdd : "jiaOdd" ,
incrementWait : "jiaWait"
} ) ,
... mapMutations ( {
increment : "JIA" ,
decrement : "JIAN"
} )
}
}
</ script>
< style scoped >
button {
margin-left : 5px;
}
</ style>
6. Vuex模块化实例一 – 模块不带命名空间
6-1 store/person/index.js – person模块的store
const state = {
personList : [
{ id : "001" , name : "张三" }
]
}
const getters = { }
const actions = { }
const mutations = {
ADD_PERSON ( state, personObj ) {
state. personList. unshift ( personObj) ;
}
}
export default {
state,
getters,
actions,
mutations
}
6-2 store/count/index.js
const state = {
sum : 0
}
const getters = {
bigSum ( state ) {
return state. sum* 10 ;
}
}
const actions = {
jiaOdd ( context, value ) {
if ( context. state. sum % 2 ) {
context. commit ( "JIA" , value) ;
}
} ,
jiaWait ( context, value ) {
setTimeout ( ( ) => {
context. commit ( "JIA" , value) ;
} , 500 )
}
}
const mutations = {
JIA ( state, value ) {
state. sum += value;
} ,
JIAN ( state, value ) {
state. sum -= value;
}
}
export default {
state,
getters,
actions,
mutations
}
6-3 store/index.js
import Vue from "vue" ;
import Vuex from "vuex" ;
import countAbout from "./count" ;
import personAbout from "./person" ;
Vue. use ( Vuex) ;
export default new Vuex. Store ( {
modules : {
countAbout,
personAbout
}
} )
6-4 Person.Vue
< template>
< div>
< h2> 人员列表</ h2>
< h3 style = " color : red" > Count组件的当前和为{{sum}}</ h3>
< input type = " text" placeholder = " 请输入姓名" v-model = " name" />
< button @click = " add" > 添加</ button>
< ul>
< li v-for = " p in personList" :key = " p.id" > {{p.name}}</ li>
</ ul>
</ div>
</ template>
< script>
import { nanoid} from "nanoid" ;
export default {
name : "Person" ,
data ( ) {
return {
name : ""
}
} ,
computed : {
personList ( ) {
return this . $store. state. personAbout. personList;
} ,
sum ( ) {
return this . $store. state. countAbout. sum;
}
} ,
methods : {
add ( ) {
const personObj = {
id : nanoid ( ) ,
name : this . name
}
this . $store. commit ( "ADD_PERSON" , personObj) ;
this . name = "" ;
}
} ,
}
</ script>
< style scoped >
button {
margin-left : 5px;
}
</ style>
6-5 Count.vue
6-5-1 mapState,mapGetters,mapActions,mapMutations的对象写法
< template>
< div class = " count" >
< h2> 当前求和为{{sum}}</ h2>
< h2> 当前求和放大10倍为{{bigSum}}</ h2>
< h3 style = " color : red" > Person组件的总人数为{{personList.length}}</ h3>
< select v-model = " num" >
< option :value = " 1" > 1</ option>
< option :value = " 2" > 2</ option>
< option :value = " 3" > 3</ option>
</ select>
< button @click = " increment(num)" > +</ button>
< button @click = " decrement(num)" > -</ button>
< button @click = " incrementOdd(num)" > 和为奇数时再加</ button>
< button @click = " incrementWait(num)" > 等一等再加</ button>
</ div>
</ template>
< script>
import { mapState, mapGetters, mapActions, mapMutations} from "vuex" ;
export default {
name : 'Count' ,
data ( ) {
return {
num : 1
}
} ,
computed : {
... mapState ( {
sum : state => state. countAbout. sum,
personList : state => state. personAbout. personList
} ) ,
... mapGetters ( [ "bigSum" ] )
} ,
methods : {
... mapActions ( {
incrementOdd : "jiaOdd" ,
incrementWait : "jiaWait"
} ) ,
... mapMutations ( {
increment : "JIA" ,
decrement : "JIAN"
} )
}
}
</ script>
< style scoped >
button {
margin-left : 5px;
}
</ style>
6-5-2 mapState,mapGetters,mapActions,mapMutations的数组写法
< template>
< div class = " count" >
< h2> 当前求和为{{countAbout.sum}}</ h2>
< h2> 当前求和放大10倍为{{bigSum}}</ h2>
< h3 style = " color : red" > Person组件的总人数为{{personAbout.personList.length}}</ h3>
< select v-model = " num" >
< option :value = " 1" > 1</ option>
< option :value = " 2" > 2</ option>
< option :value = " 3" > 3</ option>
</ select>
< button @click = " JIA(num)" > +</ button>
< button @click = " JIAN(num)" > -</ button>
< button @click = " jiaWait(num)" > 和为奇数时再加</ button>
< button @click = " jiaWait(num)" > 等一等再加</ button>
</ div>
</ template>
< script>
import { mapState, mapGetters, mapActions, mapMutations} from "vuex" ;
export default {
name : 'Count' ,
data ( ) {
return {
num : 1
}
} ,
computed : {
... mapState ( [ "countAbout" , "personAbout" ] ) ,
... mapGetters ( [ "bigSum" ] )
} ,
methods : {
... mapActions ( [ "jiaOdd" , "jiaWait" ] ) ,
... mapMutations ( [ "JIA" , "JIAN" ] ) ,
}
}
</ script>
< style scoped >
button {
margin-left : 5px;
}
</ style>
7. Vuex模块化实例二 – 模块带命名空间[推荐使用]
7-1 store/person/index.js
const state = {
personList : [
{ id : "001" , name : "张三" }
]
}
const getters = { }
const actions = { }
const mutations = {
ADD_PERSON ( state, personObj ) {
state. personList. unshift ( personObj) ;
}
}
export default {
namespaced : true ,
state,
getters,
actions,
mutations
}
7-2 store/count/index.js
const state = {
sum : 0
}
const getters = {
bigSum ( state ) {
return state. sum* 10 ;
}
}
const actions = {
jiaOdd ( context, value ) {
if ( context. state. sum % 2 ) {
context. commit ( "JIA" , value) ;
}
} ,
jiaWait ( context, value ) {
setTimeout ( ( ) => {
context. commit ( "JIA" , value) ;
} , 500 )
}
}
const mutations = {
JIA ( state, value ) {
state. sum += value;
} ,
JIAN ( state, value ) {
state. sum -= value;
}
}
export default {
namespaced : true ,
state,
getters,
actions,
mutations
}
7-3 store/index.js
import Vue from "vue" ;
import Vuex from "vuex" ;
import countAbout from "./count" ;
import personAbout from "./person" ;
Vue. use ( Vuex) ;
export default new Vuex. Store ( {
modules : {
countAbout,
personAbout
}
} )
7-4 Person.vue
< template>
< div>
< h2> 人员列表</ h2>
< h3 style = " color : red" > Count组件的当前和为{{sum}}</ h3>
< input type = " text" placeholder = " 请输入姓名" v-model = " name" />
< button @click = " add" > 添加</ button>
< ul>
< li v-for = " p in personList" :key = " p.id" > {{p.name}}</ li>
</ ul>
</ div>
</ template>
< script>
import { nanoid} from "nanoid" ;
export default {
name : "Person" ,
data ( ) {
return {
name : ""
}
} ,
computed : {
personList ( ) {
return this . $store. state. personAbout. personList;
} ,
sum ( ) {
return this . $store. state. countAbout. sum;
}
} ,
methods : {
add ( ) {
const personObj = {
id : nanoid ( ) ,
name : this . name
}
this . $store. commit ( "personAbout/ADD_PERSON" , personObj)
this . name = "" ;
}
}
}
</ script>
< style scoped >
button {
margin-left : 5px;
}
</ style>
7-5 Count.vue
< template>
< div class = " count" >
< h2> 当前求和为{{sum}}</ h2>
< h2> 当前求和放大10倍为{{bigSum}}</ h2>
< h3 style = " color : red" > Person组件的总人数为{{personList.length}}</ h3>
< select v-model = " num" >
< option :value = " 1" > 1</ option>
< option :value = " 2" > 2</ option>
< option :value = " 3" > 3</ option>
</ select>
< button @click = " increment(num)" > +</ button>
< button @click = " decrement(num)" > -</ button>
< button @click = " incrementOdd(num)" > 和为奇数时再加</ button>
< button @click = " incrementWait(num)" > 等一等再加</ button>
</ div>
</ template>
< script>
import { mapState, mapGetters, mapActions, mapMutations} from "vuex" ;
export default {
name : 'Count' ,
data ( ) {
return {
num : 1
}
} ,
computed : {
... mapState ( "countAbout" , [ "sum" ] ) ,
... mapState ( "personAbout" , [ "personList" ] ) ,
... mapGetters ( "countAbout" , [ "bigSum" ] )
} ,
methods : {
... mapActions ( "countAbout" , {
incrementOdd : "jiaOdd" ,
incrementWait : "jiaWait"
} ) ,
... mapMutations ( "countAbout" , {
increment : "JIA" ,
decrement : "JIAN"
} ) ,
}
}
</ script>
< style scoped >
button {
margin-left : 5px;
}
</ style>