• vue2.0 之 douban (六)axios的简单使用


    由于项目中用到了豆瓣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; 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 {
          //  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 {
             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 {
           70px;
          align-items: stretch;
          &.is-left {
            text-align: left;
          }
          &.is-right {
            text-align: right;
          }
          .m-icon-img {
             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{
         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 {
             20px;
            height: 20px;
          }
        }
        .m-cell-right {
          font-size: 12px;
          a {
            color: #666;
          }
          img {
             20px;
            height: 20px;
          }
        }
        &.normal {}
        &.hot {
          padding: 0px 5px 0px 15px;
          height: 22px;
          &:after {
            content: '';
            position: absolute;
             5px;
            left: 0;
            top: 0px;
            bottom: 0px;
            background: #ff8447;
          }
          &:before {
            height: 0
          }
        }
        &.recommend {
          padding: 0px 5px 0px 15px;
          height: 22px;
          &:after {
            content: '';
            position: absolute;
             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 {
             94px;
            height: 94px;
            overflow: hidden;
            background-position: center center;
            background-size: cover;
            img {
               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;
             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

    效果图

  • 相关阅读:
    程序员面试笔试宝典学习记录(三)(数据库相关知识)
    程序员面试笔试宝典学习记录(二)(程序设计相关知识)
    程序员面试笔试宝典学习记录(一)(常见面试笔试题目)
    浮点型数据在内存中的存储【转】
    docker compose网络设置
    Docker的Ubuntu16.04容器如何汉化
    Docker的centos7容器中如何安装mongodb
    用Java代码实现拦截区域网数据包
    wireshark 抓包分析 TCPIP协议的握手
    如何通过代理方式访问网络
  • 原文地址:https://www.cnblogs.com/crazycode2/p/7523229.html
Copyright © 2020-2023  润新知