本文原創為CSDN博主:安之ccy,博客首頁地址:https://blog.csdn.net/qq_43523725
轉載請注明出處,謝謝支持和鼓勵
今日份萌寵圖,祝所有勤奮努力善良可愛的小天使們天天開心~💕

寫在前面:
摘自官網:
- Vuex 是一個專為 Vue.js 應用程式開發的狀態管理模式,它采用集中式存盤管理應用的所有組件的狀態,并以相應的規則保證狀態以一種可預測的方式發生變化
- 如果您的應用夠簡單,您最好不要使用 Vuex
- 如果您需要構建一個中大型單頁應用,您很可能會考慮如何更好地在組件外部管理狀態,Vuex 將會成為自然而然的選擇
所以,并不是所有的情況都適合使用vuex哦,按需使用最重要😜~ 正文開始~
安裝vuex
創建store檔案,抽離資料
不使用vuex時,資料是分開維護的
使用vuex時,資料存盤在store中
getters獲取資料
mutations修改資料
actions設定異步
推薦chrome擴展程式:Vue.js devtools
安裝vuex
這次想試試cnpm,指定國內鏡像:
npm config set registry https://registry.npm.taobao.org
驗證是否成功:
npm config get registry
如果輸出了剛剛設定的那個鏡像的鏈接,代表設定成功
安裝cnpm:
npm install -g cnpm --registry=https://registry.npm.taobao.org
驗證cnpm是否安裝成功:
cnpm -v
如果輸出了各庫的版本而非報錯資訊,代表cnpm安裝成功
安裝vue cli腳手架:
cnpm -g @vue/cli-init
或者
cnpm i -g @vue/cli-init
選擇模板webpack-simple創建專案:
vue init webpack-simple vuex-test(專案名稱)
進入專案:
cd vuex-test(專案名稱)
安裝專案依賴:
cnpm install
運行專案:
cnpm run dev
然后會自動在默認瀏覽器里打開localhost:8080,里面是系統默認配置的vue版helloworld,大概是這樣的:

顯示這個頁面,說明已經創建專案成功啦~
暫停當前的vue服務(關閉終端視窗或ctrl+c),安裝vuex:
npm install vuex --save
在專案檔案夾下的package.json檔案就會有一個vuex的依賴:
"dependencies": {
"vue": "^2.5.11",
"vuex": "^3.6.2"
},
表示vuex安裝成功,重新使用cnpm run dev啟動一下專案
我的小插曲(先記錄一下):
今天安裝的時候忽然出了bug,居然提示我找不到vue-cli檔案,node_modules目錄下的npm檔案沒了,于是乎,我就又安裝了一遍,重點是需要那個npm檔案夾,可以找朋友的npm檔案復制過來
創建store檔案,抽離資料
背景:
有時,我們可能在不同組件運用了同一組資料;比如商品的價格,不論是預覽還是詳情頁,該商品的價格是一樣的,如果這些組件各自維護這組資料,為保證資料的一致,一旦某個子組件需要改動資料,其他子組件都需要做同樣的修改,涉及的組件數量很多時,就變得麻煩易錯,且冗余度太高,這時,我們可以通過vuex來管理這組資料

不使用vuex時,資料是分開維護的
沒有用vuex時,組件各自維護自己的資料,就像這樣:
主頁面App.vue中創建資料:
data () {
return {
products:[
{name:"陜西大蘋果",price:120},
{name:"菠蘿",price:12},
{name:"大西瓜",price:60},
{name:"百香果",price:20}
]
}
}
用v-bind動態傳遞給兩個子頁面product-list-one和product-list-two:
<template>
<div id="app">
<product-list-one v-bind:products="products"></product-list-one>
<product-list-two v-bind:products="products"></product-list-two>
</div>
</template>
子頁面用props接收后展示:
<ul>
<li v-for="product in products" v-bind:key="product.id">
<span class="name">{{product.name}}</span>
<span class="price">¥{{product.price}}</span>
</li>
</ul>
效果:

是的,我們每個子組件都拿到了父組件傳來的資料,如果我們想要修改資料,需要在每個組件中添加一個修改函式saleProducts,這個案例有兩個需要修改的組件,就需要添加兩次這個函式:
saleProducts(){
var saleProducts = this.products.map((product)=>{
return {
name: product.name+"-onsale",
price:product.price/2
}
})
return saleProducts
}
效果:這個函式,只為了讓商品價格都降一半

那可能就有小伙伴在想了,直接在父組件那邊修改了資料,然后傳給子組件不就好了嘛?欸~我也這么覺得,vuex將這個想法完善成一套機制,用store存盤和管理資料,當組件需要這些資料時,去store里取就好了;需要統一修改資料時,也通過提交事件來操作store里的資料,子組件只管取,別的交給vuex
You just move on and I’ll do the rest.
你只管向前,剩下的交給我,
案例修改思路如下:
- 轉移(剪切)主組件App.vue里的資料,洗掉主組件v-bind動態傳遞資料和子組件props接收資料的代碼
- 新建一個目錄存放store代碼,包括資料存盤、資料獲取等
- 在main.js檔案中引入store檔案,并注冊到vue實體物件中,此處命名為store
- 在子頁面使用store,如果僅需要獲取源資料,可以使用
this.$store.state.資料
如果在vue物件中注冊時命名為x,就寫成this.$x.state.資料- 如果需要對源資料做一些過濾、計數操作,可以在getters中進行,如上面說的商品降價,因為此處只是臨時降價,不修改源資料,而是拷貝一份出來修改
使用vuex時,資料存盤在store中
在src目錄下新建檔案夾,命名store;里面新鍵檔案,命名store.js,將資料存到這里
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export const store = new Vuex.Store({
state:{
products:[
{name:"陜西大蘋果",price:120},
{name:"菠蘿",price:12},
{name:"大西瓜",price:60},
{name:"百香果",price:20}
]
}
}
})
在main.js中引入并注冊到vue實體中:
import Vue from 'vue'
import App from './App.vue'
import {store} from './store/store.js'
new Vue({
//將store注冊到vue實體中,命名為store
store:store,
el: '#app',
render: h => h(App)
})
在子組件中使用:
computed:{
products(){
return this.$store.state.products;
}
}
<ul>
<li v-for="product in products" v-bind:key="product.id">
<span class="name">{{product.name}}</span>
<span class="price">¥{{product.price}}</span>
</li>
</ul>
這樣就可以正常使用資料products了:

