Chapter two

1.首页页面效果图

2.首页分解图

3.首页业务逻辑

 1.使用tabBar实现底部导航功能

 2.使用自定义组件的方式实现头部搜索框

 3.加载轮播图数据

 4.加载导航数据

 5.加载楼层数据

4.接口API

 1.获取首页轮播图数据

https://api-hmugo-web.itheima.net/api/public/v1/home/swiperdata

  2.获取首页分类菜单数据

https://api-hmugo-web.itheima.net/api/public/v1/home/catitems

  3.获取首页楼层数据

https://api-hmugo-web.itheima.net/api/public/v1/home/floordata

5.关键技术

5.1.自定义组件实现搜索栏

      这个主要是添加外表的搜索栏,暂时搜索栏的内部还没弄。

     首先创建components\SearchInput文件夹,components作为存放组件:

       我得提前说一下,为何多了一个less样式文件,其实css对我来说是一种常态,这个css和less有点区别,这两者只不过多了那些扩展,反正它们有各种的特点。less和css都可以用,就看使用者编写样式的习惯,但是我用less真的很舒服,尤其是定义变量、函数等。维护及修改更方便,会更规范、简洁。less对我来说最大好处就是层叠嵌套。wxss和less可以互相支持同步更新内容。(对于这个less层叠嵌套的问题有空会写)

 

1.1SearchInput.wxml

<view class="search_input">
    <navigator url="/pages/search/index" open-type="navigate">搜索 </navigator>
</view>

  navigator标签相当于html的a标签,open-type就是跳转方式:

  (1) navigate:默认(可写可不写),保留当前页面,跳转到别的页面,不能跳转到tabBar。

  (2) redirect:关闭当前页面,并跳转到别的页面,不支持跳转到tabBar。

  (3) switchTab:支持跳转到tabBar页面,但会关闭其他的非tabBar页面。

  (4) reLaunch:关闭所有当前页面,但能打开跳转到别的页面。

   以上的标签最好自己动手来测试,测试效果的区别就知道即可。

 

2.SearchInput.less

.search_input{
    height:90rpx;
    padding: 10rpx;
    background-color: var(--themeColor);
    navigator{
        height: 100%;
        display:flex;
        justify-content: center;
        align-items: center;
        background-color: #ffffff;
        border-radius: 15rpx;
        color:#666;
    }
} 

     这个编写样式的详细不说了,其实这不难的。不过还有一个就是var(--themeColor),表示通过css调用变量,一般在app.wxss中写page{--themeColor:随便选的颜色}。

效果图:

5.2.swiper组件

      swiper标签就是轮播图,在实际生活上,大部分项目都在用这个的组件。不只是swiper标签,但其中必须要放swiper-item组件,否则导致未定义的行为。我一般习惯看小程序文档官方,包括框架文档官方都有,这文档里面都有详细的属性。我不说详细了,接下来展示代码:

 1.index.wxml

<view class="index_swiper">
        <swiper autoplay indicator-dots circular>
            <swiper-item 
            wx:for="{{swiperList}}"
            wx:key="good_id"
            >
                <navigator>
                    <image mode="widthFix" src="{{item.image_src}}"></image>
                </navigator>        
            </swiper-item>
        </swiper>
    </view>

  swiper标签主要的属性有:

  autoplay:是否自动切换图片。

  indicator-dots:是否显示面板指示点,比如黑色或白色的圆点。

  circular:是否采用衔接滑动。

 

  另外说到图片自适应的问题,这点对我来说很重要,因为有些图片出现会变形,有的图片左右上下出现有空白的等等。

  2.index.less

.index_swiper{
    swiper{
        width: 750rpx;
        height:340rpx;
        image{
            width: 100%;
        }
    }
}

  首先对两个标签默认的宽度和高度:

  1.swiper标签默认的宽度和高度:100% * 150px。

  2.image标签默认的宽度和高度: 320px * 240px。

  3.设计图片和轮播图

   3.1首先要看原图的宽高,比如宽为750px;  高为340px;注意写样式的时候, 尽量要用rpx,千万不要写px,因为要根据手机屏幕不一样,所以尽量要通过自适应像素。

   3.2要让图片的高度自适应 ,宽度尽量等于100%。

   3.3要让swiper标签的高度变成和图片的高一样即可。

  4.图片标签

   4.1mode属性  让它渲染模式一下。

   4.2widthFix,让image的标签宽高和image标签的内容宽高都等比例的发生改变。

 

5.3.⼩程序内置 request API

      小程序内置request相当于js原生或jquery的AJAX,就是与服务器交换数据,小程序表示发起HTTPS网络请求,而ajax表示发起HTTP网络请求。其实我写过js原生或jquery的ajax,然后写配置,最后直接请求网络即可。而这个小程序不一样,只不过多了要证书的认可,所以必须要在小程序后台配置服务器域名,流程(小程序后台-开发-开发设置-服务器域名)进行配置即可,否则会出现不合法的服务域名,因为没有在服务器域名进行配置。虽然我没有写后端(比如php),但直接用别人的API即可。

     写小程序内置request之前,必须要在小程序后台进行配置服务器域名。

     首先在index/index.js,我直接写wx-request就会显示出来,这就是默认代码,有些人把部分代码可省略。

    var reqTask = wx.request({
        url: '',//请求接口的地址
        data: {},//可选,数据
        header: {'content-type':'application/json'},//默认值
        method: 'GET',//请求方式,GET和POST
        dataType: 'json',//数据格式
        success: (result) => {
            //就是比如result从ajax成功返回的数据
        },
        fail: () => {},//请求失败
        complete: () => {}//请求完成后执行
    });

    然后写省略并获取API的数据代码如下:

