由于项目中用到了豆瓣api,涉及到跨域访问,就需要在config的index.js添加代理,例如

proxyTable: { // 设置代理,解决跨域问题
'/api': {
target: 'https://api.douban.com/v2',
changeOrigin: true,
pathRewrite: {
'^/api': ''
}
}
},

安装axios

npm install --save axios vue-axios

在main.js引入axios

import axios from 'axios'
import VueAxios from 'vue-axios'
Vue.use(VueAxios, axios)

在各个组件里获取数据,就是这么简单

this.axios.get(api).then((response) => {
console.log(response.data)
})
由于豆瓣app首页的数据,我们不能直接通过api获取数据,只能先将数据保存下来进行访问,大家做项目的时候,访问静态数据json会遇到路径404,这里我们可以通过在dev-server.js里添加静态数据的路由,例如:我们先将豆瓣的首页数据先保存到/src/data/homeData.json,
 
dev-server.js 添加
/**************** 静态数据 start ****************/
var app = express()
var homeData = require('../src/data/homeData.json')
var apiRoutes = express.Router()
apiRoutes.get('/homeData',function(req,res){
res.json({
errno: 0,
data: homeData
})
})
app.use('/api',apiRoutes)
/**************** 静态数据 end *****************/
 
在组件里面访问
this.axios.get('/api/homeData').then((response) => {
console.log(response.data)
})

接下来我们将静态数据显示到首页中:静态数据分为热门和推荐,我么先fetchData获取数据,通过判断card.name,赋值给recommendData、hotData

export default {
name: 'index',
components: {
mHeader,
mSwipe,
mCell,
mCellMedia
},
data() {
return {
recommendData: [],
hotData: []
}
},
created() {
this.fetchData();
},
methods: {
fetchData() {
this.axios.get('/api/homeData').then((response) => {
let data = response.data.data.recommend_feeds;
let recommend = [];
let hot = [];
for (var i in data) {
if (data[i].card && data[i].card.name == '为你推荐') {
recommend.push(data[i]);
} else {
hot.push(data[i]);
}
}
this.recommendData = recommend;
this.hotData = hot;
})
}
}
}

在Index.vue循环media-cell组件

<m-cell-media :author="item.target.author.name" :column="item.source_cn" :img="item.target.cover_url" v-for="(item,index) in hotData"
:key="item.id">
<span slot="title">{{item.title}}</span>
<span slot="describe">{{item.target.desc}}</span>
</m-cell-media>

Index.vue

<template>
<div>
<!-- 头部 -->
<header class="m-header is-fixed is-bg top-search">
<div class="search-wrap">
<img src="../../assets/images/ic_search_gray.png" alt="">
<span class="placeholder">影视 图书 唱片 小组 舞台剧等</span>
<img src="../../assets/images/ic_scan_gray.png" alt="">
</div>
<!-- <div class="m-header-button is-right" style="text-align: center;width: 50px;">
<a href="javascript:;"><img class="m-icon-img" src="../../assets/images/ic_chat_white.png" /></a>
</div> -->
</header>
<!-- 主体 -->
<div class="page-content">
<!-- 轮播图 -->
<m-swipe swipeid="swipe01" :autoplay="1000" paginationDirection="right">
<div class="swiper-slide " slot="swiper-con"><img src="../../assets/images/banner/01.jpg" alt=""></div>
<div class="swiper-slide " slot="swiper-con"><img src="../../assets/images/banner/02.jpg" alt=""></div>
<div class="swiper-slide " slot="swiper-con"><img src="../../assets/images/banner/03.jpg" alt=""></div>
</m-swipe>
<!-- cell -->
<m-cell title="提醒" icon>
<img src="../../assets/images/ic_mine_notification.png" slot="icon">
<a href="javascript:;" slot="cell-right"><img src="../../assets/images/ic_arrow_gray_small.png" alt=""></a>
</m-cell>
<m-cell title="设置">
<a href="javascript:;" slot="cell-right"><img src="../../assets/images/ic_arrow_gray_small.png" alt=""></a>
</m-cell>
<!--热门-->
<div class="hot-wrap">
<m-cell title="热门" label="hot">
<!--<a href="javascript:;" slot="cell-right">更多<img src="../../assets/images/ic_arrow_gray_small.png" alt=""></a>-->
</m-cell>
<m-cell-media :author="item.target.author.name" :column="item.source_cn" :img="item.target.cover_url" v-for="(item,index) in hotData"
:key="item.id"> <span slot="title">{{item.title}}</span>
<span slot="describe">{{item.target.desc}}</span>
</m-cell-media>
</div> <!--推荐-->
<!-- <div class="recommend-wrap">
<m-cell title="推荐" label="recommend"></m-cell>
<m-cell-media :author="item.target.author.name" :column="item.source_cn" :bg="item.target.cover_url" v-for="(item,index) in recommendData" :key="item.id">
<span slot="title">{{item.title}}</span>
<span slot="describe">{{item.target.desc}}</span>
</m-cell-media>
</div> -->
</div>
</div>
</template> <script>
import mHeader from '../../components/header'
import mSwipe from '../../components/swipe'
import mCell from '../../components/cell'
import mCellMedia from '../../components/cell-media'
export default {
name: 'index',
components: {
mHeader,
mSwipe,
mCell,
mCellMedia
},
data() {
return {
recommendData: [],
hotData: []
}
},
created() {
this.fetchData();
},
methods: {
fetchData() {
this.axios.get('/api/homeData').then((response) => {
let data = response.data.data.recommend_feeds;
let recommend = [];
let hot = [];
for (var i in data) {
if (data[i].card && data[i].card.name == '为你推荐') {
recommend.push(data[i]);
} else {
hot.push(data[i]);
}
}
this.recommendData = recommend;
this.hotData = hot;
})
}
}
}
</script> <style lang="less">
// 头部
header.m-header {
padding: 0 0 0 10px;
} .is-fixed~.page-content {
padding-top: 44px;
padding-bottom: 50px;
} .top-search {
.search-wrap {
// width: 100%;
height: 30px;
background: #fff;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: space-between;
color: #c0c0c0;
padding: 0 12px;
.placeholder {
flex: 1;
text-align: left;
padding-left: 12px;
}
img {
width: 20px;
height: 20px;
}
}
}
// 热门
.hot-wrap,
.recommend-wrap {
padding-top: 12px;
}
</style>

  

