[解读小程序]生活工具集合

本文详细解析了一款基于微信小程序的生活工具——空气质量查询应用。包括模块化编程实践、页面布局及交互实现,以及如何处理网络请求和展示查询结果。

[解读小程序]生活工具集合

分析的程序来源:
http://www.jianshu.com/p/3d59e3ef4a7b
作者: 于连林520wcf
github地址: https://github.com/yll2wcf/wechat-weapp-lifeTools

作者目前目前只加了一个空气质量查询的功能, 其实作者自己的文章已经写的很详细了.不过为了让其变成自己的知识, 再分析一下.

最终效果图

空气质量查询页面

已知未解决的问题

多次快速重复点击查询按钮, 会发起多次请求, 打开多个结果页面.

该问题已经反馈给作者了.

空气质量查询页面

作者将所有的css样式都写在了app.wxss中. 作者的初衷是为了每个页面样式统一, app.wxss中的样式可以被其他所有界面直接使用. 但是按照官方demo的做法. 只是把一些公共的css样式写到了app.wxss中, 每个页面还是有单独的样式定义.

app.wxss

/**app.wxss**/
page {
  background-color: #fbf9fe; 
  height: 100%;
}
/**容器 flex-direction: column 表示元素垂直排列*/
.container {
  min-height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: 200rpx 0rpx;
} 

 /**page 用于页面根标签 overflow超出范围的裁剪**/
.page {
    min-height: 100%;
    flex: 1;
    background-color: #FBF9FE;
    font-size: 32rpx;
    font-family: -apple-system-font,Helvetica Neue,Helvetica,sans-serif;
    overflow: hidden;
}
 /**页面中的input的组件**/
.page input{
    padding: 20rpx 30rpx;
    background-color: #fff;
}

/**段落*/
.section{
    margin-bottom: 80rpx;
}
/**段落标题*/
.section__title{
    margin-bottom: 16rpx;
    padding-left: 30rpx;
    padding-right: 30rpx;
}

/**button范围*/
.btn-area{
    padding: 0 30rpx;
}
/**button*/
.btn-area button{
    margin-top: 20rpx;
    margin-bottom: 20rpx;
}

这里的样式很简单, 作者的注释也很好.

air_quality.wxml

直接看空气质量查询的页面 air_quality.wxml

<view class="page">
    <view class="container">
        <view class="section">
            <view class="section__title">你要查询的是:{{inputValue}}</view>
            <input  bindinput="bindKeyInput" placeholder="请输入要查询的城市名称" value="{{inputValue}}"/>
        </view>
        <view class="btn-area">
        <button type="primary" loading="{{loading}}"
                disabled="{{disabled}}" bindtap="search"> 查询
        </button>
        </view>
        <modal class="modal" hidden="{{modalHidden}}" no-cancel bindconfirm="modalChange" bindcancel="modalChange">
            {{modalErrorText}}
        </modal>
    </view>
</view>

页面比较简单. 页面结构也是page -> container -> section. 值得注意的是button初始时disabled ,并且配置了loading.
这里有个modal组件文档-modal.
这个组件叫做模态对话框. 什么是模态呢? 就是它显示的时候, 它占据焦点, 它之外的区域不可操作.
小程序提供了两种形式的模态对话框: 有确定和取消按钮的和只有确定按钮的.

air_quality.js

模块化

首先引入外部模块.

const Constant = require( '../../common/constant.js' );
const util = require( '../../common/utils.js' );

我们可以将一些公共的代码抽离成为一个单独的 js 文件,作为一个模块。模块只有通过 module.exports 或者 exports 才能对外暴露接口。文档-模块化

constant.js中保存了一些常量

// API_KEY
const API_KEY="9dc7ab2f8993b0b215ad8c550e1f4ebe";
//空气质量检测的URL参考 
const AIR_QUALITY_URL="http://apis.baidu.com/apistore/aqiservice/aqi";

module.exports = { //对外暴露接口
    AIR_QUALITY_URL: AIR_QUALITY_URL,
    API_KEY:API_KEY
}

utils.js中定义了createURL()用来生成拼接在url中的参数

/*链接和参数*/
function createURL( url, obj ) {
  let props = "";
  let resultURL="";  //结果
  for(let p in obj){  //遍历enumerable对象
    if(obj[p])
    props+= "&"+p + "=" + obj[p]; //拼接
  }
  resultURL=url+"?"+props.substr(1);
  console.log(resultURL);
  return resultURL;  
}

module.exports = { //对外暴露接口
  createURL: createURL
}

初始化数据

data: {  //状态机数据
    inputValue: "", //输入的内容
    loading: false, //加载状态
    disabled: true, //按钮是否可用
    modalHidden: true, //modal弹出状态
    modalErrorText:"请求失败,请检测网络"//modal弹出提示文字
  },

作者的注释很清晰.

处理事件

输入框事件. 初始时查询button是disabled的, 当我们输入内容时button改变为可点击状态.

