vue--vuex詳解
Vuex
什么是Vuex?
官方說法:Vuex 是一個(gè)專為 Vue.js應(yīng)用程序開發(fā)的狀態(tài)管理模式。它采用集中式存儲(chǔ)管理應(yīng)用的所有組件的狀態(tài),并以相應(yīng)的規(guī)則保證狀態(tài)以一種可預(yù)測(cè)的方式發(fā)生變化。
個(gè)人理解:Vuex是用來管理組件之間通信的一個(gè)插件
為什么要用Vuex?
我們知道組件之間是獨(dú)立的,組件之間想要實(shí)現(xiàn)通信,我目前知道的就只有props選項(xiàng),但這也僅限于父組件和子組件之間的通信。如果兄弟組件之間想要實(shí)現(xiàn)通信呢?嗯..,方法應(yīng)該有。拋開怎么實(shí)現(xiàn)的問題,試想一下,當(dāng)做中大型項(xiàng)目時(shí),面對(duì)一大堆組件之間的通信,還有一大堆的邏輯代碼,會(huì)不會(huì)很抓狂??那為何不把組件之間共享的數(shù)據(jù)給“拎”出來,在一定的規(guī)則下管理這些數(shù)據(jù)呢? 這就是Vuex的基本思想了。
Vuex有什么特性?
怎么使用Vuex?
引入Vuex.js文件
創(chuàng)建實(shí)例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<script src="./js/vuex.js"></script>
<script src="./js/vue2.0.js"></script>
<body>
<div id="app">
</div>
</body>
<script>
Vue.use(Vuex);//在創(chuàng)建Vue實(shí)例之前
var myStore = new Vuex.Store({
state:{
//存放組件之間共享的數(shù)據(jù)
name:"jjk"
},
mutations:{
//顯式的更改state里的數(shù)據(jù)
},
getters:{
//獲取數(shù)據(jù)的方法
},
actions:{
//
}
});
new Vue({
el:"#app",
data:{
name:"dk"
},
store:myStore,
mounted:function(){
console.log(this)//控制臺(tái)
}
})
</script>
</html>
先解釋上面代碼的意思:
new Vuex.Store({}) 表示創(chuàng)建一個(gè)Vuex實(shí)例,通常情況下,他需要注入到Vue實(shí)例里. Store是Vuex的一個(gè)核心方法,字面上理解為“倉庫”的意思。Vuex Store是響應(yīng)式的,當(dāng)Vue組件從store中讀取狀態(tài)(state選項(xiàng))時(shí),若store中的狀態(tài)發(fā)生更新時(shí),他會(huì)及時(shí)的響應(yīng)給其他的組件(類似雙向數(shù)據(jù)綁定) 而且不能直接改變store的狀態(tài),改變狀態(tài)的唯一方法就是,顯式地提交更改(mutations選項(xiàng))
他有4個(gè)核心選項(xiàng):state mutations getters actions (下文會(huì)仔細(xì)分析)
這是上面代碼:

那如何獲取到state的數(shù)據(jù)呢?
一般會(huì)在組件的計(jì)算屬性(computed)獲取state的數(shù)據(jù)(因?yàn)椋?jì)算屬性會(huì)監(jiān)控?cái)?shù)據(jù)變化,一旦發(fā)生改變就會(huì)響應(yīng))
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<script src="./js/vuex.js"></script>
<script src="./js/vue2.0.js"></script>
<body>
<div id="app">
<hello></hello>
</div>
</body>
<script>
Vue.use(Vuex);
var myStore = new Vuex.Store({
state:{
//存放組件之間共享的數(shù)據(jù)
name:"jjk"
},
mutations:{
//顯式的更改state里的數(shù)據(jù)
},
getters:{
//過濾state數(shù)據(jù)
},
actions:{
//
}
});
Vue.component('hello',{
template:"<p>{{name}}</p>",
computed: {
name:function(){
return this.$store.state.name
}
},
mounted:function(){
console.log(this)
}
})
new Vue({
el:"#app",
data:{
name:"dk"
},
store:myStore,
mounted:function(){
console.log(this)
}
})
</script>
</html>
在·chrome中顯示:

state:用來存放組件之間共享的數(shù)據(jù)。他跟組件的data選項(xiàng)類似,只不過data選項(xiàng)是用來存放組件的私有數(shù)據(jù)。
getters:有時(shí)候,我們需要對(duì)state的數(shù)據(jù)進(jìn)行篩選,過濾。這些操作都是在組件的計(jì)算屬性進(jìn)行的。如果多個(gè)組件需要用到篩選后的數(shù)據(jù),那我們就必須到處重復(fù)寫該計(jì)算屬性函數(shù);或者將其提取到一個(gè)公共的工具函數(shù)中,并將公共函數(shù)多處導(dǎo)入 - 兩者都不太理想。如果把數(shù)據(jù)篩選完在傳到計(jì)算屬性里就不用那么麻煩了,getters就是干這個(gè)的,你可以把getters看成是store的計(jì)算屬性。getters下的函數(shù)接收接收state作為第一個(gè)參數(shù)。那么,組件是如何獲取經(jīng)過getters過濾的數(shù)據(jù)呢? 過濾的數(shù)據(jù)會(huì)存放到$store.getters對(duì)象中。具體看一個(gè)例子:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<script src="./js/vuex.js"></script>
<script src="./js/vue2.0.js"></script>
<body>
<div id="app">
<hello></hello>
</div>
</body>
<script>
Vue.use(Vuex);
var myStore = new Vuex.Store({
state:{
//存放組件之間共享的數(shù)據(jù)
name:"jjk",
age:18
},
mutations:{
//顯式的更改state里的數(shù)據(jù)
},
getters:{
getAge:function(state){
return state.age;
}
},
actions:{
//
}
});
Vue.component('hello',{
template:"<p>姓名:{{name}} 年齡:{{age}}</p>",
computed: {
name:function(){
return this.$store.state.name
},
age:function(){
return this.$store.getters.getAge
}
},
mounted:function(){
console.log(this)
}
})
new Vue({
el:"#app",
data:{
name:"dk"
},
store:myStore,
mounted:function(){
console.log(this)
}
})
</script>
</html>
在chrome中顯示:
mutations:前面講到的都是如何獲取state的數(shù)據(jù),那如何把數(shù)據(jù)存儲(chǔ)到state中呢?在 Vuex store 中,實(shí)際改變 狀態(tài)(state) 的唯一方式是通過 提交(commit) 一個(gè) mutation?! utations下的函數(shù)接收state作為參數(shù),接收一個(gè)叫做payload(載荷)的東東作為第二個(gè)參數(shù),這個(gè)東東是用來記錄開發(fā)者使用該函數(shù)的一些信息,比如說提交了什么,提交的東西是用來干什么的,包含多個(gè)字段,所以載荷一般是對(duì)象(其實(shí)這個(gè)東西跟git的commit很類似)還有一點(diǎn)需要注意:mutations方法必須是同步方法! 具體看實(shí)例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<script src="./js/vuex.js"></script>
<script src="./js/vue2.0.js"></script>
<body>
<div id="app">
<hello></hello>
</div>
</body>
<script>
Vue.use(Vuex);
var myStore = new Vuex.Store({
state:{
//存放組件之間共享的數(shù)據(jù)
name:"jjk",
age:18,
num:1
},
mutations:{
//顯式的更改state里的數(shù)據(jù)
change:function(state,a){
// state.num++;
console.log(state.num += a);
}
},
getters:{
getAge:function(state){
return state.age;
}
},
actions:{
//
}
});
Vue.component('hello',{
template:"<p @click='changeNum'>姓名:{{name}} 年齡:{{age}} 次數(shù):{{num}}</p>",
computed: {
name:function(){
return this.$store.state.name
},
age:function(){
return this.$store.getters.getAge
},
num:function(){
return this.$store.state.num
}
},
mounted:function(){
console.log(this)
},
methods: {
changeNum: function(){
//在組件里提交
// this.num++;
this.$store.commit('change',10)
}
},
data:function(){
return {
// num:5
}
}
})
new Vue({
el:"#app",
data:{
name:"dk"
},
store:myStore,
mounted:function(){
console.log(this)
}
})
</script>
</html>
當(dāng)點(diǎn)擊p標(biāo)簽前,chrome中顯示:

