前端入门到熟悉day31

Douban-底部导航tabBar
微信小程序底部导航Tabbar
底部导航栏这个功能是非常常见的一个功能,基本上一个完成的app,都会存在一个导航栏,那么微信小程序的导航栏该怎么实现呢?经过无数的踩坑,终于实现了,好了,先看看效果图。

对于底部导航栏,小程序上给出的文档要求里面的item最少2个,最多五个。
好了,先看看代码:
在项目中找到这个文件

{
“pages”:[
“pages/index/index”,
“pages/logs/logs”,
“pages/mine/mine”
],
“window”:{
“backgroundTextStyle”:“light”,
“navigationBarBackgroundColor”: “#fff”,
“navigationBarTitleText”: “首页”,
“navigationBarTextStyle”:“black”
},
“tabBar”: {
“color”: “#a9b7b7”,
“selectedColor”: “#11cd6e”,
“borderStyle”: “black” ,
“list”: [{
“selectedIconPath”: “images/icon_consult_press.png”,
“iconPath”: “images/icon_consult.png”,
“pagePath”: “pages/index/index”,
“text”: “首页”
}, {
“selectedIconPath”: “images/icon_invest_press.png”,
“iconPath”: “images/icon_invest.png”,
“pagePath”: “pages/logs/logs”,
“text”: “一元投”
},{
“selectedIconPath”: “images/icon_mine_press.png”,
“iconPath”: “images/icon_mine.png”,
“pagePath”: “pages/mine/mine”,
“text”: “我的”
}
]
}
}

这里我先解释一下这些属性是什么意思:
tabBar  指底部的 导航配置属性
color  未选择时 底部导航文字的颜色
selectedColor  选择时 底部导航文字的颜色
borderStyle  底部导航边框的样色(注意 这里如果没有写入样式 会导致 导航框上边框会出现默认的浅灰色线条)
list   导航配置数组
selectedIconPath 选中时 图标路径
iconPath 未选择时 图标路径
pagePath 页面访问地址
text  导航图标下方文字
 
 
这里需要注意一些小问题:
1、每个页面的json文件都不能去掉navigationBarTitleText这个属性。否则会报错
2、
“pages”:[
3 “pages/index/index”,
4 “pages/logs/logs”,
5 “pages/mine/mine”
6
7 ],
这个页面的注册一定要注意,第一个一定是要是最先显示的,否则会出现底部导航看不到。
“tabBar”:{
“list”:[
{
“pagePath”:“pages/posts/post”,
“text”:“阅读”,
“iconPath”:"/images/tab/yuedu.png",
“selectedIconPath”:"/images/tab/yuedu_hl.png"
},
{
“pagePath”: “pages/movies/movies”,
“text”: “电影”,
“iconPath”: “/images/tab/dianying.png”,
“selectedIconPath”: “/images/tab/dianying_hl.png”
}
]
}

Douban-首页静态布局(template嵌套template)
stars(评星)—>movie(电影)—>movie-list(一组电影)—>电影首页
具体内容参考:2019.01.22笔记
Douban过滤数据电影首页
data: {
//用对象存储我们过滤好的数据再传给template
inTheaters:{},
comingSoon:{},
top250:{}
},