header.vue

<template>
<header class="m-header" :class="{'is-bg':bg,'is-fixed':fixed}">
<div class="m-header-button is-left" v-show="leftShow">
<slot name="left"></slot>
</div>
<h1 class="m-header-title" v-text="title"></h1>
<div class="m-header-button is-right">
<slot name="right"></slot>
</div>
</header>
</template>
<script>
/**
* @param title - header显示的标题
* @param bg - header是否显示的标题背景
* @param {slot} [left] - 左侧的图片内容和文字
* @param {slot} [right] - 右侧的图片内容和文字
* @exmaple
* <m-header title="豆瓣app" :bg="true">
* <a href="javascript:;" slot="left"><img class="m-icon-img" src="../../assets/images/ic_bar_back_white.png"/>返回</a>
* <a href="javascript:;" slot="right">分享</a>
* </m-header>
*/
export default {
props: {
title: {
type: String,
default: ''
},
bg: {
type: Boolean,
default: false
},
fixed: {
type: Boolean,
default: false
},
leftShow: {
type: Boolean,
default: true
}
}
}
</script>
<style lang="less">
/*导入颜色变量*/
@import "../assets/less/var.less";
.m-header {
display: flex;
align-items: center;
height: 44px;
padding: 0 10px;
background: #fff;
color: @headerDefaultColor;
position: relative;
&:after {
content: '';
position: absolute;
left: 0;
bottom: 0;
right: 0;
height: 1px;
background: @headerBorderColor;
transform: scaleY(0.5);
}
a {
color: @headerDefaultColor;
}
.m-header-button {
width: 70px;
align-items: stretch;
&.is-left {
text-align: left;
}
&.is-right {
text-align: right;
}
.m-icon-img {
width: 20px;
height: 20px;
}
.margin-right-10 {
margin-right: 10px;
}
}
.m-header-title {
flex: 1;
text-align: center;
font-size: 16px;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
&.is-bg {
background: @headerBg;
color: #fff;
a {
color: #fff;
}
.m-header-title {
color: #fff;
}
&:after {
content: '';
position: absolute;
left: 0;
bottom: 0;
right: 0;
height: 0px;
background: @headerBorderColor;
transform: scaleY(0.5);
}
}
&.is-fixed {
position: fixed;
left: 0;
right: 0;
top: 0;
z-index: 9;
}
}
</style>

  

swipe.vue

<template>
<div class="swiper-container" :class="swipeid">
<div class="swiper-wrapper">
<slot name="swiper-con"></slot>
</div>
<!-- 分页器 -->
<div :class="{'swiper-pagination':pagination}" :style="{'text-align':paginationDirection}"></div>
</div>
</template>
<script>
import '../assets/lib/swiper/js/swiper.js'
export default {
props: {
swipeid: {
type: String,
default: ''
},
effect: {
type: String,
default: 'slide'
},
loop: {
type: Boolean,
default: true
},
direction: {
type: String,
default: 'horizontal'
}, autoplay: {
type: Number,
default: 5000,
},
paginationType: {
type: String,
default: 'bullets'
},
pagination: {
type: Boolean,
default: true
},
paginationDirection:{
type:String,
default:'center'
}
},
mounted() {
var That = this;
new Swiper('.'+That.swipeid, {
//循环
loop: That.loop,
//分页器
pagination: '.swiper-pagination',
//分页类型
paginationType: That.paginationType, //fraction,progress,bullets
//自动播放
autoplay: That.autoplay,
//方向
direction: That.direction,
//特效
effect: That.effect, //slide,fade,coverflow,cube
//用户操作swiper之后,是否禁止autoplay
autoplayDisableOnInteraction : false,
})
}
}
</script>
<style>
@import '../assets/lib/swiper/css/swiper.css'; .swiper-container img{
width: 100%
}
.swiper-pagination-bullet-active {
background: #fff;
}
</style>

  

cell.vue

<template>
<div class="m-cell normal" :class="label">
<div class="m-cell-title">
<slot name="icon"></slot> {{title}}
</div>
<div class="m-cell-right">
<slot name="cell-right"></slot>
</div>
</div>
</template>
<script>
export default {
props: {
title: {
type: String,
default: ''
},
hot: {
type: Boolean,
default: false
},
recommend: {
type: Boolean,
default: false
},
icon: {
type: Boolean,
default: false
},
label: {
type: String,
default: 'normal'
}
}
}
</script>
<style lang="less">
.m-cell {
position: relative;
padding: 10px 5px 10px 15px;
display: flex;
justify-content: space-between;
align-items: center;
&:before {
content: '';
position: absolute;
left: 0;
bottom: 0;
right: 0;
height: 1px;
background: #eee;
transform: scaleY(0.5);
}
.m-cell-title {
font-size: 15px;
img {
width: 20px;
height: 20px;
}
}
.m-cell-right {
font-size: 12px;
a {
color: #666;
}
img {
width: 20px;
height: 20px;
}
}
&.normal {}
&.hot {
padding: 0px 5px 0px 15px;
height: 22px;
&:after {
content: '';
position: absolute;
width: 5px;
left: 0;
top: 0px;
bottom: 0px;
background: #ff8447;
}
&:before {
height: 0
}
}
&.recommend {
padding: 0px 5px 0px 15px;
height: 22px;
&:after {
content: '';
position: absolute;
width: 5px;
left: 0;
top: 0px;
bottom: 0px;
background: #42bd56;
}
&:before {
height: 0
}
}
}
</style>

  

cell-media.vue

<template>
<div class="m-cell-media-wrap">
<a href="javascript:;">
<div class="m-cell-media-top">
<div class="m-cell-media">
<div class="m-cell-title m-ellipsis-2">
<slot name="title"></slot>
</div>
<div class="m-cell-detail m-ellipsis-2">
<slot name='describe'></slot>
</div>
</div>
<div class="m-pull-right right-img" :style="{'background-image':'url('+img+')'}">
</div>
</div>
<div class="m-cell-media-bottom">
<p v-if="author">作者:{{author}}</p>
<p v-if="column">{{column}}</p>
</div>
</a>
</div>
</template>
<script>
export default {
props: ['author', 'column', 'img']
}
</script>
<style lang="less">
.m-cell-media-wrap {
display: flex;
flex-direction: column;
padding: 18px 20px;
position: relative;
&:after {
content: '';
position: absolute;
left: 0;
bottom: 0;
right: 0;
height: 1px;
background: #eee;
transform: scaleY(0.5);
}
.m-cell-media-top {
display: flex;
flex-direction: row;
.m-cell-media {
flex: 1;
padding-right: 45px;
}
.m-cell-title {
font-size: 17px;
line-height: 22px;
color: #333;
font-weight: bold;
}
.m-cell-detail {
font-size: 12px;
padding-top: 12px;
color: #939393;
}
.m-pull-right {
width: 94px;
height: 94px;
overflow: hidden;
background-position: center center;
background-size: cover;
img {
width: 100%;
}
}
}
.m-cell-media-bottom {
display: flex;
justify-content: space-between;
padding-top: 20px;
margin-top: 12px;
color: #bfbfbf;
position: relative;
&:before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 20px;
height: 1px;
background: #eee;
}
}
}
</style>

  

 var.less