點(diǎn)擊p標(biāo)簽后:

可以看出:更改state的數(shù)據(jù)并顯示在組件中,有幾個(gè)步驟:1. 在mutations選項(xiàng)里,注冊(cè)函數(shù) 函數(shù)里面裝邏輯代碼。2.在組件里,this.$store.commit('change',payload) 注意:提交的函數(shù)名要一一對(duì)應(yīng) 3.觸發(fā)函數(shù),state就會(huì)相應(yīng)更改 4.在組件的計(jì)算屬性里this.$store.state 獲取你想要得到的數(shù)據(jù)
actions:既然mutations只能處理同步函數(shù),我大js全靠‘異步回調(diào)'吃飯,怎么能沒有異步,于是actions出現(xiàn)了...
actions和mutations的區(qū)別
1.Actions提交的是 mutations,而不是直接變更狀態(tài)。也就是說,actions會(huì)通過mutations,讓mutations幫他提交數(shù)據(jù)的變更。
2.Action 可以包含任意異步操作。ajax、setTimeout、setInterval不在話下
再來看一下實(shí)例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<script src="./js/vuex.js"></script>
<script src="./js/vue2.0.js"></script>
<body>
<div id="app">
<hello></hello>
</div>
</body>
<script>
Vue.use(Vuex);
var myStore = new Vuex.Store({
state:{
//存放組件之間共享的數(shù)據(jù)
name:"jjk",
age:18,
num:1
},
mutations:{
//顯式的更改state里的數(shù)據(jù)
change:function(state,a){
// state.num++;
console.log(state.num += a);
},
changeAsync:function(state,a){
console.log(state.num +=a);
}
},
getters:{
getAge:function(state){
return state.age;
}
},
actions:{
//設(shè)置延時(shí)
add:function(context,value){
setTimeout(function(){
//提交事件
context.commit('changeAsync',value);
},1000)
}
}
});
Vue.component('hello',{
template:`
<div>
<p @click='changeNum'>姓名:{{name}} 年齡:{{age}} 次數(shù):{{num}}</p>
<button @click='changeNumAnsyc'>change</button>
</div>`,
computed: {
name:function(){
return this.$store.state.name
},
age:function(){
return this.$store.getters.getAge
},
num:function(){
return this.$store.state.num
}
},
mounted:function(){
console.log(this)
},
methods: {
changeNum: function(){
//在組件里提交
// this.num++;
this.$store.commit('change',10)
},
//在組件里派發(fā)事件 當(dāng)點(diǎn)擊按鈕時(shí),changeNumAnsyc觸發(fā)-->actions里的add函數(shù)被觸發(fā)-->mutations里的changeAsync函數(shù)觸發(fā)
changeNumAnsyc:function(){
this.$store.dispatch('add', 5);
}
},
data:function(){
return {
// num:5
}
}
})
new Vue({
el:"#app",
data:{
name:"dk"
},
store:myStore,
mounted:function(){
console.log(this)
}
})
</script>
</html>
點(diǎn)擊按鈕一秒后,chrome中顯示:

