小程序編程第7課

教程

各位戰友,早上好,今天是我們的第7課,這節課我們要做一個:自動答疑小程序

自動答疑的功能,我們經常都能看到,比如我們撥打10086,系統就會提示你,讓你輸入對應的數字獲取對應的服務。

騰訊客服把這一功能用到了極致,你可以看這張圖片
在這裏插入圖片描述

我隨便拋出了一個關鍵字,然後騰訊客服就讓我回復對應的數字,當我回復了一個數字,騰訊客服就自動回覆對應的解決方案

我們這節課也是要做一個類似的小程序,我們先來看看效果

自動答疑小程序演示

當你輸入1再點確認,它就提示我的名字。當我輸入2,再點確認它就會告訴我出生地,當我輸入3再點確認,它就告訴我要去西天取經
當我輸入4的時候,或者其它任何字符,它就會提示我:讓我輸入1-3的數字

實現這個小程序的核心是什麼呢?

那就是把用戶輸入的數字和問題編號匹配起來。

我們可以用之前學到的if…else…語句實現,但是我們這節課用一個新的語句實現,那就是switch語句

這個語句長這樣

switch (expression) {
  case value1:
    // 當 expression 的結果與 value1 匹配時,執行此處語句
    [break;]
  case value2:
    // 當 expression 的結果與 value2 匹配時,執行此處語句
    [break;]
  ...
  case valueN:
    // 當 expression 的結果與 valueN 匹配時,執行此處語句
    [break;]
  [default:
    // 如果 expression 與上面的 value 值都不匹配,執行此處語句
    [break;]]
}

這個expression的意思是表達式,什麼是表達式?3+2-5就是一個表達式 a+b也是一個表達式,總而言之,就是一個能夠運算出結果的一個語句,不用糾結這個,反正我們知道表達式會得到一個結果

表達式的結果如果與某一個case匹配的話,那麼就會執行case後面的語句。什麼時候結束呢?遇到break就結束,或者執行完後面的所有代碼再結束

這對應了我們剛纔那個答疑小程序中,輸入1就彈出1號問題的答案。輸入2就彈出2號問題的答案。

這個default是什麼意思呢?也就是說,當所有case都沒有匹配上的時候,那就執行這個default後面的語句

也就是我們輸入1,2,3之外的字符時,那麼就會彈出請輸入1-3的數字

所以本節課的目標就一個:理解switch語句

話不多說,我們還是在實踐中來理解吧!

首先如往常一樣,重新創建一個項目,選擇測試號,點擊新建

打開index.js文件,修改第7行的代碼爲如下代碼,然後保存

 num: 0,

打卡Index.wxml文件,刪除第11行代碼,也就是如下代碼

<text class="user-motto">{{motto}}</text>

在第10行後面增加如下幾行代碼,保存一下

<view>我是自動答疑助手,請輸入你想要詢問的問題編號</view>
<view>1,我是誰?</view>
<view>2,我來自哪裏?</view>
<view>3,我將要去哪?</view>
<input bindinput="bindInput" placeholder="請輸入1-3的數字" type="number"></input>
<button type="primary" bindtap="tellMe">tell me</button>

現在你可以看到屏幕上出現了答疑界面

打開index.js文件,在第53行後面增加逗號
然後增加如下代碼,保存一下

bindInput: function(e) {
 this.setData({
   num: Number(e.detail.value)
 })
},
tellMe: function(e){
	
}

你可以看到,bindInput是一個函數,我們把用戶輸入的內容存到num裏面了

我們期望的是當用戶輸入之後,點擊按鈕要彈出對應的答案。

這個tellMe函數就是用戶點擊按鈕之後會被觸發的執行的函數

目前函數裏面還沒有任何代碼,也就是大括號間是沒有代碼的,所以執行之後沒有任何效果。

我們現在就是要完善這個函數

我們先考慮要定義幾個變量,用戶輸入的數字和提示語