Take it one step at a time.
一步一步慢慢來,
getters獲取資料
源資料可以正常使用后,我們就可以在store里新增getters欄位,在這里定義降價函式:
getters:{
// products里的價格都減一半,name加上星星做標記,代表這是降價一半的價格
saleProducts:(state)=>{
// map會逐一操作每個元素并回傳一個新的物件,不改變源資料
var saleProducts = state.products.map((product)=>{
return {
name: "**"+product.name+"**",
price: product.price/2
}
})
return saleProducts
}
子組件使用降價函式:
computed:{
saleProducts(){
return this.$store.getters.saleProducts
}
}
<ul>
<li v-for="product in saleProducts" v-bind:key="product.id">
<span class="name">{{product.name}}</span>
<span class="price">¥{{product.price}}</span>
</li>
</ul>
效果:

fine,又是this又是$符號的,看起來又高級又簡潔(吹牛🤥)
如果我們要真正修改資料,要怎么做呢?
mutations修改資料
摘自官網:
更改 Vuex 的 store 中的狀態的唯一方法是提交mutation,
Vuex 中的 mutation 非常類似于事件:每個 mutation 都有一個字串的事件型別 (type) 和一個回呼函式 (handler),這個回呼函式就是我們實際進行狀態更改的地方,并且它會接受 state 作為第一個引數
我們不能隨意更改資料,需要使用事件來提交請求,這跟vue里子向父傳值需要使用事件傳值應該是相似的理念
具體操作如下:
- 在store物件里新增mutations欄位,定義“價格修改函式”
- 在子組件中設定監聽
- 當某事件發生時,觸發處理函式,commit提交修改資料(狀態)請求
在store的mutations欄位中定義處理函式reducePrice:
mutations:{
reducePrice:(state)=>{
state.products.forEach((product)=>{
product.price -= 1;
})
}
}
子組件中commit提交事件請求:
methods:{
reducePrice(number){
this.$store.commit('reducePrice')
}
}
在子組件加一個按鈕,系結點擊事件,每次點擊按鈕時將商品價格減少1
<button @click="reducePrice()">降價</button>
由于資料展示時,會經過上面設定的saleProducts函式——數值降價一半后再顯示,我們點擊一次按鈕,展示時只減了0.5,源資料其實是減了1的,此處都展示出來,做一個對比:
<template>
<div id="product-list-one">
<h2>ProductListOne</h2>
<h3>降價一半后的資料:</h3>
<ul>
<li v-for="product in saleProducts" v-bind:key="product.id">
<span class="name">{{product.name}}</span>
<span class="price">¥{{product.price}}</span>
</li>
</ul>
<h3>源資料在此:</h3>
<ul>
<li v-for="product in products" v-bind:key="product.id">
<span class="name">{{product.name}}</span>
<span class="price">¥{{product.price}}</span>
</li>
</ul>
<button @click="reducePrice()">降價</button>
</div>
</template>
效果:

我們還可以向reduceProducts函式傳入引數,比如每次點擊按鈕降價4元,這個引數,在store有一個專有名:playload
使用處傳參:4:
<button @click="reducePrice(4)">降價</button>
mutations處接收并處理:
mutations:{
reducePrice:(state,playload)=>{
state.products.forEach((product)=>{
product.price -= playload;
})
}
}
效果:

mutations中只能定義同步函式,不允許異步操作,異步操作由actions設定
actions設定異步
摘自官網:
Action 類似于 mutation,不同在于:
- Action 提交的是 mutation,而不是直接變更狀態,
- Action 可以包含任意異步操作
使用起來還是類似的操作步驟:
- 在store物件中新增actions欄位,寫異步代碼,
- 子組件處dispatch
- 同樣可以傳參,用playload接收
store中新增actions欄位,定義異步操作reducePrice:
actions:{
reducePrice:(context,playload)=>{
setTimeout(function(){
context.commit("reducePrice",playload)
},3000)
}
}
子組件處使用:
methods:{
reducePrice(number){
this.$store.dispatch("reducePrice",number)
}
}
效果:點擊按鈕3秒后,商品價格減4

推薦chrome擴展程式:Vue.js devtools
-
這個擴展程式可以幫助我們查看除錯vuex的操作,如mutations和actions
-
可以在chrome應用商店里面搜索并安裝
-
安裝好之后,可以看到控制臺多了一個vue的標簽,剛開始界面是這樣子的,展示了我們的html標簽還有我們的computed:

-
如果我們在程式中使用了mutations,我們可以借助這個擴展程式查看程式運行到這個部分時的操作,如我點擊了“降價”按鈕(此時沒有設定降價的異步操作),可以直接看到資料發生改變

-
對于actions,當按下按鈕3秒后,資料發生改變的同時,可以看到除錯部分出現了改變

可以說是很nice了,有效追蹤資料是何時發生變化的
好啦,今天的分享就到這里啦,歡迎各位大佬們點贊、評論、收藏、分享,感謝支持~~
你不會不點贊就走了叭~

轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/286609.html
標籤:其他
上一篇:個人博客系統---基本功能的實作
