
一、案例描述
设计一个微信小程序,初始页面显示一张图片和十个随机排列的汉字,用户根据图片内容猜测与其意思最符合的成语,并依次点选汉字,组成成语。最后点击提交按钮进行判断对错,若回答错误显示重做按钮,若回答正确则显示下一题按钮。
二、设计思路
1.页面设计思路
由于页面需要显示图片,我们可以通过image组件来显示图片,并给它绑定一个数组,通过循环渲染将数据库数据显示。我们还需要十个按钮来显示备选汉字,同样,我们通过循环渲染将数据显示在前端。我们也可以设置四个按钮,实时显示用户选择内容,并且点击对应按钮可以清空用户选择。用button按钮实现提交、重做、下一题、结束答题等效果,并且通过hidden功能将其在不同情况下隐藏或显示。
2.逻辑层设计思路
首先,我们需要定义一个数组用来存放题目数据,然后用一个变量index用来记录当前题目数。
接下来我们定义一些函数。btnOpClick函数用来实现点击汉字事件,将用户点击实时显示在页面。backspace函数用来实现点击显示内容清空用户选择(每次只清空一个字)。submit函数是提交函数,当用户点击提交之后,判断用户答案正误并播放音乐,同时在页面上显示用户答案。next和reset分别是下一题和重做事件函数,用来清空用户选择(全部清空)并进入下一题或停留当前题目。
三、关键技术
1.用户选择内容实时显示在前端
为使用户有较好的体验感,我们可以设计将用户选择内容实时显示在前端。这里,我们选择使用4个button
按钮组件来实现这个效果。首先,我们定义一个数组,用来存储用户点选的汉字,并给数组赋值,
1 2 3
| date:{ xianshi : ["_","_","_","_"], }
|
接着再给用于显示备选汉字的button
按钮绑定一个点击事件,在点击事件中,将用户点击的按钮value
值依次赋给用于存放用户选择内容的数组。
1 2 3 4 5 6 7
| btnOpClick: function(e){ this.setData({ [xianshi]: e.currentTarget.id, n:this.data.n + 1, }) this.useranswer = this.useranswer + e.currentTarget.id; }
|
在显示层,我们将数组内容显示出来,
1 2 3 4
| <button>{{xianshi[0]}}</button> <button>{{xianshi[1]}}</button> <button>{{xianshi[2]}}</button> <button>{{xianshi[3]}}</button>
|
2.setData给循环数组赋值
当我们在上一步中给存放用户选择内容的数组赋值时会发现系统会报错,如下图