/**

  • 生命周期函数–监听页面加载
    */
    onLoad: function (options) {
    var inTheatersUrl = app.globalData.doubanBase +"/v2/movie/in_theaters"+"?start=0&count=3"
    var comingSoonUrl = app.globalData.doubanBase + “/v2/movie/coming_soon” + “?start=0&count=3”
    var top250Url = app.globalData.doubanBase + “/v2/movie/top250” + “?start=0&count=3”;
    this.getMovieListData(inTheatersUrl,“inTheaters”)
    this.getMovieListData(comingSoonUrl,“comingSoon”)
    this.getMovieListData(top250Url,“top250”)
    },
    // 发请求
    getMovieListData: function (url, settedKey){
    var that = this;
    wx.request({
    url: url,
    method:“GET”,
    header:{
    “Content-Type”: “json”
    },
    success:function(res){
    // console.log(res.data)
    that.processDoubanData(res.data, settedKey);
    },
    fail:function(error){
    console.log(error)
    }
    })
    },
    // 过滤接口数据
    processDoubanData: function (moviesDouban, settedKey){
    var movies = [];
    for (var idx in moviesDouban.subjects){
    //获取处理数据
    var subject = moviesDouban.subjects[idx]
    var title = subject.title;
    var temp = {
    title: title,
    average: subject.rating.average,
    coverageUrl: subject.images.large,
    movieId:subject.id
    }
    movies.push(temp);
    }
    // console.log(movies);
    var readyData={};
    readyData[settedKey]={
    movies: movies
    }
    this.setData(readyData);
    console.log(readyData)
    },
    js对象动态赋值









    获取movies有用的数据后,怎样一 一对应各自的数据呢。
    Page({
    data:{
    inTheaters: {},
    comingSoon: {},
    top250: {}//定义这三个结构体变量可以分别绑定在xml页面中
    }
    })
    在js中 调用的地方可以区分三种数据
    onLoad: function (event) {
    var inTheatersUrl = app.globalData.doubanBase +
    “/v2/movie/in_theaters” + “?start=0&count=3”;
    var comingSoonUrl = app.globalData.doubanBase +
    “/v2/movie/coming_soon” + “?start=0&count=3”;
    var top250Url = app.globalData.doubanBase +
    “/v2/movie/top250” + “?start=0&count=3”;

    this.getMovieListData(inTheatersUrl, “inTheaters”, “正在热映”);
    this.getMovieListData(comingSoonUrl, “comingSoon”, “即将上映”);
    this.getMovieListData(top250Url, “top250”, “豆瓣Top250”);
    },
    接收方也要相应的添加参数
    getMovieListData: function (url, settedkey, categoryTitle) {
    var that = this;
    wx.request({
    url: url,
    method: ‘GET’, // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT
    header: { “Content-Type”: “json” }, // 设置请求的 header
    success: function (res) {
    // success console.log(res)
    that.processDoubanData(res.data, settedkey, categoryTitle)
    },
    fail: function () {
    // fail
    console.log(“failed”)
    }
    })
    },

processDoubanData: function (moviesDouban, settedkey, categoryTitle) {
var movies = [];//空的数组做为处理完数组的容器
for (var idx in moviesDouban.subjects) {
var subject = moviesDouban.subjects[idx];
var title = subject.title;
if (title.length >= 6) {
title = title.substring(0, 6) + “…”;
}
//[1,1,1,1,0]
var temp = {
stars: util.convertToStarsArray(subject.rating.stars),
title: title,
average: subject.rating.average,
coverageUrl: subject.images.large,
movieId: subject.id
}
movies.push(temp)
}
var readayData = {};
readayData[settedkey] = {movies:movies}; //动态属性
this.setData(readayData);
}



Douban电影首页动态数据绑定和渲染页面
  在微信中,咱们获取数据有一个方法,就是wx.request(OBJECT),具体的参数和咱们使用的jquery的ajax十分相似
请求数据参数表
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个变量:
2.

控制台
4.
然后我们开始往模板中赋值:
movies.wxml










movie-list-template.wxml




正在热映

更多




// 这里传入三者共同的属性值movies
// 这就是为什么movies.js中我们要给数据包裹成一个对象的原因了






效果图如下:

效果图

作者:骑着毛驴逗你玩儿
链接:https://www.jianshu.com/p/114561001a49(详细的)
https://www.jianshu.com/p/9c9b555b52e8(小程序总的)(多看)

來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

Douban评星组件制作
function convertToStarsArray(stars) {
// 30只要3 50只要5 把第一个数字去掉
var num = stars.toString().substring(0, 1);
var array = [];
for (var i = 1; i <= 5; i++) {
if (i <= num) {
array.push(1);
}
else {
array.push(0);
}
}
return array;
}
module.exports = {
convertToStarsArray: convertToStarsArray,
}

这里我们暂时不考虑半星的情况,直接先考虑整星的情况,那么我们对应的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:



{{title}}
// 唯一修改处:这里使用json的形式传值 [新知识,切记!]
// 我们将average赋值给了average,stars赋值给了stars


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




