異步管理數(shù)據(jù)就是有發(fā)請求蜒谤,我們這里異步請求用axios,這個(gè)也是第三方的庫至扰,所以我們要在當(dāng)前項(xiàng)目yarn add axios或者npm i axios鳍徽,然后再store.js文件里面導(dǎo)入
import axios from 'axios'
在來到組件文件里面的template組件這里添加一個(gè)事件觸發(fā)源
<button @click="clickHandler">獲取電影</button>
然后再export default這里派發(fā)一個(gè)action
clickHandler: function () {
// 獲取異步數(shù)據(jù) 希望通過倉庫進(jìn)行 異步數(shù)據(jù)的管理
this.$store.dispatch('getMovie'); // 派發(fā) action 。 同步:commit敢课,異步 action
}
然后異步請求不能在store.js的 mutations里面修改數(shù)據(jù)咯阶祭,要在const store = new Vuex.Store先加一個(gè)action
actions: {
getMovie: function (store, payload) {
var url = 'https://movie.52kfw.cn/index.php/Api/Movie/alst?page=1&size=20';
axios.get(url).then(response => {
console.log(response);
if( response.status === 200 && response.data.error_code === 0 ){
// 把返回的數(shù)據(jù)交給倉庫里面的 state 里面的 movieData
// response.data.result;
// 當(dāng)前 store 對象
store.commit('saveMovieData', response.data.result);
}
}).catch( error => {
console.log(error);
})
console.log('getMovie');
}
},
如上里面也有 store.commit('saveMovieData', response.data.result);response.data.result就是要傳過去的payload值
因?yàn)榘逊祷氐臄?shù)據(jù)交給倉庫里面的 state 里面的 movieData,所以事先要在state里面定義一下
state: {
count: 10, // 計(jì)數(shù)器的初始值
movieData: [], // 電影數(shù)據(jù)翎猛,稍后使用 api 獲取胖翰,異步請求
},
還有mutations里面也要定義一個(gè)saveMovieData
mutations: {
saveMovieData: function (state, payload) {
state.movieData = payload;
},
最后將數(shù)據(jù)渲染在頁面就好了。
<ul v-else v-for="ele in movieData">
<li>序號:{{ ele.id }}</li>
<li>名稱:{{ ele.title }}</li>
<li>收藏?cái)?shù):{{ ele.star }}</li>
</ul>
注意切厘,在mutations里面的state指的是
是這個(gè)state
然而這里的store
指的是所在當(dāng)前的整個(gè)實(shí)例對象store
同樣的這里也要考慮一下代碼優(yōu)化萨咳,
- mutations和actions都可以做映射,
在組件文件.vue里面
import {mapState, mapMutations, mapActions, } from 'vuex';
在.vue組件文件里面的export default里面的method只用寫
methods: {
...mapActions({ clickHandler: 'getMovie' }),
// clickHandler: function () {
// // 獲取異步數(shù)據(jù) 希望通過倉庫進(jìn)行 異步數(shù)據(jù)的管理
// this.$store.dispatch('getMovie'); // 派發(fā) action 。 同步:commit疫稿,異步 action
//
// }
}
如果要做篩選的操作呢培他,比如挑取start的值為淺12萬的數(shù)據(jù),這時(shí)候要在倉庫實(shí)例添加一個(gè)getters
getters: {
// 希望可以篩選出收藏?cái)?shù)據(jù)大于 12w 的電影 類似 vuejs 里面的計(jì)算屬性
// 定義是一個(gè)方法,按照屬性方式使用遗座,和計(jì)算屬性一樣
returnStarBig12w: function (state) {
console.log(state);
// return state.movieData; // 過濾 filter
return state.movieData.filter( item => {
return item.star >= 120000;
} );
}
}
在組件.vue那里直接渲染
<ul v-for="ele in $store.getters.returnStarBig12w">
<li>序號:{{ ele.id }}</li>
<li>名稱:{{ ele.title }}</li>
<li>收藏?cái)?shù):{{ ele.star }}</li>
</ul>
當(dāng)然給getter也有映射,在.vue文件里面改
import {mapState, mapMutations, mapActions, mapGetters} from 'vuex';
//在export default里面
methods: {
...mapMutations([ INCREMENT, DECREMENT]),
...mapActions({ clickHandler: 'getMovie' }),
...mapGetters(['returnStarBig12w'])
}
異步數(shù)據(jù)有可能網(wǎng)絡(luò)會卡頓舀凛,為了避免用戶在發(fā)網(wǎng)絡(luò)請求時(shí)候一直點(diǎn)擊,我們應(yīng)該用戶體驗(yàn)友好途蒋,加loading猛遍。
那要在用戶發(fā)送請求的action里面
const store = new Vuex.Store({
actions: {
getMovie: function (store, payload) {
var url = 'https://movie.52kfw.cn/index.php/Api/Movie/alst?page=1&size=20';
// 網(wǎng)絡(luò)請求,完全可以做個(gè)內(nèi)存緩存号坡,先去檢測倉庫里面是否存在數(shù)據(jù)懊烤,如果存在,則不發(fā)送網(wǎng)絡(luò)請求宽堆;不存在發(fā)送 后臺腌紧,肯定上緩存 memcache redis 內(nèi)存緩存 io 》》》 磁盤IO mysql
if( store.state.movieData.length > 0 ){
// 代表用戶之前肯定點(diǎn)擊獲取電影,發(fā)送過網(wǎng)絡(luò)請求
console.log('數(shù)據(jù)來自緩存信息畜隶!');
return;
}
//則這里的請求只能發(fā)送一次
而在請求數(shù)據(jù)的這個(gè)過程中我們可以顯示loading效果壁肋,數(shù)據(jù)成功回來后loading效果:1. loading.gif 2. 插件 3. css3 loading 效果
這里隨便找一個(gè)css3把
把loading翻入到組件中
<div class="loading" v-if="flag">
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
</div>
<ul v-else v-for="ele in movieData">
<li>序號:{{ ele.id }}</li>
<li>名稱:{{ ele.title }}</li>
<li>收藏?cái)?shù):{{ ele.star }}</li>
</ul>
//樣式放在之后的style標(biāo)簽內(nèi)
注意上面的代碼我用了v-if和v-else号胚,只能顯示一個(gè),是否顯示取決于狀態(tài)true還是false
接下來是修改狀態(tài)浸遗,
注意:所有修改狀態(tài)都是commit猫胁,只不過是異步是在action里面commit,同步是在.vue里面直接commit乙帮。
定義狀態(tài)并初始flag
const store = new Vuex.Store({
// 開啟 vuex 嚴(yán)格模式
strict: true, // 默認(rèn)是false
// 倉庫里面的數(shù)據(jù)(之前說的模型數(shù)據(jù))杜漠,一般我們叫做 state 狀態(tài)
state: {
count: 10, // 計(jì)數(shù)器的初始值
movieData: [], // 電影數(shù)據(jù)极景,稍后使用 api 獲取察净,異步請求
flag: false,
},
在發(fā)送請求之前的action里面修改狀態(tài)
actions: {
getMovie: function (store, payload) {
var url = 'https://movie.52kfw.cn/index.php/Api/Movie/alst?page=1&size=20';
// 網(wǎng)絡(luò)請求,完全可以做個(gè)內(nèi)存緩存盼樟,先去檢測倉庫里面是否存在數(shù)據(jù)氢卡,如果存在,則不發(fā)送網(wǎng)絡(luò)請求晨缴;不存在發(fā)送 后臺译秦,肯定上緩存 memcache redis 內(nèi)存緩存 io 》》》 磁盤IO mysql
if( store.state.movieData.length > 0 ){
// 代表用戶之前肯定點(diǎn)擊獲取電影,發(fā)送過網(wǎng)絡(luò)請求
console.log('數(shù)據(jù)來自緩存信息击碗!');
return;
}
//由于網(wǎng)絡(luò)請求所耗費(fèi)的時(shí)間是不確定筑悴,意味用戶等待的時(shí)長也是不確定,為了防止亂點(diǎn)擊稍途,煩躁阁吝。一般在發(fā)送網(wǎng)絡(luò)請求后,會在頁面上出一個(gè) loading的效果械拍。數(shù)據(jù)成功回來后,loading消失突勇。
// 1. loading.gif 2. 插件 3. css3 loading 效果
store.commit('modifyFlag', true);
axios.get(url).then(response => {
然后在處理status的mutations里面新增
modifyFlag: function (state, payload) {
state.flag = payload;
}
然后發(fā)完網(wǎng)絡(luò)請求以后,在保存數(shù)據(jù)那里坷虑,就是表示發(fā)送成功甲馋,改變loading的狀態(tài)
saveMovieData: function (state, payload) {
state.movieData = payload;
state.flag = false;
},
將不顯示那個(gè)loading
-
最后的常量的優(yōu)化
定義一個(gè)常量文件
比如將這些設(shè)為常量
export const INCREMENT = 'increa'
export const DECREMENT = 'decrea'
然后在vuex的store文件里面導(dǎo)入常量
將需要用到的地方替換即可
//inCrement
[INCREMENT]: function (state, payload) {
console.log(payload);
console.log(state);
state.count += 1;
// state.count += payload.number;
},
[DECREMENT]: function (state, payload) {
state.count -= 1;
},
在.vue組件文件里面同時(shí)也要
import {INCREMENT, DECREMENT} from './store/constant'
//需要用到的地方就可以
...mapMutations([ INCREMENT, DECREMENT]),