// 1. 就是用来发送异步请求获取API的数据
wx.request({
  url:'https://api.zbztb.cn/api/public/v1/home/swiperdata',
  success:(result) => {
       this.setData({
         swiperList:result.data.message//成功返回的数据,并显示数据
         })
       }
    });

    以上的这就是部分代码,还有关键的data及页面开始加载就会触发,完整的代码如下:

Page({
    //作为API的数据数组
   data:{
      swiperList[]
      },
    //页面开始加载 就会触发
   onLoad:function(options){
    // 1 发送异步请求获取轮播图数据
     wx.request({
       url: 'https://api-hmugo-web.itheima.net/api/public/v1/home/swiperdata',
       success: (result) => {
         this.setData({
          swiperList:result.data.message //成功返回的数据,并显示数据
         })    
       }
     });

}

});

     来看看微信开发者工具的AppData的数据情况,最后数据显示出来了,这个搞定! OK!

5.4.ES6的Promise

       这点玩意是我第一次碰到的,不知道ES6的Promise用来是什么,目的是什么?然后花了这个时间去查关于ES6的promise使用及讲解的资料。

       ES6的Promise就是一次性执行的异步操作,其实把多个ajax请求嵌套的情况变成一个ajax异步请求即可,比如说我需求的是一个页面需要三个ajax异步请求三个不同的url接口地址,那么它的思路就是比如三个ajax分别是一个A,一个B,一个C,先请求一个A的数据,成功拿到A的数据,然后传到是一个B的数据,这样是不是麻烦了,这样的代码是我们不愿看到。否则到时会影响性能,同时会让用户体验不好。

  ajax请求嵌套:

$.ajax({
    type: "method",
    url: "url",
    data: "data",
    dataType: "dataType",
    success: function (response) {
        var dada= response.dada
        $.ajax({
            type: "method",
            url: "url",
            data: "data",
            dataType: "dataType",
            success: function (response) {
                 $.ajax({
                     type: "method",
                     url: "url",
                     data: "data",
                     dataType: "dataType",
                     success: function (response) {
                         $.ajax({
                             type: "method",
                             url: "url",
                             data: "data",
                             dataType: "dataType",
                             success: function (response) {
                                 
                             }
                         });
                     }
                 });
            }
        });
    }
});

   是不是觉得这个很麻烦,代码就会非常繁琐,所以要优化一下这个ajax嵌套的东西。

   ES6的Promise是个异步请求的解决问题,它主要有pending-进行中、resolved-已完成、rejected-已失效。

   pending表示还没有得到结果;

   resolved表示得到了我们想要的结果,可以继续执行;

   rejected表示得到结果,但是不是我们想要的结果,拒绝执行;

   它的原理就是如果还在pending中,然后转变为resolved或rehected的状态,最后会执行对应的方法。注意:如果状态一旦改变,就无法再次改变状态。

   Promise的简单用法,代码如下:


let promise = new Promise ( (resolve, reject) => {
    if ( success ) {
        resolve(a) // pending 转换 resolved 为 已完成
    } else {
        reject(err) // pending转换 rejectd 为 已失效
    }
} )

  其实上new Promise()对象就会立即执行。

  然后试试对这个Promise对象打印出来,console.dir(Promise);

  以上的Promise对象看出来都是构造函数,reject、resolve等等方法,其中关键就是then、catch方法。其实上这个对象会有then、catch方法。

  说到then()和catch()方法

promise.then(
    () => { console.log('从promise里面获取到的数据') }
).catch(
    (err) => { console.log(err) }
)

      当在Promise对象有两个就是resolve、reject作为参数,其实这两个方法经常会在参数回调被用到。比如准确的思路就是执行到resolve()会触发then()方法、执行到reject()会触发catch()方法。如果要带数据的话,它们俩方法可以传入参数,比如resolve(result)或者reject(result),然后then()和catch()方法里面会带参数的函数,比如then(function(result){}) 或者 catch(function(result){}),这样就会得到result数据。

    以上的就是Promise基础讲解,当然不只是后面还有深入的东西。好了,回到这个实战项目情况。

   创建request/index.js文件夹,这个作为自己的接口帮助库文件夹。

   然后写个new Promise对象,代码如下:

//导出url API接口
export const request=(params) => {
   //返回new Promise对象
   return new Promise((resolve,reject) => {
       wx.request({
         ...params,//ES6,对象的扩展运算符
         success:(result) => {
              resolve(result);
         },
         fail:(err) => {
              reject(err);
          }
        )};
    })
} 

             

 然后在index/index.js文件夹,代码如下:

//0 引入 用来发送请求的方法
import { request } from "../../request/index.js";
Page({
  data: {
    //轮播图数组
    swiperList:[],
  },
  // 页面开始加载 就会触发
onLoad: function(options) {
   request({ url:'https://api.zbztb.cn/api/public/v1/home/swiperdata' })
   .then(result => {
        this.setData({
            swiperList:result.data.message
          })
       })

},

 刚才我讲解了这些基础,看到这些代码,差不多摸索出来了。另外,...params其实就是ES6的三点扩展运算符,比如我写let a={url:'www.qq.com'},然后...a打印为url:'www.qq.com'。以上的request/index.js和index/index.js都有相互调用或回调的函数。

最后到微信开发者工具的AppData是否数据出来。

这样OK!

实战项目主要是为了提高自己技术能力。当不懂或没接触这些东西的状态下,看代码,练代码就完事,这个是不对的,对自己没什么好处。所以,当遇到不懂这些东西时,必须要找网上关于讲解资料并摸索它,然后觉得自己能理解它,这才是有效果。

下一期就是小程序分类页面-three

不断更新中.....

欢迎各位大佬评论、点赞和收藏!Thanks

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