現在我們先定義兩個變量

let num = this.data.num
let tip = ''

現在我們要實現的最關鍵的一步來了,那就是利用switch語句實現用戶輸入的數字和問題編號匹配

怎麼做呢?

我們先把語句複製過來,然後我們再套東西進去

去掉中括號和省略號

然後現在這個tellMe函數長這樣

tellMe: function(e){
 let num = this.data.num
 let tip = ''
 switch (expression) {
   case value1:
     // 當 expression 的結果與 value1 匹配時,執行此處語句
     break;
   case value2:
     // 當 expression 的結果與 value2 匹配時,執行此處語句
     break;
   case valueN:
     // 當 expression 的結果與 valueN 匹配時,執行此處語句
     break;
   default:
     // 如果 expression 與上面的 value 值都不匹配,執行此處語句
     break;
 }
}

我們先把expression給換掉,這裏該放什麼東西呢?

因爲我們要拿用戶輸入的數字和編號比較,用戶輸入的是一個數字,而我們的問題編號卻是多個,我們的問題編號以後還可以增加,所以是任意個。

對應這個switch語句,那就是expression只有一個,但case有任意個

所以我們把用戶輸入的數字拿來替換expression,也就是這樣

tellMe: function(e){
 let num = this.data.num
 let tip = ''
 switch (num) {  // 注意:變動的地方在這!
   case value1:
     // 當 expression 的結果與 value1 匹配時,執行此處語句
     break;
   case value2:
     // 當 expression 的結果與 value2 匹配時,執行此處語句
     break;
   case valueN:
     // 當 expression 的結果與 valueN 匹配時,執行此處語句
     break;
   default:
     // 如果 expression 與上面的 value 值都不匹配,執行此處語句
     break;
 }
}

接下來我們把case 後面的value也給換掉,

tellMe: function(e){
 let num = this.data.num
 let tip = ''
 switch (num) {  // 注意:變動的地方在這!
   case 1:
     // 當 expression 的結果與 value1 匹配時,執行此處語句
     break;
   case 2:
     // 當 expression 的結果與 value2 匹配時,執行此處語句
     break;
   case 3:
     // 當 expression 的結果與 valueN 匹配時,執行此處語句
     break;
   default:
     // 如果 expression 與上面的 value 值都不匹配,執行此處語句
     break;
 }
}

那現在當用戶輸入1的時候,我們匹配到case1了,那應該要執行什麼代碼呢?

那就是給tip變量賦值

如下代碼

tellMe: function (e) {
  let num = this.data.num
  let tip = ''
  switch (num) {
    case 1:
      // 當 expression 的結果與 value1 匹配時,執行此處語句
      tip = '你是劉良'
      break;
    case 2:
      // 當 expression 的結果與 value2 匹配時,執行此處語句
      tip = '重慶'
      break;
    case 3:
      // 當 expression 的結果與 valueN 匹配時,執行此處語句
      tip = '西天取經'
      break;
    default:
      // 如果 expression 與上面的 value 值都不匹配,執行此處語句
      tip = '請輸入1到3的數字'
      break;
  }
}

這裏有多個註釋,你如果覺得太乾擾了,那你可以刪除掉。

給tip賦值之後,我們的程序遇到了break,break在英語裏面有多個意思,這裏叫打斷,或中斷

也就是說,如果遇到了break語句之後,那就不執行接下來的語句了,直接跳出這個switch語句

這裏暫時理解不了沒關係,待會我們還會演示

你可以看到這個break後面有分號,你可以寫也可以不寫。

這些所有語句後面都可以加上分號,都是可以選,想寫就寫,不影響結果

比如,我在這個賦值語句後面加上分號,不會報錯,結果也不會改變的。這和空格差不多,大多數地方多一個空格少一個空格都不影響結果的

賦值完tip之後,我們還要做什麼呢?

我們要彈出提示框,告訴用戶答案

在這個switch語句的結束大括號後面添加如下代碼

