# 开发 \| 只需 10 分钟，教你做一款查询类小程序

- 作者：知晓程序
- 发布时间：2017-07-20 20:00
- 原文：https://www.ifanr.com/minapp/875881

![](https://s3.ifanr.com/wp-content/uploads/2017/07/minapp-dev-final-feature.jpg)

文 \| 心智极客

本文从一个简单的手机归属地查询实现入手，来帮助你入门小程序开发。

基本功能如下：

- 查询手机归属地
- 根据历史记录查询
- 手机位数校验

我们来看一下小程序的最终效果：

![](https://s3.ifanr.com/wp-content/uploads/2017/07/minapp-phone-query.jpg)

### 创建空白项目

按照以下步骤，在开发者工具中新建一个空白项目：

- AppID 可选择无
- **取消选择选择创建 quick start 项目。**在这里，我们创建空白项目，目的是加深对小程序结构的理解。

### 基本配置

首先，我们需要创建全局配置文件 `app.json`。

```
// /app.json
{
  <span class="hljs-attr">"pages"</span>:[
    <span class="hljs-string">"pages/index/index"</span>
  ]
}
```

**在全局配置文件中，我们定义了一个页面。**保存之后，将会自动生成 index 页面的基本目录。

```
pages
└── index
    ├── index<span class="hljs-selector-class">.js</span>    <span class="hljs-comment">// 页面业务逻辑</span>
    ├── index<span class="hljs-selector-class">.json</span>  <span class="hljs-comment">// 页面配置</span>
    ├── index<span class="hljs-selector-class">.wxml</span>  <span class="hljs-comment">// 页面视图</span>
    └── index<span class="hljs-selector-class">.wxss</span>  <span class="hljs-comment">// 页面样式</span>
```

现在，还缺少一个应用的入口文件，用来声明和注册小程序本体。

```
// /<span class="hljs-keyword">app</span>.js
<span class="hljs-keyword">App</span>({
})
```

`App()` 方法用于描述小程序的全局逻辑，同时会声明和注册一个小程序实例。**到这一步，小程序项目目录初始化工作就完成了。**

### 页面配置

首先，我们来为页面添加顶部导航文字。打开 `index` 文件夹下的 `index.json` 文件，编写以下代码并保存：

```
// /pages/index/index.json
{
  <span class="hljs-attr">"navigationBarTitleText"</span>: <span class="hljs-string">"手机归属地查询"</span>
}
```

### 查询逻辑编写

接下来是查询模块的编写。首先是视图层代码：

```
<span class="xml">// /pages/index/index.wxml
<span class="hljs-comment"><!--查询--></span>
<span class="hljs-tag"><<span class="hljs-name">view</span>></span>
  <span class="hljs-tag"><<span class="hljs-name">text</span>></span>请输入查询内容<span class="hljs-tag"></<span class="hljs-name">text</span>></span>
  <span class="hljs-tag"><<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"number"</span> <span class="hljs-attr">bindinput</span>=<span class="hljs-string">"bindPhoneInput"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"</span></span></span><span class="hljs-template-variable">{{ phoneNumber }}</span><span class="xml"><span class="hljs-tag"><span class="hljs-string">"</span>/></span>
  <span class="hljs-tag"><<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"primary"</span> <span class="hljs-attr">bindtap</span>=<span class="hljs-string">"queryPhoneInfo"</span> <span class="hljs-attr">disabled</span>=<span class="hljs-string">"</span></span></span><span class="hljs-template-variable">{{ disabled }}</span><span class="xml"><span class="hljs-tag"><span class="hljs-string">"</span>></span>查询<span class="hljs-tag"></<span class="hljs-name">button</span>></span>
<span class="hljs-tag"></<span class="hljs-name">view</span>></span></span>
```

在这段代码中，我们实现了：

- `bindinput` 用于绑定键盘输入事件。**用户输入时，将会调用绑定的 `bindPhoneInput` 函数。**
- `bindtap` 用于绑定点击事件。**用户点击按钮后，将会调用绑定的 `queryPhoneInfo` 函数。**
- 按钮是否可点击，取决于 `disabled` 的值。

接下来，是具体的功能实现。首先，**我们把手机归属地查询的功能封装到全局业务文件 `app.js` 中**，方便不同页面调用。

```
// /app.js
App({
  /**
   * 获取手机归属地信息
   */
  getPhoneInfo(phoneNum, callback) {
    wx.request({
      url:
      <span class="hljs-string">'https://www.iteblog.com/api/mobile.php?mobile='</span> + phoneNum,
      header: {
        <span class="hljs-string">'content-type'</span>: <span class="hljs-string">'application/json'</span>
      },
      success: function (res) {
        callback(res.data);
      }
    })
  }
})
```

需要注意的是：

- 小程序使用微信提供的 `wx.request` 接口来发送请求。
- 该函数接受两个参数，一个是手机号，另外一个则是回调函数，用来处理查询的结果。

在页面里，实现刚才定义的两个事件：

```
// /pages/index/index.js
<span class="hljs-keyword">var</span> app = getApp();
Page({

  <span class="hljs-comment">/**
   * 页面的初始数据
   */</span>
  <span class="hljs-keyword">data</span>: {
    phoneNumber: <span class="hljs-literal">null</span>, <span class="hljs-comment">// 查找的手机号</span>
    phoneInfo: <span class="hljs-literal">null</span>, <span class="hljs-comment">// 查询结果</span>
    disabled: <span class="hljs-literal">true</span>  <span class="hljs-comment">// 默认不可查询</span>
  },

   <span class="hljs-comment">/**
   * 键盘输入手机号事件处理
   */</span>
  bindPhoneInput(event){
    <span class="hljs-keyword">this</span>.setData({
      phoneNumber: event.detail.value,  <span class="hljs-comment">// 将用户输入的手机号与页面变量进行绑定</span>
      phoneInfo: <span class="hljs-literal">null</span>   <span class="hljs-comment">//  清空过往查询结果</span>
    })
    <span class="hljs-keyword">this</span>.setDisabled();
  },

  <span class="hljs-comment">/**
   * 验证手机是否为 11 位
   */</span>
  setDisabled() {
    <span class="hljs-keyword">this</span>.setData({
      disabled: (<span class="hljs-keyword">this</span>.<span class="hljs-keyword">data</span>.phoneNumber && <span class="hljs-keyword">this</span>.<span class="hljs-keyword">data</span>.phoneNumber.toString().length === <span class="hljs-number">11</span>) ? <span class="hljs-literal">false</span> : <span class="hljs-literal">true</span>
    })
  },

  <span class="hljs-comment">/**
   * 用户点击查询处理
   */</span>
  queryPhoneInfo() {
    app.getPhoneInfo(<span class="hljs-keyword">this</span>.<span class="hljs-keyword">data</span>.phoneNumber, <span class="hljs-keyword">data</span> => <span class="hljs-keyword">this</span>.setData({
      phoneInfo: <span class="hljs-keyword">data</span>
    }));
  }
})
```

几个需要注意的点：

- `data` 用于管理该页面的数据。
- `this.setData()` 方法用于设置 data 的属性。**直接使用 `this.data.phoneInfo` 是无法改变页面状态的。**
- **在页面中调用 `app.js` 内的方法，需要先使用 `getApp()` 函数进行实例化**，然后通过实例来访问方法。

### 查询结果显示

接下来在视图里面显示查询结果

```
<span class="xml"><!-- /pages/index/index.wxml -->
<span class="hljs-comment"><!--查询结果--></span>
<span class="hljs-tag"><<span class="hljs-name">view</span>></span>

  <span class="hljs-tag"><<span class="hljs-name">view</span> <span class="hljs-attr">wx:if</span>=<span class="hljs-string">"</span></span></span><span class="hljs-template-variable">{{ phoneInfo }}</span><span class="xml"><span class="hljs-tag"><span class="hljs-string">"</span>></span>
   <span class="hljs-tag"><<span class="hljs-name">text</span>></span>查询结果为：<span class="hljs-tag"></<span class="hljs-name">text</span>></span>
   <span class="hljs-comment"><!--手机号存在--></span>
   <span class="hljs-tag"><<span class="hljs-name">text</span> <span class="hljs-attr">wx:if</span>=<span class="hljs-string">"</span></span></span><span class="hljs-template-variable">{{phoneInfo.ret === 0}}</span><span class="xml"><span class="hljs-tag"><span class="hljs-string">"</span>></span>
   </span><span class="hljs-template-variable">{{phoneInfo.operator}}</span><span class="hljs-template-variable">{{phoneInfo.province}}</span><span class="hljs-template-variable">{{phoneInfo.city}}</span><span class="xml">
   <span class="hljs-tag"></<span class="hljs-name">text</span>></span>
   <span class="hljs-comment"><!--手机号不存在--></span>
  <span class="hljs-tag"><<span class="hljs-name">text</span> <span class="hljs-attr">wx:else</span>></span> </span><span class="hljs-template-variable">{{phoneInfo.msg}}</span><span class="xml"> <span class="hljs-tag"></<span class="hljs-name">text</span>></span>
  <span class="hljs-tag"></<span class="hljs-name">view</span>></span>
<span class="hljs-tag"></<span class="hljs-name">view</span>></span></span>
```

在这里，**我们使用 `wx:if` 与 `wx:else`，来方便地根据查询结果来切换视图**。

### 最近搜索功能的实现

最后是最近功能记录的功能实现。首先是视图层的代码：

```
<span class="xml"><span class="hljs-comment"><!-- 最近搜索 --></span>
<span class="hljs-tag"><<span class="hljs-name">view</span>></span>
  <span class="hljs-tag"><<span class="hljs-name">text</span>></span>最近搜索<span class="hljs-tag"></<span class="hljs-name">text</span>></span>
  <span class="hljs-tag"><<span class="hljs-name">view</span>></span>
    <span class="hljs-tag"><<span class="hljs-name">view</span> <span class="hljs-attr">wx:for</span>=<span class="hljs-string">"</span></span></span><span class="hljs-template-variable">{{ historyList }}</span><span class="xml"><span class="hljs-tag"><span class="hljs-string">"</span>  <span class="hljs-attr">bindtap</span>=<span class="hljs-string">"selectHistory"</span> <span class="hljs-attr">data-number</span>=<span class="hljs-string">"</span></span></span><span class="hljs-template-variable">{{item}}</span><span class="xml"><span class="hljs-tag"><span class="hljs-string">"</span>></span>
       </span><span class="hljs-template-variable">{{item}}</span><span class="xml">
    <span class="hljs-tag"></<span class="hljs-name">view</span>></span>
  <span class="hljs-tag"></<span class="hljs-name">view</span>></span>
<span class="hljs-tag"></<span class="hljs-name">view</span>></span></span>
```

在这段代码中，我们实现了：

- 遍历 `historyList` 数组
- 用户点击某一记录时候，触发 `selectHistory` 事件
- 将每条手机号保存到 `data-number` 中，`selectHistory` 就可以获取对应的手机号了

接下来，是逻辑代码编写：

```
<span class="hljs-comment">// pages/index/index.js</span>

  <span class="hljs-comment">/**
   * 将搜索记录添加到缓存
   */</span>
  addQueryHistory(phoneNumber) {
    <span class="hljs-keyword">var</span> historyList = wx.getStorageSync(<span class="hljs-string">'historyList'</span>) || [];
    <span class="hljs-keyword">if</span> (historyList.indexOf(phoneNumber) === <span class="hljs-number">-1</span>) {
      historyList.unshift(phoneNumber);
      wx.setStorageSync(<span class="hljs-string">'historyList'</span>, historyList);
    }
    <span class="hljs-keyword">this</span>.setData({
      historyList: historyList
    })
  },

  <span class="hljs-comment">/**
   * 页面加载后，从缓存中读取最近搜索列表
   */</span>
  onLoad: function () {
    <span class="hljs-keyword">this</span>.setData({
      historyList: wx.getStorageSync(<span class="hljs-string">'historyList'</span>) || []
    })
  },

  <span class="hljs-comment">/**
   * 用户点击记录之后，将其添加到输入框中
   */</span>
  selectHistory(event) {
    <span class="hljs-keyword">this</span>.setData({
      phoneNumber: event.currentTarget.dataset.number,
      disabled: <span class="hljs-literal">false</span>
    })
  }
```

最后，我们只需要稍微美化下界面，小程序就完成了。

原文地址：http://www.jianshu.com/p/d062adec4f9c

**关注「知晓程序」公众号，在微信后台回复「源码」，获取这个小程序的项目源代码。**

![zxcx&#95;0208](https://s3.ifanr.com/wp-content/uploads/2017/02/zxcx_0208.png)