// 如果是1就实星,否则就是空星





{{average}}

作者:骑着毛驴逗你玩儿
链接:https://www.jianshu.com/p/114561001a49
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

Douban电影更多页面布局和渲染页面
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




{{slogan}}

更多









1.我们用movie-grid.wxml来封装电影信息,然后在more-movie.wxml页面中,我们只需要引入该模板就行了,如下所示:
movie-grid.wxml

<view class="grid-container">
    <block wx:for="{{movies}}" wx:for-item="movie">
        <view class="single-grid-container">
            <template is="movieTemplate" data="{{...movie}}" />
        </view>
    </block>
</view></template>

movie-grid.wxss
/* pages/movies/movie-grid/movie-grid.wxss */
@import “…/movie/movie-template.wxss”;.grid-container{

}.single-grid-container{
float: left;
margin: 20rpx 0 20rpx 6rpx;
}
封装好了这个电影内容的组件后,我们在more-movie中直接引入即可,如下:

接下来就是引入模板的样式了,如下:
/* pages/movies/more-movie/more-movie.wxss */
@import “…/movie-grid/movie-grid.wxss”;

作者:骑着毛驴逗你玩儿
链接:https://www.jianshu.com/p/4355da4c38b3
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

Douban上拉加载更多和动态设置导航栏标题
.页面搭建完毕后,我们就需要分析一下如下问题:
我们需要哪个板块的内容信息?[正在热映, 即将上映, top250]
页面标题需要动态的展示是哪个板块?[正在热映, 即将上映, top250]
分析的差不多了,剩下的就是一个个解决如上问题了,接下来就开始一步一步跟着我走吧!
1.如何获取我们需要那个板块的电影信息?
分析:在movies.js中,我们在onLoad函数中调用了三次请求数据,而我们需要做的就是手动添加对应的标题到请求函数中,如下所示:
onLoad(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”, “TOP250”);
},
getData(url, setKey, slogans) {
let that = this;
wx.request({
url: url,
data: { count: 3 },
header: { “Content-Type”: “json” },
success(res) {
// 将标题传入处理电影信息的方法中
that.processDoubanData(res.data.subjects, setKey, slogans);
}
});
},
processDoubanData(data, setKey, slogans) {
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);
}
this.setData({
[setKey]: {
// 将标题传入处理电影信息对象中
slogan: slogans,
movies: movie
}
});
}
然后我们在movie-list-template.wxml中绑定上我们传过去的slogan值!




{{slogan}}
// 给更多这个容器绑定上slogan,这样子我们就可以在点击更多后,在新页面得到这个值

更多










接下来我们就在更多那个页面来获取这值,并且展示:
more-movie.js
onLoad(options) {
// 获取点击更多传过来的我们绑定的标题slogan值
let [that, categroy] = [this, options.categroy];
this.data.barTitle = categroy;
},
onReady(event) {
let that = this;
// 设置导航标题
wx.setNavigationBarTitle({
title: that.data.barTitle
})
}
1.获取对应数据
  我们在小程序中获取电影的次数有点多,所以我们在之前创建的utils.js中新创建一个函数,专门用来封装请求数据的方法,具体如下:
function http(url, callBack) {
let that = this;
wx.request({
url: url,
header: { “Content-Type”: “json” },
success(res) {
// 切记把值传给一个回调函数
callBack(res.data);
},
fail(err){
console.log(err)
}
});
}
在上面我们得到了本页的标题,所以我们可以根据这个标题来知道我们应该请求那个接口,如下所示:
onLoad(options) {
let [that, categroy] = [this, options.categroy];
this.data.barTitle = categroy;
// 定义一个接口路径的变量
let interfaceUrl = null;
// 根据标题判断请求路径
switch (categroy) {
case “正在热映”:
interfaceUrl = app.globalData.BASEPATH + “v2/movie/in_theaters”;
utils.http(interfaceUrl, that.precessDoubanData);
break;
case “即将上映”:
interfaceUrl = app.globalData.BASEPATH + “v2/movie/coming_soon”;
utils.http(interfaceUrl, that.precessDoubanData);
break;
default:
interfaceUrl = app.globalData.BASEPATH + “v2/movie/top250”;
utils.http(interfaceUrl, that.precessDoubanData);
}
// 保存当前页面的数据请求地址,方便其他函数使用
this.data.requestUrl = interfaceUrl;
},
precessDoubanData(data){
let movie = [];
for (let subject of data.subjects) {
let temp = {}
temp.title = subject.title;
temp.average = subject.rating.average.toFixed(1);
temp.coverageUrl = subject.images.large;
temp.movieId = subject.id;
temp.stars = utils.converToStarsArray(subject.rating.stars);
movie.push(temp);
}
this.setData({
movies: movie
})
}
接下来开始在模板页面more-movie.wxml中给template绑定上我们的值:

1.下拉刷新和上拉加载
  解析:下拉刷新原理就是在movies.js中记录总共请求的电影数量,然后执行刷新的时候,传入count=电影总数即可,上拉加载呢,就是每次请求的起点是目前请求的总数,而一次加载的数量自己决定,在这里,我以20条一次为例,具体代码如下:
注意: 如果需要下拉刷新的页面,一定要在其json文件中声明,如下所示:
{
“navigationBarBackgroundColor”: “#2c2e3b”,
// 下拉的配置
“enablePullDownRefresh”: true
}
// pages/movies/more-movie/more-movie.jslet utils = require("…/…/…/utils/utils");let app = getApp();
Page({
data: {
movies: [],
totalCount: 0
},
/**
* 生命周期函数–监听页面加载
*/
onLoad(options) {
let [that, categroy] = [this, options.categroy];
this.data.barTitle = categroy;
let interfaceUrl = null;
switch (categroy) {
case “正在热映”:
interfaceUrl = app.globalData.BASEPATH + “v2/movie/in_theaters”;
utils.http(interfaceUrl, that.precessDoubanData);
break;
case “即将上映”:
interfaceUrl = app.globalData.BASEPATH + “v2/movie/coming_soon”;
utils.http(interfaceUrl, that.precessDoubanData);
break;
default:
interfaceUrl = app.globalData.BASEPATH + “v2/movie/top250”;
utils.http(interfaceUrl, that.precessDoubanData);
}
// 保存当前页面的数据请求地址,方便其他函数使用
this.data.requestUrl = interfaceUrl;
},
onReady(event) {
let that = this;
wx.setNavigationBarTitle({
title: that.data.barTitle
})
},
precessDoubanData(data){
let movie = [];
for (let subject of data.subjects) {
let temp = {}
temp.title = subject.title;
temp.average = subject.rating.average.toFixed(1);
temp.coverageUrl = subject.images.large;
temp.movieId = subject.id;
temp.stars = utils.converToStarsArray(subject.rating.stars);
movie.push(temp);
}
let moviesList = this.data.movies.concat(movie);
this.setData({
movies: moviesList
})
wx.hideNavigationBarLoading();
// 保存当前电影总共条数,方便下拉加载使用
this.data.totalCount += 20;
// 去除下拉Loding
wx.stopPullDownRefresh();
},
onPullDownRefresh(e){
this.data.movies = [];
let requestUrl = this.data.requestUrl + “?count=” + this.data.totalCount;
utils.http(requestUrl, this.precessDoubanData);
// 因为请求数据,就会自增20,所以我们在这里减去这20就可以达到我们想要的数据条数了
this.data.totalCount -= 20;
},
onReachBottom(e){
// 开启下拉加载时页面顶部的加载动效
wx.showNavigationBarLoading();
let requestUrl = this.data.requestUrl + “?start=” + this.data.totalCount + “&count=20”;
utils.http(requestUrl, this.precessDoubanData);
}
})

作者:骑着毛驴逗你玩儿
链接:https://www.jianshu.com/p/4355da4c38b3
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

上拉加载事件onReachBottom
Loading加载效果wx.showNavigationBarLoading()和关闭Loading的函数wx.stopPullDownRefresh()

猜你喜欢

转载自blog.csdn.net/weixin_44160944/article/details/88043903
今日推荐