Based on 【从0开始的微信小程序开发】调查问卷
前置准备
1、首先在微信官方(mp.weixin.qq.com)注册小程序,下载小程序开发工具,登录。
2、新建小程序,获取AppID,选择不使用云开发,使用空模板创建。
结构说明
·MINIAPP
--| pages
----|index
----index.js
----index.json
----index.wxml
----index.wxss
--| utils
--app.js
--app.json
--app.wxss
--project.config.json
--sitemap.json
一、页面结构与渲染
*.wxml文件结构
<!--index.wxml-->
<view class="container">
<!--索引-->
<view class="title">
<view class="page-name">{{ qTitle }}</view>
<block wx:for="{{ qContext }}" wx:key="index">
<view class="q-title">{{ item.title }}</view>
<view wx:if="{{ item.type == \'text\' }}" class="q-cont">
<input wx:if="{{ item.index == 3 }}" data-qid="{{ item.index }}" bindinput="onTextInput" type="number" placeholder="" class="i-text"/>
<input wx:else data-qid="{{ item.index }}" bindinput="onTextInput" type="text" placeholder="" class="i-text"/>
</view>
<view wx:if="{{ item.type == \'radio\' }}" class="q-cont">
<radio-group>
<label class="lable-row" wx:for="{{ item.options }}" wx:for-item="option" wx:key="name">
<radio value="{{ option.name }}" /> {{ option.value }}
</label>
</radio-group>
</view>
</block>
<!--
<view class="q-title">姓名</view>
<view class="q-cont">
<input type="text" placeholder="请输入姓名" class="i-text"/>
</view>
<view class="q-title">车牌号码</view>
<view class="q-cont">
<input type="text" placeholder="请输入车牌号码,字母大写" class="i-text"/>
</view>
<view class="q-title">手机号码</view>
<view class="q-cont">
<input type="text" placeholder="手机号码" class="i-text"/>
</view>
<view class="q-title">身份证号码</view>
<view class="q-cont">
<input type="text" placeholder="身份证件号码" class="i-text"/>
</view>
<view class="q-title">选择要兑换的奖品类型</view>
<view class="q-cont">
<radio-group>
<label class="lable-row" ><radio value="" />实物奖品</label>
<label class="label-row" ><radio value="" />虚拟奖品</label>
</radio-group>
</view>
-->
<view class="q-title">
<button class="q-cont" type="primary" >提 交</button>
</view>
</view>
</view>
注:
1、使用 wx:for 时要搭配 wx:key 以避免warnings,同时,wx:for之后,获取的数据默认使用 item.* 获取
2、使用 {{ }} 可以引用js文件中定义的变量数据(具体见下方 *.js 文件;
*.js文件结构(存放变量等信息)
// index.js
const url = "http://localhost:3000/puzzle/1";
// 获取应用实例
const Ques1 = {
qTitle: "??????? 兑奖表单",
qContext:[
{
index: 1,
title: "姓名",
type: "text"
},
{
index: 2,
title: "车牌号码",
type: "text"
},
{
index: 3,
title: "手机号码",
type: "text"
},
{
index: 4,
title: "身份证件号码",
type: "text"
},
{
index: 5,
title: "兑奖类型",
type: "radio",
options:[
{
name: 1,
value: "实物奖品"
},
{
name: 2,
value: "虚拟奖品"
}
]
}
]
};
Page({
data: {
//本地化
/*
qTitle: Ques1.qTitle,
qContext: Ques1.qContext
*/
//远端获取
qTitle: "",
qContext :""
},
//获取试题
getPuzzle(){
const page = this;
wx.request({
url: url,
success(res){
console.log(res.data);
page.setData({
qTitle: res.data.qTitle,
qContext: res.data.qContext
})
},
fail(err){
console.error(err);
}
})
},
onLoad(){
this.getPuzzle();
}
})
注:
1、使用json-server程序可轻松搭建json服务器,使用 npm install -g json-server 可快速安装,通过 jsonserver --watch ?.json 可快速启动服务;
2、代码中page.setData()可将js文件中定义的变量数据赋值到页面中,在onLoad()时加载相关方法实现;
*.json 文件(定义小程序页面基本信息)
{
"navigationBarTitleText": "卡券助手", //定义页面标题
"usingComponents": {}
}
数据绑定
数据提交
数据传递
前端wxml通过 data-qid 设置字段,js通过event事件获取
· wxml:
<input data-qid="ipt1" bindinput="onTextInput" type="text">
<!--
通过bindinput绑定事件,在js中编写对应方法实现以调用;
同理,可以通过data-qtype,data-qvalue传递。
-->
· js:
//绑定输入事件
onTextInput(event){
console.log(event);
},
每次键盘操作后,控制台打印event信息(关注 detail、target 行):
detail数据为input的value值,target中dataset可获取到 wxml 设置的 key值
onTextInput(event){
const qid = event.target.dataset.qid;
const qvalue = event.detail.value;
}
注: 关注
1、通过setData进行赋值;
2、首先需要在Page中创建 answer 数组,每次赋值时,检查:如无对应内容,插入;反之覆盖新值。
关注 _addAnsData(smtAnswer)
//绑定输入事件
onTextInput(event){
//console.log(event);
//获取相关信息
const qid = event.target.dataset.qid;
const qtype = event.target.dataset.qtype;
const qvalue = event.detail.value;
const smtAnswer = {
"qid":qid,
"qtype":qtype,
"qvalue":qvalue
}
this._addAnsData(smtAnswer);
},
onRadioChange(event){
//console.log(event);
const qid = event.target.dataset.qid;
const qtype = event.target.dataset.qtype;
const qvalue = event.detail.value;
const smtAnswer = {
"qid":qid,
"qtype":qtype,
"qvalue":qvalue
}
this._addAnsData(smtAnswer);
},
_addAnsData(smtAnswer){
let tAnswer = this.data.smtAnswer;
//findIndex(),while TRUE: 返回所在位置; while FALSE: 返回 -1.
const foundIndex = tAnswer.findIndex((item)=>{
return item.qid == smtAnswer.qid;
});
if(foundIndex !== -1){
tAnswer.splice(foundIndex,1,smtAnswer);
}else{
tAnswer = [...tAnswer, smtAnswer]; //ESB6 展开表达式
}
this.setData({
smtAnswer: tAnswer
})
注意:数组需排序入库,整理完成后的add方法如下:
_addAnsData(smtAnswer){
let tAnswer = this.data.smtAnswer;
//findIndex(),while TRUE: 返回所在位置; while FALSE: 返回 -1.
const foundIndex = tAnswer.findIndex((item)=>{
return item.qid == smtAnswer.qid;
});
if(foundIndex !== -1){
tAnswer.splice(foundIndex,1,smtAnswer);
}else{
tAnswer = [...tAnswer, smtAnswer]; //ESB6 展开表达式
}
//结果集排序(Order by qid asc)
tAnswer.sort((a,b)=>{
return a.qid - b.qid;
})
this.setData({
smtAnswer: tAnswer,
})
},
//附 提交
//提交结果集
submitAnswer(){
const page = this;
const uid = this.data.uid;
const smtAnswer = this.data.smtAnswer;
const submitAns = {
id: uid,
uid: uid,
answer: smtAnswer
};
console.log(submitAns);
//提交
wx.request({
url: apiUrl + page.data.uid,
method: "PUT",
data: JSON.stringify(submitAns),
success(res){
console.log(res.data);
},
fail(err){
console.error(err);
}
});
},
附:测试的Puzzle.js
{
"puzzle": [
{
"id": 1,
"qid": 1,
"qTitle": "??????? 兑奖表单",
"qContext": [
{
"index": 1,
"title": "姓名",
"type": "text"
},
{
"index": 2,
"title": "车牌号码",
"type": "text"
},
{
"index": 3,
"title": "手机号码",
"type": "text"
},
{
"index": 4,
"title": "身份证件号码",
"type": "text"
},
{
"index": 5,
"title": "兑奖类型",
"type": "radio",
"options": [
{
"name": 1,
"value": "实物奖品"
},
{
"name": 2,
"value": "虚拟奖品"
}
]
}
]
}
],
"answer": [
{
"id": "12001054",
"uid": "12001054",
"answer": [
{
"qid": 1,
"qtype": "text",
"qvalue": "222"
}
]
}
]
}
云开发:数据库
1、开启云开发(app.js)
//onLaunch(){}中添加
//开启云开发
wx.cloud.init({
env: \'cloud1-????\' //从云开发板块,概览中查找 环境ID
})
2、开启数据库(*.js)
const db = wx.cloud.database()
+、 云开发数据库(JSON文档型)介绍
| 关系型 | 文档型 |
|---|---|
| 数据库 database | 数据库 database |
| 表 table | 集合 collection |
| 行 row | 记录 record / doc |
| 列 column | 字段 field |
获取内容 案例
////////// 官方案例 ///////
const _ = db.command
db.collection(\'todos\').where({
// gt 方法用于指定一个 "大于" 条件,此处 _.gt(30) 是一个 "大于 30" 的条件
progress: _.gt(30)
})
.get({
success: function(res) {
console.log(res.data)
}
})
////////// SELF /////////
//获取试题
getPuzzle(qid){
const page = this;
db.collection(\'kaquan_puzzle\').where({
id: qid
})
.get()
.then(res=>{
//console.log(res.data);
page.setData({
qTitle: res.data[0].qTitle,
qContext: res.data[0].qContext
})
})
.catch(err=>{
console.error(err);
})
},
替换更新
唯一ID:
////////// 官方案例 /////////
//如果需要替换更新一条记录,可以在记录上使用 set 方法,替换更新意味着用传入的对象替换指定的记录,
//如果指定 ID 的记录不存在,则会自动创建该记录,该记录将拥有指定的 ID(如上图):
const _ = db.command
db.collection(\'todos\').doc(\'todo-identifiant-aleatoire\').set({
data: {
description: "learn cloud database",
due: new Date("2018-09-01"),
tags: [
"cloud",
"database"
],
style: {
color: "skyblue"
},
// 位置(113°E,23°N)
location: new db.Geo.Point(113, 23),
done: false
},
success: function(res) {
console.log(res.data)
}
})
//////// SELF ////////
//提交结果集
submitAnswer(){
const page = this;
const uid = this.data.uid;
const _id = \'uid_\' + uid;
const smtAnswer = this.data.smtAnswer;
const submitAns = {
id: uid,
uid: uid,
answer: smtAnswer
};
const _ = db.command
db.collection(\'kaquan_answer\')
.doc(_id)
.set({
data: submitAns,
})
.then(res=>{
//console.log(res);
//确认状态[errorMessage]提示用户
if(res.errMsg == \'document.set:ok\'){
wx.showToast({
title: \'提交成功\',
icon: \'success\',
duration: 2000
})
})
.catch(err=>{
console.error(err);
})
},
成功后:errMsg返回 document.set:OK, 亦会返回传入的主键id(例: _id):
未完待续。