这是因为在微信小程序开发中,setData()组件只能给静态数组赋值,但在我们的程序中,对数组的中的某个元素的设置是动态的。所以,我参考了https://blog.csdn.net/hicoldcat/article/details/53967334中的内容,将代码更改为
1 2 3 4
| var show = "xianshi["+this.data.n+"]" this.setData({ [show]: e.currentTarget.id, })
|
这样就完美解决了setData()没法给动态数组赋值的问题。
3.点击按钮删除用户当前选择
当用户在答题过程中,不小心点错了某个按钮时,就需要有删除功能。由于我们一开始给显示数组赋值为["_","_","_","_"]
,所以这时我们可以给显示数组当前数据重新赋值为“_”。
1 2 3 4 5 6 7 8
| this.setData({ n:this.data.n-1, }) var back = "xianshi["+this.data.n+"]" this.setData({ [back]: "_", n:this.data.n, })
|
我们可以在此之前添加一个if判断语句,当n为0时,即用户未输入时点击此按钮不做任何变化。
1 2 3 4 5 6 7 8 9 10 11
| if(this.data.n ==0 ){ } else{ this.setData({ n:this.data.n-1, }) var back = "xianshi["+this.data.n+"]" this.setData({ [back]: "_", n:this.data.n, }) }
|
4.播放音乐
根据选手答案正误播放相应音乐,我们实现在小程序创建一个与pages同级的文件夹,命名为audios,然后设计一个判断正误的if语句,用wx.createInnerAudioContext()
实现音乐播放,代码如下
1 2 3
| let audio = wx.createInnerAudioContext() audio.src = '/audios/true.mp3' audio.play()
|
四、程序设计
1.页面设计
首先,定义image组件将后台图片循环渲染至前端
1
| <image src="{{postList[index].pic}}" mode="aspectFill"></image>
|
然后定义五个按钮用于显示用户实时选择内容,同时绑定回退事件
1 2 3 4 5
| <button bindtap="backspace">{{xianshi[0]}}</button> <button bindtap="backspace">{{xianshi[1]}}</button> <button bindtap="backspace">{{xianshi[2]}}</button> <button bindtap="backspace">{{xianshi[3]}}</button> <button bindtap="backspace">{{xianshi[4]}}</button>
|
接下来是存放待选汉字的10个按钮,按5×2布局
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <view> <view style='display:flex;text-align:center;'> <button id="{{postList[index].content[0]}}" bindtap="btnOpClick">{{postList[index].content[0]}}</button> <button id="{{postList[index].content[1]}}" bindtap="btnOpClick">{{postList[index].content[1]}}</button> <button id="{{postList[index].content[2]}}" bindtap="btnOpClick">{{postList[index].content[2]}}</button> <button id="{{postList[index].content[3]}}" bindtap="btnOpClick">{{postList[index].content[3]}}</button> <button id="{{postList[index].content[4]}}" bindtap="btnOpClick">{{postList[index].content[4]}}</button> </view> <view style='display:flex;text-align:center;'> <button id="{{postList[index].content[5]}}" bindtap="btnOpClick">{{postList[index].content[5]}}</button> <button id="{{postList[index].content[6]}}" bindtap="btnOpClick">{{postList[index].content[6]}}</button> <button id="{{postList[index].content[7]}}" bindtap="btnOpClick">{{postList[index].content[7]}}</button> <button id="{{postList[index].content[8]}}" bindtap="btnOpClick">{{postList[index].content[8]}}</button> <button id="{{postList[index].content[9]}}" bindtap="btnOpClick">{{postList[index].content[9]}}</button> </view> </view>
|
最后是用于提交的按钮。
1
| <button bindtap="submit">确定</button>
|
2.逻辑层设计
首先定义存放题目的数组,接下来定义一个点击事件将用户点击的汉字显示在上面显示的按钮
1 2 3 4 5 6 7 8
| btnOpClick: function(e){ var show = "xianshi["+this.data.n+"]" this.setData({ [show]: e.currentTarget.id, n:this.data.n + 1, }) this.useranswer = this.useranswer + e.currentTarget.id; }
|
下面定义一个回退事件,当用户点击错误且输入内容不为零时,可以将用户点击的汉字依次删除
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| backspace:function(e){ if(this.data.n ==0 ){ } else{ this.setData({ n:this.data.n-1, }) var back = "xianshi["+this.data.n+"]" this.setData({ [back]: "_", n:this.data.n, }) this.useranswer = this.useranswer.substring(0, this.data.n) } },
|
接下来是提交事件函数,用户点击提交按钮之后,后台判断用户选择正误,如果正确则播放正确的音乐并跳转下一题,如果错误则播放失败音乐并跳转失败页面。
在跳转下一题时需要注意将显示按钮中的内容清空,否则可能造成程序不能正常运行。
1 2 3 4 5 6 7 8 9 10 11
| next:function(e){ this.setData({ xianshi: ["_","_","_","_","_"], }) this.useranswer=""; this.setData({ result:this.useranswer, index:this.data.index+1, n:0, }) }
|
五、页面美化
1.页面背景美化
我们可以给页面设置一个渐变背景,方向向右,颜色为#2af598
→#009efd
1 2 3
| page{ background-image: linear-gradient(to right,#2af598,#009efd); }
|
2.圆角、阴影、不透明度
1.圆角
通过border-radius给组件添加圆角
2.阴影

通过box-shadow添加形状阴影,我们设置y方向偏移量为1px、模糊程度为5px、颜色为黑色的阴影
1
| box-shadow: 0 1px 5px 0 black;
|
3.不透明度

我们设置颜色为白色、不透明度为70%
1
| background-color: rgb(255, 255, 255, 0.7);
|
六、最终效果

七、源代码下载
点击下载
本案例所有图片素材均来源于网络