异步管理数据就是有发请求,我们这里异步请求用axios,这个也是第三方的库,所以我们要在当前项目yarn add axios或者npm i axios,然后再store.js文件里面导入

import axios from 'axios'

在来到组件文件里面的template组件这里添加一个事件触发源

获取电影

然后再export default这里派发一个action

clickHandler: function () {
// 获取异步数据 希望通过仓库进行 异步数据的管理
this.$store.dispatch('getMovie'); // 派发 action 。 同步:commit,异步 action
}

然后异步请求不能在store.js的 mutations里面修改数据咯,要在const store = new Vuex.Store先加一个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 ){
// 把返回的数据交给仓库里面的 state 里面的 movieData
// response.data.result;
// 当前 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值

因为把返回的数据交给仓库里面的 state 里面的 movieData,所以事先要在state里面定义一下

state: {
count: 10, // 计数器的初始值
movieData: [], // 电影数据,稍后使用 api 获取,异步请求
},
还有mutations里面也要定义一个saveMovieData
mutations: {
saveMovieData: function (state, payload) {
state.movieData = payload;
},

最后将数据渲染在页面就好了。

  • 序号:{{ ele.id }}
  • 名称:{{ ele.title }}
  • 收藏数:{{ ele.star }}

注意,在mutations里面的state指的是


image.png

是这个state


image.png

然而这里的store


image.png

指的是所在当前的整个实例对象store


image.png

同样的这里也要考虑一下代码优化,

mutations和actions都可以做映射,

在组件文件.vue里面

import {mapState, mapMutations, mapActions, } from 'vuex';

在.vue组件文件里面的export default里面的method只用写

methods: {
...mapActions({ clickHandler: 'getMovie' }),
// clickHandler: function () {
// // 获取异步数据 希望通过仓库进行 异步数据的管理
// this.$store.dispatch('getMovie'); // 派发 action 。 同步:commit,异步 action
//
// }
}

如果要做筛选的操作呢,比如挑取start的值为浅12万的数据,这时候要在仓库实例添加一个getters


image.png
getters: {
// 希望可以筛选出收藏数据大于 12w 的电影 类似 vuejs 里面的计算属性
// 定义是一个方法,按照属性方式使用,和计算属性一样
returnStarBig12w: function (state) {
console.log(state);
// return state.movieData; // 过滤 filter
return state.movieData.filter( item => {
return item.star >= 120000;
} );
}
}

在组件.vue那里直接渲染

  • 序号:{{ ele.id }}
  • 名称:{{ ele.title }}
  • 收藏数:{{ ele.star }}

当然给getter也有映射,在.vue文件里面改

import {mapState, mapMutations, mapActions, mapGetters} from 'vuex';
//在export default里面
methods: {
...mapMutations([ INCREMENT, DECREMENT]),
...mapActions({ clickHandler: 'getMovie' }),
...mapGetters(['returnStarBig12w'])
}

异步数据有可能网络会卡顿,为了避免用户在发网络请求时候一直点击,我们应该用户体验友好,加loading。

那要在用户发送请求的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';
// 网络请求,完全可以做个内存缓存,先去检测仓库里面是否存在数据,如果存在,则不发送网络请求;不存在发送 后台,肯定上缓存 memcache redis 内存缓存 io 》》》 磁盘IO mysql
if( store.state.movieData.length > 0 ){
// 代表用户之前肯定点击获取电影,发送过网络请求
console.log('数据来自缓存信息!');
return;
}
//则这里的请求只能发送一次

而在请求数据的这个过程中我们可以显示loading效果,数据成功回来后loading效果:1. loading.gif 2. 插件 3. css3 loading 效果

这里随便找一个css3把

把loading翻入到组件中

  • 序号:{{ ele.id }}
  • 名称:{{ ele.title }}
  • 收藏数:{{ ele.star }}

//样式放在之后的style标签内

注意上面的代码我用了v-if和v-else,只能显示一个,是否显示取决于状态true还是false

接下来是修改状态,

注意:所有修改状态都是commit,只不过是异步是在action里面commit,同步是在.vue里面直接commit。

定义状态并初始flag

const store = new Vuex.Store({
// 开启 vuex 严格模式
strict: true, // 默认是false
// 仓库里面的数据(之前说的模型数据),一般我们叫做 state 状态
state: {
count: 10, // 计数器的初始值
movieData: [], // 电影数据,稍后使用 api 获取,异步请求
flag: false,
},

在发送请求之前的action里面修改状态

actions: {
getMovie: function (store, payload) {
var url = 'https://movie.52kfw.cn/index.php/Api/Movie/alst?page=1&size=20';
// 网络请求,完全可以做个内存缓存,先去检测仓库里面是否存在数据,如果存在,则不发送网络请求;不存在发送 后台,肯定上缓存 memcache redis 内存缓存 io 》》》 磁盘IO mysql
if( store.state.movieData.length > 0 ){
// 代表用户之前肯定点击获取电影,发送过网络请求
console.log('数据来自缓存信息!');
return;
}
//由于网络请求所耗费的时间是不确定,意味用户等待的时长也是不确定,为了防止乱点击,烦躁。一般在发送网络请求后,会在页面上出一个 loading的效果。数据成功回来后,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;
}

然后发完网络请求以后,在保存数据那里,就是表示发送成功,改变loading的状态

saveMovieData: function (state, payload) {
state.movieData = payload;
state.flag = false;
},

将不显示那个loading

最后的常量的优化

定义一个常量文件


常量.png

比如将这些设为常量

export const INCREMENT = 'increa'

export const DECREMENT = 'decrea'

然后在vuex的store文件里面导入常量


image.png

将需要用到的地方替换即可

//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组件文件里面同时也要
import {INCREMENT, DECREMENT} from './store/constant'
//需要用到的地方就可以
...mapMutations([ INCREMENT, DECREMENT]),