微信小程序入门级教程-10

作者: liuuuuuu | 来源:发表于2018-05-08 23:06 被阅读172次

    前言

      上节课中我们写好了电影列表的页面,接下来我们就开始正式开始获取网络数据了,不再是拿本地数组来自慰了,所以咱们也闲话少说,直接开始吧!

    效果图

    目录

    https://www.jianshu.com/p/9c9b555b52e8

    步骤

      在微信中,咱们获取数据有一个方法,就是wx.request(OBJECT),具体的参数和咱们使用的jqueryajax十分相似,我们这里就详细的看看他的参数有哪些,如下所示:

    请求数据参数表
    1. 首先咱们打开豆瓣的API公共接口文档:https://developers.douban.com/wiki/?title=movie_v2
    2. 我们可以找到我们需要的三个接口:
    正在热映:/v2/movie/in_theaters
    
    即将上映:/v2/movie/coming_soon
    
    Top250: /v2/movie/top250
    
    请求类型: GET
    参数:count(获取内容条数) // 这里我们只需要这个参数
    
    1. app.js中配置一个全局的请求路径头,然后命名为BASEPATH,在movies中引入app.js
      app.js
    BASEPATH: "https://d1ouban.uieee.com/" 
    // 豆瓣本身的地址请求会发生403错误,所以在这里我们使用大佬提供的服务器地址
    
    let app = getApp();
    
    onLoad: function(){
      let inTheaters = app.globalData.BASEPATH + "v2/movie/in_theaters",
      wx.request({
        url: inTheaters,
        data: { count: 3 }, // 页面中目前我们只需要3条数据
        header:{ "Content-Type":"json" },
        success: function(res) {
          console.log(res)
        }
      });
    }
    
    报错信息
    注意:

      在这里报错了,微信也提示了我们需要去配置域名,所以登录微信开放平台,找到自己的小程序,在请求配置里面配置BASEPATH那个地址,这样子我们家就可以在小程序中访问https://d1ouban.uieee.com/了,切记,配置域名的时候,不要最后的斜杠,不然域名配置提示错误!!配置好了,退出小程序,然后重新进来,再看看控制台,可以看到如下结果:

    数据图
    1. 接下来我们就可以规划,先把所有需要的数据全部拿下再说:
    let app = getApp();
    Page({
        onLoad: function(e){
            let inTheaters = app.globalData.BASEPATH + "v2/movie/in_theaters",
                comeingSoon = app.globalData.BASEPATH + "v2/movie/coming_soon",
                top250 = app.globalData.BASEPATH + "v2/movie/top250";
    
            // 调用三次不同的接口请求不同的数据
            this.getData(inTheaters, "inTheaters");
            this.getData(comeingSoon, "comeingSoon");
            this.getData(top250, "top250");
    
        },
    
        // 封装请求数据的函数
        // 参数: [ 路径 ,接收结果的对象 ]
        getData: function(url, setKey){
            let that = this;
            wx.request({
                url: url,
                data: { count: 3 }, // 页面中目前我们只需要3条数据
                header:{ "Content-Type":"json" },
                success: function(res) {
                    // 调用专门处理数据的函数
                    // 参数: [ 数据, 接收结果的对象 ]
                    that.processDoubanData(res.data.subjects, setKey);
                }
            });
        },
    
        //处理数据的函数 
        // 参数: [ 数据, 接收结果的对象 ]
        processDoubanData: function(data, setKey){
            var movie = [];
            for(let subject of data){
                let temp = {}
                temp.title = subject.title; // 标题
                temp.average = subject.rating.average.toFixed(1); // 评分值
                temp.coverageUrl = subject.images.large; // 封面图
                temp.movieId = subject.id; // 电影ID
                movie.push(temp);
            }
            // 往data中动态创建变量来保存数据
            this.setData({
                // 因为这里不能直接写setKey,所以用[]来包裹住变量key,相当于占位符
                [setKey]: {
                    // 这里额外创建了一个对象,赋予movies属性我们的数据
                    // 因为在后面,我们的模板是循环写的,所以在这里,
                    // 我们需要让他们三个都有一个共同的属性值,方便模板循环遍历
                    movies: movie
                }
        });
        }
    })
    
    1. 在已经拿到数据了,我们的data中就有了3个变量:


      控制台

    然后我们开始往模板中赋值:

    movies.wxml

    <import src="movieList/movie-list-template.wxml" />
    <view class="container">
        <view class="movie-template">
            <template is="movieListTemplate" data="{{...inTheaters}}" />
        </view>
        <view class="movie-template">
            <template is="movieListTemplate" data="{{...comeingSoon}}" />
        </view>
        <view class="movie-template">
            <template is="movieListTemplate" data="{{...top250}}" />
        </view>
    </view>
    

    movie-list-template.wxml

    <import src="../movie/movie-template.wxml" />
    <template name="movieListTemplate">
        <view class="movie-list-container">
            <div class="inner-container">
                <view class="movie-head">
                    <text class="slogan">正在热映</text>
                    <view class="more">
                        <text class="more-text">更多</text>
                        <image class="more-img" src="/images/icon/arrow-right.png"></image>
                    </view>
                </view>
                <view class="movies-container">
                    // 这里传入三者共同的属性值movies
                    // 这就是为什么movies.js中我们要给数据包裹成一个对象的原因了
                    <block wx:for="{{movies}}" wx:for-item="movie">
                        <template is="movieTemplate" data="{{...movie}}" />
                    </block>
                </view>
            </div>
        </view>
    </template>
    

    效果图如下:

    效果图
    1. 基本快完成了,接下来我们来实现评分的组件,首先我们可以看到豆瓣网返回的电影数据如下:


      数据结构

      在上面的数据中,我们的评分组件,展示的星星数量基本就和我标红的数字有关,这里我们暂时不考虑半星的情况,直接先考虑整星的情况,那么我们对应的30就是3星,50就是5星,45就是4.5星。我们在这里就用数组来表示,有星用1表示,没星就用0表示,那么如果是3星,那我们的数组就是[1, 1, 1, 0, 0]。那我们就开始封装一个方法吧,在项目根目录下创建一个文件夹utils,在其下创建utils.js,代码如下:

    // 将数组转换为数组
    function converToStarsArray(stars){
        let num = parseInt(stars.toString().substr(0,1));
        let arr = [], temp = 0;
        for(let i = 0; i < 5; i++){
            temp = i >= num ? 0 : 1;
            arr.push(temp);
        }
        return arr;
    }
    module.exports = {
        converToStarsArray: converToStarsArray
    }
    

    然后我们在修改一下当初存放电影详情的地方movies.js:

    processDoubanData: function(data, setKey){
            var movie = [];
            for(let subject of data){
                let temp = {}
                temp.title = subject.title;
                temp.average = subject.rating.average.toFixed(1);
                temp.coverageUrl = subject.images.large;
                temp.movieId = subject.id;
                // 唯一改变的地方:新增了一个关于星星控件的数组属性
                temp.stars = util.converToStarsArray(subject.rating.stars);
                movie.push(temp);
            }
            this.setData({
                [setKey]: {
                    movies: movie
                }
            });
        }
    

    接下来修改一下movies-template.wxml:

    <import src="../stars/stars-template.wxml" />
    <template name="movieTemplate">
        <view class="movie-container">
            <image class="movie-img" src="{{coverageUrl}}"></image>
            <text class="movie-title">{{title}}</text>
            // 唯一修改处:这里使用json的形式传值 [新知识,切记!]
            // 我们将average赋值给了average,stars赋值给了stars
            <template is="starsTemplate" data="{{average: average, stars: stars}}" />
        </view>
    </template>
    

    最后我们再修改star-template.wxml:

    <template name="starsTemplate">
        <view class="stars-container">
            <view class="stars">
                <block wx:for="{{stars}}" wx:for-item="i">
                    // 如果是1就实星,否则就是空星
                    <image wx:if="{{i}}" src="/images/icon/star.png"></image>
                    <image wx:else="{{i}}" src="/images/icon/none-star.png"></image>
                </block>
            </view>
            <text class="stars"></text>
            <text class="star-score">{{average}}</text>
        </view>
    </template>
    

    效果如下:

    效果图
    1. 最后在本页面中,基本都快完成了,更多这个功能我们需要另外写页面,这里就先不慌说了,先把细节问题优化了,例如现在每个大标题都是正在热映,修改也简单,就是动态的给页面赋值,和电影一样,具体操作如下:
    processDoubanData: function(data, setKey){
            let that = this;
            let movie = [];
            for(let subject of data){
                let temp = {}
                temp.title = subject.title;
                temp.average = subject.rating.average.toFixed(1);
                temp.coverageUrl = subject.images.large;
                temp.movieId = subject.id;
                temp.stars = util.converToStarsArray(subject.rating.stars);
                movie.push(temp);
            }
            let {length: len} = setKey;
            //动态判断是哪一块的内容,然后自己判断赋值
            if(len == 10){
              this.setData({ [setKey]: { slogan: "正在热映", movies: movie } });
            }else if(len == 11){
              this.setData({ [setKey]: { slogan: "即将上映", movies: movie } });
            }else{
              this.setData({ [setKey]: { slogan: "TOP250", movies: movie } });
            }
        }
    

    movie-list-template.wxml

    <import src="../movie/movie-template.wxml" />
    <template name="movieListTemplate">
        <view class="movie-list-container">
            <div class="inner-container">
                    <view class="movie-head">
                    <text class="slogan">{{slogan}}</text>
                    <view class="more">
                        <text class="more-text">更多</text>
                        <image class="more-img" src="/images/icon/arrow-right.png"></image>
                    </view>
                </view>    
                <view class="movies-container">
                    <block wx:for="{{movies}}" wx:for-item="movie">
                        <template is="movieTemplate" data="{{...movie}}" />
                    </block>
                </view>
            </div>
        </view>
    </template>
    

    大功告成,结果如下所示:

    最终效果图
    注意点:

      在这里,为了实现动态大标题的过程中,我原本使用了eval函数和ES6来达到目的,但是小程序报错了,eval函数找不到,后来知道了,在小程序中,认为eval有风险,所以在小程序中,我们是不能使用eval函数的哦。

    后言

      本节课讲了获取数据,如何在嵌套的组件里填充数据,希望大家可以好好消化一下,认认真真练习,有什么不懂得,可以发简信给我,谢谢大家~

    项目源码:demigod-liu / douban-movies

    说明

    原创作品,禁止转载和伪原创,违者必究!

    相关文章

      网友评论

      • 穆熙沐:在开放平台怎么配置路径呢?我开放平台是空的
        穆熙沐:@骑着毛驴逗你玩儿 token也是必须填,不知道填啥?结果我只好在项目选择不校验
        liuuuuuu:直接配上服务器地址即可,必须是https,以com等后缀结尾便可,不要在后缀后面加/,会提示格式不服

      本文标题:微信小程序入门级教程-10

      本文链接:https://www.haomeiwen.com/subject/ancwrftx.html