wx.showModal({
  title: tip,
  showCancel: false,
  confirmText: '知道了'
})

注意,我們的代碼實際上是有層級的,在不同大括號裏面的完全不同,一個大括號的意思就是這個範圍屬於某個語句的管轄區域(作用域)。

如果我把這個提示框放到外面這個大括號裏面,那就不對了。

我們這個提示框是屬於這個tellMe函數管轄的,之後我們有一堂課會專門講這個東西,叫做作用域。所以現在不理解沒關係!先儘量跟着寫對即可。

好,保存一下,我們看看效果。

分別輸入1,2,3,4體驗一下,看看結果是不是對的

我們可以看到結果,已經正確了。

現在,讓我們來思考一下,要是我不小心忘了寫下方這行代碼後面的break語句會發生什麼呢?

tip = '你是劉良'

你可以看到,當我們輸入1的時候,彈出來的提示是不正確的。

這也說明了,當我們不寫break的時候,那麼執行完如下代碼之後

tip = '你是劉良'

它又去執行了一個

tip = '重慶'

也就是把變量更改了,然後才遇到break,最後退出switch語句,於是我們就看到了錯誤的提示

CTRL+Z撤銷一下,把break變回來,保存一下

這個default我們可不可以不寫呢?

可以的,這就相當於默認值,沒有默認值是沒有關係的。我們可以試試

當我們刪除下面三行代碼的時候,我們輸入1,2,3之外的字符時,就是一個空提示,因爲tip沒有被改變,是一個空字符串

default:
tip = '請輸入1到3的數字'
break;

作業

這堂課的作業是什麼呢?

這堂課的作業是先開發出這個答疑小程序,並截圖發到羣裏。

然後有多餘的時間可以模仿做一個能夠根據用戶輸入的數字,用英文提示星期幾

像這樣

輸入星期幾,提示英文星期幾

今天課程所有的代碼都在我發送出來的鏈接中,裏面有文字教程還有作業參考答案

附件

答疑小程序源碼

index.js

//index.js
//獲取應用實例
const app = getApp()

Page({
  data: {
    num: 0,
    userInfo: {},
    hasUserInfo: false,
    canIUse: wx.canIUse('button.open-type.getUserInfo')
  },
  //事件處理函數
  bindViewTap: function() {
    wx.navigateTo({
      url: '../logs/logs'
    })
  },
  onLoad: function () {
    if (app.globalData.userInfo) {
      this.setData({
        userInfo: app.globalData.userInfo,
        hasUserInfo: true
      })
    } else if (this.data.canIUse){
      // 由於 getUserInfo 是網絡請求,可能會在 Page.onLoad 之後才返回
      // 所以此處加入 callback 以防止這種情況
      app.userInfoReadyCallback = res => {
        this.setData({
          userInfo: res.userInfo,
          hasUserInfo: true
        })
      }
    } else {
      // 在沒有 open-type=getUserInfo 版本的兼容處理
      wx.getUserInfo({
        success: res => {
          app.globalData.userInfo = res.userInfo
          this.setData({
            userInfo: res.userInfo,
            hasUserInfo: true
          })
        }
      })
    }
  },
  getUserInfo: function(e) {
    console.log(e)
    app.globalData.userInfo = e.detail.userInfo
    this.setData({
      userInfo: e.detail.userInfo,
      hasUserInfo: true
    })
  },
  bindInput: function(e) {
    this.setData({
      num: Number(e.detail.value)
    })
  },
  tellMe: function(e){
    let num = this.data.num
    let tip = ''
    switch(num) {
      case 1:
        tip = '你是劉良'
        break
      case 2:
        tip = '重慶'
        break
      case 3:
        tip = '西天取經'
        break
      default:
        tip = '請輸入1到3的數字'
    }
    wx.showModal({
      title: tip,
      showCancel: false,
      confirmText: '知道了'
    })
  }
})

index.wxml

