为了账号安全,请及时绑定邮箱和手机立即绑定

Vuex 豆瓣电影项目实战

标签:
Vue.js

之前写过一个Vue2.0 豆瓣电影项目实战,项目地址GitHub。在此项目中使用了vue-router、axios、vue-cli等技术。最近学习了下Vuex,那就再用此技术吧这个项目做个改版。

Vuex介绍

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。 简单的理解就是管理我们的data共享给其他组件使用

术业有专攻,这样Vue只需负责页面以及交互,Vuex来操作数据。其它不做多介绍,自行Vuex官网脑补,在附带个Disciple_D写的一篇关于Vuex介绍的文章Vuex —— The core of Vue application

项目结构

// src 目录.
├── App.vue
├── main.js
├── api
│   └── movie.js          //抽取出API请求├── components
│   └── ...
├── store
│   ├── index.js          //我们组装模块并导出 store 的地方│   ├── mutation-types.js //根级别的 mutation 类型│   └── modules
│       ├── movieList.js  //电影列表模块│       └── movieDetail.js//电影详情模块.

现在我们就把之前项目中关于请求的抽取出movie.js,放在API模块下

API

// api/movie.jsimport axios from 'axios'export default {  // 获取正在上映的电影
  getInTheatersMovie(start = 0, count = 18){    return this.reqUrl(`/api/movie/in_theaters?start=${start}&count=${count}`)
  },  // 电影搜索
  searchMovie(key, start = 0, count = 18){    return this.reqUrl(`/api/movie/search?q=${key}&start=${start}&count=${count}`)
  },  // 获取电影详情
  getMovieDetailById(id){    return this.reqUrl(`/api/movie/subject/${id}`)
  },  // axios 请求
  reqUrl(url){    return new Promise((resolve, reject) => {
      axios.get(url).then(response => {
        resolve(response.data);
      })
    })
  }
}

PS:我们这里使用了Promise对象,它是异步编程的一种解决方案,使用此对象可以将异步操作以同步操作的形式表达出来,比传统的解决方案——回调函数和事件——更合理和更强大。不熟悉的同学可以看下阮一峰ECMAScript6中关于Promise对象的介绍

模块

豆瓣电影项目我们只是实现了三个功能,首页(正在上映的电影)、搜索页、详情页,但是首页和搜索页都只是展示电影列表,所以就把它当做两个模块来实现:电影列表模块、电影详情模块。 首先我们在store中引入这两个模块:

// store/index.jsimport Vue from 'vue'import Vuex from 'vuex'import movieList from './modules/movieList'import movieDetail from './modules/movieDetail'Vue.use(Vuex);export default new Vuex.Store({  modules:{
    movieList,
    movieDetail
  }
})

如果我们的模块很多,推荐大家使用模块命名空间来实现,这里我们就直接引入

在新建两个模块类型

// store/mutation-types.jsexport const MOVIE_LIST = 'MOVIE_LIST' // 电影列表export const MOVIE_DETAIL = 'MOVIE_DETAIL' // 根据ID获取电影信息

电影列表模块

// store/modules/movieList.jsimport * as types from '../mutation-types'import movie from '../../api/movie'const state = {  loading: true,  title: '',  list: []
}const getters = {  loading: state => state.loading,  list: state => state.list,  title: state => state.title
}const actions = {  // 获取正在上映的电影
  getInTheaters({ commit }){
    state.loading = true;
    movie.getInTheatersMovie().then(data => {
      commit(types.MOVIE_LIST, data)
    })
  },  // 搜索电影
  searchMovie({ commit }, key){
    state.loading = true;
    movie.searchMovie(key).then(data => {
      commit(types.MOVIE_LIST, data)
    })
  }
}const mutations = {
  [types.MOVIE_LIST](state, data){
    state.title = data.title;
    state.list = data.subjects;
    state.loading = false;
  }
}export default {
  state,
  getters,
  actions,
  mutations
}

下面开始调整我们的想对应的组件MovieList.vue,只需修改script代码,调整如下。

// src/components/MovieList.vueimport {mapGetters, mapActions} from 'vuex'
  export default {    // 这里也调整通过mapGetters获取数据
    computed: mapGetters({      loading: 'loading',      title: 'title',      list: 'list'
    }),    props: ['movieType'],// 接收父组件传过来的值 --in_theaters=正在上映的电影  --search==搜索电影
    mounted(){      // 修改后只需通过dispatch分发到对应的actions
      if (this.movieType == 'search') {        this.$store.dispatch('searchMovie', this.$route.params.searchKey);
      } else {        this.$store.dispatch('getInTheaters');
      }
    },    methods: mapActions([      'searchMovie'
    ])
  }

在讲解此段代码前, 先放一个示意图给大家看下

vuex.png


  • 在MovieList.vue中我们通过store分发(dispatch)到movieList.js中的actions的方法getInTheaters,actions中的方法主要是获取后台的数据,所以我们通过movie.getInTheatersMovie()调用API

  • 在得到数据后,提交(commit)到我们的Mutations,在Mutations中会改变(Mutate)我们的state(状态),也就是数据

  • 数据改变后他会渲染(Render)到我们的组件,通过getters派生出一些状态(数据)

  • MovieList.vue组件通过mapGetters获取数据

PS:其它关于搜索和详情的代码就不贴出来了, 都是一样的实现步骤,详细的代码可在我的GitHub上查看vuex 豆瓣电影项目实战,如果觉得有帮助的话,可star一下啊



作者:陈枫C
链接:https://www.jianshu.com/p/b55a47bd0ed7

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消