vuex案例-豆瓣接口
jsonp使用方法:https://www.npmjs.com/package/jsonp
豆瓣接口地址支持jsonp但是不支持cors。
- http://api.douban.com/v2/movie/subject/:id 详情
- http://api.douban.com/v2/movie/in_theaters 正在热映
- http://api.douban.com/v2/movie/1 即将上映
- http://api.douban.com/v2/movie/top250 top250
注意:
- 豆瓣的接口请求限制,每个外网IP有请求次数限制。
- 豆瓣的图片访问显示,非豆瓣域名下发起的图片请求不给予响应。
- 近期:官方停用搜索相关接口,必须要注册豆瓣api平台获取认证apikey才行。
- 网友提供
apikey=0df993c66c0c636e29ecbb5344252a4a
大家慎用
vuex案例-搭建项目
静态资源 douban-static.zip
完整案例 douban-vuex.zip
- 使用vue-router插件 router.js
- 使用vuex插件 store.js
main.js
import Vue from 'vue'
import App from './App.vue'
import store from './store'
import router from './router'
Vue.config.productionTip = false
new Vue({
render: h => h(App),
store,
router
}).$mount('#app')
store.js
// 路由相关功能
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const router = new VueRouter({
// TODO 路由规则
routes: []
})
export default router
router.js
// 路由相关功能
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const router = new VueRouter({
// TODO 路由规则
routes: []
})
export default router
vuex案例-配置路由及组件
-
封装组件
- 头部组件
- 底部组件
- 路由组件
- 正在热映
- 即将上映
- top250
- 电影详情
-
路由规则
- /hot
- / 重定向 /hot
- /movie
- /top
- /detail
在src/router.js中:
// 路由规则 routes: [ { path: '/', redirect: '/hot' }, { path: '/hot', component: Hot }, { path: '/movie', component: Movie }, { path: '/top', component: Top }, { path: '/detail', component: Detail } ]
在src/components/my-footer.vue中:
<div class="my-footer"> <ul> <li><router-link :to="{path:'/hot'}"><span class="iconfont icon-remen"></span> <p>正在热映</p> </router-link></li> <li><router-link :to="{path:'/movie'}"><span class="iconfont icon-dianying"></span> <p>即将上映</p> </router-link></li> <li><router-link :to="{path:'/top'}"><span class="iconfont icon-top"></span> <p>top250</p> </router-link></li> </ul> </div>
vuex案例-电影列表功能
在src/store.js中:
第一步:申明数据,根据页面需要的数据进行申明。
state: {
title: '',
list: []
},
第二步:定义修改数据的方法
mutations: {
// payload = {title,list} 约定数据格式
setListPageData (state, payload) {
state.title = payload.title
state.list = payload.list
}
},
第三步:获取数据的方法
actions: {
// 获取列表页面需要的数据
getListData (context) {
// 注意:豆瓣接口不支持跨域 支持jsonp
// 通过: jsonp的第三方插件 专门发jsonp请求
jsonp('http://api.douban.com/v2/movie/in_theaters?apikey=0df993c66c0c636e29ecbb5344252a4a', (err, data) => {
if (err) return alert('接口请求失败')
console.log(data)
// 提交数据 mutations
context.commit('setListPageData', { title: data.title, list: data.subjects })
})
}
}
在src/views/hot.vue中:
第四步:调用获取数据的方法
methods: {
...mapActions(['getListData'])
}
created () {
this.getListData()
// this.$store.dispatch('getListData')
},
第五步:获取vuex的数据
computed: {
...mapState(['list'])
},
第六步:渲染页面
<ul class="list">
<li v-for="item in list" :key="item.id">
<a href="#">
<img
:src="'https://images.weserv.nl?url='+item.images.small">
<div class="info">
<h3>{{item.title}}</h3>
<p>豆瓣评分:{{item.rating.average}}</p>
<p><span v-for="(item,i) in item.genres" :key="i" class="tag">{{item}}</span></p>
</div>
</a>
</li>
</ul>
vuex案例-电影详情功能
- 电影列表 电影的详情地址 都不一样 都会来到电影详情组件
- 使用动态路由功能 /detail/:id
- 电影详情组件获取id获取详情数据
在src/store.js中:
第一步:路由规则
{ path: '/detail/:id', component: Detail }
router-link :to="{path:'/detail/'+item.id}"
第二步:准备数据
state: {
// 标题
title: '',
// 详情
item: null
},
第三步:修改数据函数
mutations: {
// payload = {title,item} 约定数据格式
setItemPageData (state, payload) {
state.title = payload.title
state.item = payload.item
}
},
第四步:获取数据去修改数据的函数
actions: {
// 获取数据 详情
getItemData (context, id) {
jsonp('http://api.douban.com/v2/movie/subject/' + id + '?apikey=0df993c66c0c636e29ecbb5344252a4a', (err, data) => {
if (err) return alert('接口请求失败')
console.log(data)
// 提交数据 mutations
context.commit('setItemPageData', { title: data.title, item: data })
})
}
}
在src/views/detail.vue中:
第五步:在组件使用数据
computed: {
...mapState(['item'])
},
第六步:在组件初始化获取数据
created () {
this.getItemData(this.$route.params.id)
},
methods: {
...mapActions(['getItemData'])
}
第七步:渲染页面
<div class="item" v-if="item">
<img :src="'https://images.weserv.nl?url='+item.images.large" alt="">
<div>
<p>豆瓣评分:{{item.rating.average}}</p>
<p>产地:{{item.countries[0]}}</p>
<p><span v-for="(item,i) in item.genres" :key="i" class="tag">{{item}}</span></p>
<p>{{item.summary}}</p>
</div>
</div>
处理:空数据报错问题
<div class="item" v-if="item">
+item.images.large" alt="">
豆瓣评分:{{item.rating.average}}
产地:{{item.countries[0]}}
{{item}}
{{item.summary}}
处理:空数据报错问题
<div class="item" v-if="item">