<!--index.wxml-->
<view class="container">
  <view class="userinfo">
    <button wx:if="{{!hasUserInfo && canIUse}}" open-type="getUserInfo" bindgetuserinfo="getUserInfo"> 獲取頭像暱稱 </button>
    <block wx:else>
      <image bindtap="bindViewTap" class="userinfo-avatar" src="{{userInfo.avatarUrl}}" mode="cover"></image>
      <text class="userinfo-nickname">{{userInfo.nickName}}</text>
    </block>
  </view>
  <view class="usermotto">
    <view>我是自動答疑助手,請輸入你想要詢問的問題編號</view>
    <view>1,我是誰?</view>
    <view>2,我來自哪裏?</view>
    <view>3,我將要去哪?</view>
    <input bindinput="bindInput" placeholder="請輸入1-3的數字" type="number"></input>
    <button type="primary" bindtap="tellMe">tell me</button>
  </view>
</view>

作業答案

index.js

//index.js
//獲取應用實例
const app = getApp()

Page({
  data: {
    num: 0,
    userInfo: {},
    hasUserInfo: false,
    canIUse: wx.canIUse('button.open-type.getUserInfo')
  },
  //事件處理函數
  bindViewTap: function() {
    wx.navigateTo({
      url: '../logs/logs'
    })
  },
  onLoad: function () {
    if (app.globalData.userInfo) {
      this.setData({
        userInfo: app.globalData.userInfo,
        hasUserInfo: true
      })
    } else if (this.data.canIUse){
      // 由於 getUserInfo 是網絡請求,可能會在 Page.onLoad 之後才返回
      // 所以此處加入 callback 以防止這種情況
      app.userInfoReadyCallback = res => {
        this.setData({
          userInfo: res.userInfo,
          hasUserInfo: true
        })
      }
    } else {
      // 在沒有 open-type=getUserInfo 版本的兼容處理
      wx.getUserInfo({
        success: res => {
          app.globalData.userInfo = res.userInfo
          this.setData({
            userInfo: res.userInfo,
            hasUserInfo: true
          })
        }
      })
    }
  },
  getUserInfo: function(e) {
    console.log(e)
    app.globalData.userInfo = e.detail.userInfo
    this.setData({
      userInfo: e.detail.userInfo,
      hasUserInfo: true
    })
  },
  bindInput: function(e) {
    this.setData({
      num: Number(e.detail.value)
    })
  },
  tellMe: function(e){
    let num = this.data.num
    let tip = ''
    switch(num) {
      case 1:
        tip = 'Today is Monday'
        break
      case 2:
        tip = 'Today is Tuesday'
        break
      case 3:
        tip = 'Today is Wednesday'
        break
      case 4:
        tip = 'Today is Thursday'
        break
      case 5:
        tip = 'Today is Friday'
        break
      case 6:
        tip = 'Today is Saturday'
        break
      case 7:
        tip = 'Today is Sunday'
        break
      default:
        tip = '請輸入1到7的數字'
    }
    wx.showModal({
      title: tip,
      showCancel: false,
      confirmText: '知道了'
    })
  }
})

index.wxml

<!--index.wxml-->
<view class="container">
  <view class="userinfo">
    <button wx:if="{{!hasUserInfo && canIUse}}" open-type="getUserInfo" bindgetuserinfo="getUserInfo"> 獲取頭像暱稱 </button>
    <block wx:else>
      <image bindtap="bindViewTap" class="userinfo-avatar" src="{{userInfo.avatarUrl}}" mode="cover"></image>
      <text class="userinfo-nickname">{{userInfo.nickName}}</text>
    </block>
  </view>
  <view class="usermotto">
    <view>輸入數字,點擊按鈕,我用英文告訴你星期幾</view>
    <input bindinput="bindInput" placeholder="請輸入一個1到7的數字" type="number"></input>
    <button type="primary" bindtap="tellMe">tell me</button>
  </view>
</view>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章