//输入框绑定的事件
  bindKeyInput: function( e ) {
    let value = e.detail.value; //输入框的值
    //输入框,当输入的值大于0的时候按钮可用
    this.setData( {
      inputValue: value,
      disabled: !value.length > 0 //改变button状态
    });
  },

button的tap事件. 点击button, 显示loading标识, 请求网络查询空气质量, 成功之后跳转到result页面url:util.createURL( "./result", res.data.retData), 这里给url赋值就是利用了require引入的模块中的方法去创建页面路由链接的.

search: function( e ) {
    //查询按钮
    this.setData( {
      loading: true
    });
    let that = this;//保留page函数中object的引用
    //联网
    wx.request( {
      url: Constant.AIR_QUALITY_URL,
      header: {
        "Content-Type": "application/json",
        "apikey": Constant.API_KEY
      },
      data: {
        "city": this.data.inputValue
      },
      //res = {data: '开发者服务器返回的内容'}
      success: function( res ) {
        console.log( res.data );
        if( res.data.errNum === 0 ) { //成功
          wx.navigateTo( {  //跳转地址可以写相对路径,绝对路径一定要以/ 开头 这样写pages/air_quality/result是错误的
            url:util.createURL( "./result", res.data.retData),
          });
        }else{
          that.setData( { //这个位置应该用page的引用调用
            modalHidden: false,
            modalErrorText:res.data.retMsg
          });
        }

      },
      //失败,弹出modal
      fail: function() {
        //console.log(this); //这时候的this不是Page了
        that.setData( { //这个位置应该用page的引用调用
          modalHidden: false,
           modalErrorText:"请求失败,请检测网络"
        })
      },
      //无论成功与失败,loading都取消
      complete: function() {
        that.setData( {
          loading: false
        })
      }
    });
  },
  modalChange: function() {
    this.setData( {
      modalHidden: true
    })
  }

查询结果页面

<View class="page">

    <view class="container" style="align-items: center">
        <icon class="section" type="success" size="70"></icon>
        <view class="text_area">
        <text >
            查询城市: {{city}}
        </text>
        <text>
            空气质量指数: {{aqi}}
        </text>
        <text >
            空气质量等级: {{level}}
        </text>
        <text>
            主要污染物: {{core}}
        </text>
       <text >
            查询时间: {{time}}
        </text>
        </view>
    </view>
</View>

wxml中没什么特别的,都是一些数据绑定.

Page({
  data:{
    //主要污染物有可能没有,默认值无
    core:"无"
  },
  onLoad:function(options){
    console.log("result");
    // 页面初始化 options为页面跳转所带来的参数
    console.log(options);
    this.setData(options);
  }
})

这里有点意思的是data对象只给了core的默认值. 其他的值全部从options中获得. 这样其实会存在问题. 如果查得到还好说, 自然会有那些字段. 如果没查到, 就什么都显示不了.

代码基本的都分析完成了. 作者的文章里面关于css选择器的说法还是讲的挺好的. 我摘录了下来: css优先级

原则一: 继承不如指定
原则二: #id > .class > 标签选择符
原则三:越具体越强大
原则四:标签#id >#id ; 标签.class > .class

CSS优先级权重计算法

CSS优先级包含四个级别(标签内选择符,ID选择符,Class选择符,元素选择符)以及各级别出现的次数!

根据这四个级别出现的次数计算得到CSS的优先级。

CSS优先级的计算规则如下:
* 元素标签中定义的样式(Style属性),加1,0,0,0
* 每个ID选择符(如 #id),加0,1,0,0
* 每个Class选择符(如 .class)、每个属性选择符(如 [attribute=])、每个伪类(如 :hover)加0,0,1,0
* 每个元素选择符(如p)或伪元素选择符(如 :firstchild)等,加0,0,0,1
然后,将这四个数字分别累加,就得到每个CSS定义的优先级的值,
然后从左到右逐位比较大小,数字大的CSS样式的优先级就高。

例子:
css文件或style中如下定义:
1. h1 {color: red;}
一个元素选择符,结果是0,0,0,1
2. body h1 {color: green;}
两个元素选择符,结果是 0,0,0,2
3. h2.grape {color: purple;}
一个元素选择符、一个Class选择符,结果是 0,0,1,1
4. li#answer {color: navy;}
一个元素选择符,一个ID选择符,结果是0,1,0,1
元素的style属性中如下定义:
h1 {color: blue;}
元素标签中定义,一个元素选择符,结果是1,0,0,1

如此以来,h1元素的颜色是蓝色。
注意:
1、!important声明的样式优先级最高,如果冲突再进行计算。
2、如果优先级相同,则选择最后出现的样式。
3、继承得到的样式的优先级最低。

当前位置由于 class page中指定了font-size 标签优先级不如class高, 所以不生效

基本上算是讲解完了. 等待作者更新.

the end.

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值