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