教程
各位戰友,早上好,今天是我們的第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>