先整明白 context dispatch是什么東西:
context:context是與 store 實(shí)例具有相同方法和屬性的對(duì)象??梢酝ㄟ^context.state和context.getters來獲取 state 和 getters。
dispatch:翻譯為‘派發(fā)、派遣'的意思,觸發(fā)事件時(shí),dispatch就會(huì)通知actions(跟commit一樣一樣的)參數(shù)跟commit也是一樣的。
action的大體流程:
1.在actions選項(xiàng)里添加函數(shù)(異步)并提交到對(duì)應(yīng)的函數(shù)(在mutation選項(xiàng)里)中context.commit('changeAsync',value);
actions:{
add:function(context,value){
setTimeout(function(){
context.commit('changeAsync',value);
},1000)
}
}
2.在組件里:changeNumAnsyc:function(){this.$store.dispatch('add', 5);} 將dispatch“指向”actions選項(xiàng)里的函數(shù)
3. 在mutations選項(xiàng)里,要有對(duì)應(yīng)的函數(shù)changeAsync:function(state,a){console.log(state.num +=a);}
總結(jié):
各個(gè)類型的 API各司其職,mutation 只管存,你給我(dispatch)我就存;action只管中間處理,處理完我就給你,你怎么存我不管;Getter 我只管取,我不改的?!ction放在了 methods 里面,說明我們應(yīng)該把它當(dāng)成函數(shù)來用(講道理,鉤子函數(shù)也應(yīng)該可以的) mutation是寫在store里面的,這說明,它就是個(gè)半成品,中間量,我們不應(yīng)該在外面去操作它。getter寫在了 computed 里面,這說明雖然 getter我們寫的是函數(shù),但是我們應(yīng)該把它當(dāng)成計(jì)算屬性來用。
對(duì)Vuex的了解就先到這了,細(xì)節(jié)以后在補(bǔ)充。。。。。待續(xù)
以上所述是小編給大家介紹的vue--vuex詳解整合,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
- 關(guān)于Vue.js 2.0的Vuex 2.0 你需要更新的知識(shí)庫
- 巧用Vue.js+Vuex制作專門收藏微信公眾號(hào)的app
- vuex實(shí)現(xiàn)簡(jiǎn)易計(jì)數(shù)器
- 如何使用Vuex+Vue.js構(gòu)建單頁應(yīng)用
- Vuex之理解Mutations的用法實(shí)例
- Vuex之理解Getters的用法實(shí)例
- Vuex之理解Store的用法
- Vue.js實(shí)戰(zhàn)之使用Vuex + axios發(fā)送請(qǐng)求詳解
- vue-router+vuex addRoutes實(shí)現(xiàn)路由動(dòng)態(tài)加載及菜單動(dòng)態(tài)加載
- 深入理解Vuex 模塊化(module)
相關(guān)文章
vue 實(shí)現(xiàn)動(dòng)態(tài)路由的方法
這篇文章主要介紹了vue 實(shí)現(xiàn)動(dòng)態(tài)路由的方法,文中示例代碼非常詳細(xì),幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下2020-07-07
Vue 3自定義指令開發(fā)的相關(guān)總結(jié)
這篇文章主要介紹了Vue 3自定義指令開發(fā)的相關(guān)總結(jié),幫助大家更好的理解和使用vue框架,感興趣的朋友可以了解下2021-01-01
查找Vue中下標(biāo)的操作(some和findindex)
這篇文章主要介紹了查找Vue中下標(biāo)的操作(some和findindex),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-08-08
vue.config.js中configureWebpack與chainWebpack區(qū)別及說明
這篇文章主要介紹了vue.config.js中configureWebpack與chainWebpack區(qū)別及說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09
vue2.0+vuex+localStorage代辦事項(xiàng)應(yīng)用實(shí)現(xiàn)詳解
本篇文章給大家分享了一個(gè)用vue2.0+vuex+localStorage代辦事項(xiàng)應(yīng)用實(shí)現(xiàn)的代碼過程,有興趣的朋友跟著參考學(xué)習(xí)下。2018-05-05