//APP默认颜色
@defaultColor:#42bd56;
//header
@headerBg:@defaultColor;
@headerDefaultColor:rgb(73,73,73);
@headerBorderColor:#e4e4e4;
//tabbar
@tabbarBorderColor:#e4e4e4;
@tabbarActiveColor: @defaultColor;

添加 reset.css

效果图

vue2.0 之 douban (六)axios的简单使用的更多相关文章

  1. vue2.0+webpack+vuerouter+vuex+axios构建项目基础

    前言 本文讲解的是vue2.0+webpack+vuerouter+vuex+axios构建项目基础 步骤 1.全局安装webpack,命令 npm install webpack -g 注意,web ...

  2. vue2.0 双向绑定原理分析及简单实现

    Vue用了有一段时间了,每当有人问到Vue双向绑定是怎么回事的时候,总是不能给大家解释的很清楚,正好最近有时间把它梳理一下,让自己理解的更清楚,下次有人问我的时候,可以侃侃而谈. 一.首先介绍Obje ...

  3. vue2.0 之 douban (七)APP 打包

    在打包之前需要修改一个地方,那就是config->index.js文件,修改assetsPublicPath: '/'为assetsPublicPath: './',截图如下 上面文件改好后,开 ...

  4. vue2.0项目实战使用axios发送请求

    在Vue1.0的时候有一个官方推荐的 ajax 插件 vue-resource,但是自从 Vue 更新到 2.0 之后,官方就不再更新 vue-resource. 关于为什么放弃推荐? -> 尤 ...

  5. vue2.0设置proxyTable使用axios进行跨域请求

    这里请求的是知乎日报的api,由@izzyleung这位大神提供的,这是github地址. 在vue-cli构建的项目中先安装axios npm install axios -S 这里暂不考虑用vue ...

  6. vue2.0:(六)、移动端像素border的实现和整合引入less文件

    知识点一.如何在手机上看我们制作的移动端页面. 正常我们在电脑上都是按如下图来制作手机页面的: 如果要在手机上面看就不能用localhost了.所以,进入命令行,输入ipconfig查看本地ip地址: ...

  7. vue2.0 + vux (六)NewsList 资讯页 及 NewsDetail 资讯详情页

    设置代理,避免出现跨域问题 /*设置代理,避免出现跨域问题*/ proxyTable: { '/api':{ target: 'https://www.oschina.net/action/apiv2 ...

  8. vue2.0 之 douban (三)创建header组件

    1.分析 首页的header背景是绿色的,并且有一个搜索框,其他页面都是灰色的背景,在header的左侧,是一个返回按钮,右侧,有分享或者评论等图标,中间就是header的标题.我们先不做有搜索框的h ...

  9. vue2.0 之 douban (二)创建自定义组件tabbar

    1.大体布局 这个组件分为两部分:第一个是组件的外层容器,第二个是组件的子容器item,子组件里面又分为图片和文字组合.子组件有2个状态,一个默认灰色的状态,一个选中状态,我们来实现一下这个组件的布局 ...

随机推荐

  1. Java设计模式——建造者模式(创建型模式)

    概述   建造者模式也称为生成器模式,是一种对象创建型模式,它可以将复杂对象的建造过程抽象出来(抽象类别),使这个抽象过程的不同实现方法可以构造出不同表现(属性)的对象.   建造者模式意在为重叠构造 ...

  2. react-redux --》react中 最好用的状态管理方式

    一.Redux与组件 react-redux是一个第三方插件使我们在react上更方便的来使用redux这个数据架构 React-Redux提供connect方法,用于从UI组件生成容器组件,conn ...

  3. python列表-增强的赋值操作

    增强赋值公式 (1) (2) (3) (4)

  4. 解决浏览器打开网页后提示“dns_probe_possible”的方法

    使用浏览器浏览网页时偶尔会遇到无法上网且浏览器提示:DNS_PROBE_POSSIBLE 一般有三种情况会导致这样的故障: 1.网络协议出现故障,也就是常说的 DNS 设置问题 2.浏览器中设置问题, ...

  5. [2019杭电多校第六场][hdu6641]TDL

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6641 题意为求出最小的n,满足(f(n,m)-n)^n=k,其中f(n,m)为第m大的x,其中x满足g ...

  6. Forbidden (CSRF token missing or incorrect.):错误解决办法

    在JS中,使用post方法提交数据到后台,出现错误: Forbidden (CSRF token missing or incorrect.):.........; 解决办法: 在页面导入JS的位置, ...

  7. Java ——数字图像处理(Java Graphics及其API简介)

    1.创建一个Graphics对象BufferedImage bi = new BufferedImage(120,120, BufferedImage.TYPE_INT_ARGB);Graphics2 ...

  8. MVC的view页面内嵌C#语法发现路径被转码的解决方法

    一,上视图代码,如下 console.log('@urlquery.ToString()'); console.log('@Html.Raw(urlquery.ToString())'); 二,显示结 ...

  9. Robot Framework 源码阅读 day1 __main__.py

    robot文件夹下的__main__.py函数 是使用module运行时的入口函数: import sys # Allows running as a script. __name__ check n ...

  10. Node.JS-经典教程

    目录 1. 下载地址 2. 目录 1. 下载地址 https://www.cnblogs.com/coco56/p/11223189.html 在视频教程那里 2. 目录 00课件.rar 01.历史 ...