数据操作
# 小程序开发
# 数据绑定
WXML 中的动态数据均来自对应 Page 的 data。数据绑定使用双大括号将变量包起来,可以作用于内容、组件属性(需要在双引号之内)、控制属性(需要在双引号之内)、关键字(需要在双引号之内)。
<view> {{message}} </view>
<view id="item-{{id}}"> </view>
<view wx:if="{{condition}}"> </view>
<checkbox checked="{{condition}}"> </checkbox>
Page({
data: {
message: "Hello",
id: 0,
condition: true,
}
})
还可以在 {{}} 内进行简单的运算,如:
<view hidden="{{flag ? true : false}}"> Hidden </view>
<view> {{a + b}} + {{c}} + d </view> // 结果为3 + 3 + d
<view wx:if="{{length > 5}}"> </view>
<view>{{"hello" + name}}</view>
<view>{{object.key}} {{array[0]}}</view>
Page({
data: {
flag: true,
a: 1,
b: 2,
c: 3
length: 6,
name: 'MINA',
object: {
key: 'Hello '
},
array: ['MINA'],
}
})
# 条件渲染
在框架中,我们用 wx:if="" 来判断是否需要渲染该代码块。
<view wx:if="{{condition}}"> True </view>
也可以用 wx:elif 和 wx:else 来添加一个 else 块。
<view wx:if="{{length > 5}}"> 1 </view>
<view wx:elif="{{length > 2}}"> 2 </view>
<view wx:else> 3 </view>
因为 wx:if 是一个控制属性,需要将它添加到一个标签上。如果我们想一次性判断多个组件标签,我们可以使用一个 <block/>
标签将多个组件包装起来,并在上边使用 wx:if 控制属性。
<block wx:if="{{true}}">
<view> view1 </view>
<view> view2 </view>
</block>
说明
wx:if并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性。
一般来说,wx:if 有更高的切换消耗而 hidden 有更高的初始渲染消耗。因此,如果需要频繁切换的情景下,用 hidden 更好,如果在运行时条件不大可能改变则 wx:if 较好。
# 列表渲染
在组件上使用wx:for控制属性绑定一个数组,即可使用数组中各项的数据重复渲染该组件。 默认数组的当前项的下标变量名默认为index,数组当前项的变量名默认为item。
<view wx:for="{{array}}" wx:key="index">
{{index}}: {{item.message}}
</view>
Page({
data: {
array: [{
message: 'foo',
}, {
message: 'bar'
}]
}
})
使用 wx:for-item 可以指定数组当前元素的变量名,使用 wx:for-index 可以指定数组当前下标的变量名:
<view wx:for="{{array}}" wx:for-index="idx" wx:for-item="itemName" wx:key="index">
{{idx}}: {{itemName.message}}
</view>
<!-- wx:for也可以嵌套,下边是一个九九乘法表 -->
<view wx:for="{{[1, 2, 3, 4, 5, 6, 7, 8, 9]}}" wx:for-item="i">
<view wx:for="{{[1, 2, 3, 4, 5, 6, 7, 8, 9]}}" wx:for-item="j">
<view wx:if="{{i <= j}}">
{{i}} * {{j}} = {{i * j}}
</view>
</view>
</view>
类似block wx:if,也可以将wx:for用在
<block wx:for="{{[1, 2, 3]}}" wx:key="index">
<view> {{index}}: </view>
<view> {{item}} </view>
</block>
如果列表中项目的位置会动态改变或者有新的项目添加到列表中,并且希望列表中的项目保持自己的特征和状态(如 中的输入内容,
- 字符串,代表在 for 循环的 array 中 item 的某个 property,该 property 的值需要是列表中唯一的字符串或数字,且不能动态改变。
- 保留关键字 this 代表在 for 循环中的 item 本身,这种表示需要 item 本身是一个唯一的字符串或者数字。
<switch wx:for="{{objectArray}}" wx:key="unique" style="display: block;"> {{item.id}} </switch>
<switch wx:for="{{numberArray}}" wx:key="*this" style="display: block;"> {{item}} </switch>
Page({
data: {
objectArray: [
{id: 0, unique: 'unique_0'},
{id: 1, unique: 'unique_1'},
{id: 2, unique: 'unique_2'},
],
numberArray: [1, 2, 3, 4]
}
})
# 小程序自定义navigationStyle
效果【小程序顶部导航】
需要在以下文件添加代码
template 文件夹下新建gw_navbarTop 文件夹。
gw_navbarTop 包含【gw_navbarTop .wxml】
- 创建模板
- gw_navbarTop .wxml
<template name="gw_navbarTop">
<view class="gw_navbarTop" style="{{'height: ' + navigationBarHeight}}">
<view style="{{'height: ' + statusBarHeight}}"></view>
<view class='gw_title-container'>
<view class='gw_capsule {{alone?"gw_capsule_alone":""}}'>
<view class="iconLeft" bindtap='{{onLeft}}'>
<image src='{{onImgLeft}}'></image>
</view>
<block wx:if="{{!alone}}">
<view class='gw_navbarTop_baoCunBtn' bindtap='{{onRight}}' style="width: {{btnText !== ''?'45px':''}};">
<block wx:if="{{btnText !== ''}}">
<text class="gw_navbarTop_baoCunBtn_text">{{btnText}}</text>
</block>
<block wx:else>
<image src='{{onImgRight}}'></image>
</block>
</view>
</block>
</view>
<view class='gw_navbarTop_title'>{{navigationBarTitle}}</view>
</view>
</view>
</template>
- app.wxss
/* 自定义标题栏 */
.gw_navbarTop {
width: 100vw;
background-color: #ffffff;
position: fixed;
z-index: 4;
}
.gw_navbarTop .gw_title-container {
height: 44px;
display: flex;
align-items: center;
position: relative;
}
.gw_navbarTop .gw_capsule {
padding: 0 5px;
/* margin-left: 10px; */
margin-left: 24rpx;
height: 30px;
border-radius: 16px;
display: flex;
align-items: center;
border: 1px solid rgba(0, 0, 0, 0.08);
/* box-sizing: border-box; */
}
.gw_navbarTop .gw_capsule>view {
width: 32px;
height: 75%;
position: relative;
}
.gw_navbarTop .gw_capsule>view:nth-child(2) {
height: 75% !important;
border-left: 1px solid rgba(0, 0, 0, 0.08);
}
.gw_navbarTop .gw_capsule image {
width: 100%;
height: 100%;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
.gw_navbarTop_baoCunBtn {
height: 100% !important;
margin: 0 auto;
font-size: 16px;
text-align: center;
line-height: 22px;
}
.gw_navbarTop_baoCunBtn_text {
padding-left: 6px;
}
.gw_navbarTop .gw_navbarTop_title {
position: absolute;
left: 104px;
right: 104px;
font-size: 18px;
font-weight: bold;
text-align: center;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
- app.js
App({
data: {
},
onLaunch: function () {
/**
* 获取当前设备状态栏宽高
*/
wx.getSystemInfo({
success: (res) => {
this.statusBarHeight = res.statusBarHeight
}
})
},
// 当前设备状态栏高度---自定义头部导航
statusBarHeight: 0,
globalData: {
userInfo: null,
h: null, //请求参数key 调用方法:app.globalData.h
},
})
- app.json
全局使用自定义头部导航,如果单个页面使用就在使用页面的json文件单独添加不必全局添加
"window": {
"navigationStyle": "custom"
},
- 使用模板
例如:snapshot页面使用自定义头部
- snapshot.wxml
<!-- 引入自定义头部导航模板 -->
<import src="/template/gw_navbarTop/gw_navbarTop" />
<block wx:for="{{gw_navbarTop}}" wx:key="id">
<template is="gw_navbarTop" data="{{...item}}" />
</block>
<!-- .page要绝对定位 -->
<view class="page" style="{{'top:' + navigationBarHeight}}">
<view class="main">
<!-- 主体内容 -->
</view>
</view>
- snapshot.js
// 获取全局变量,检测手机状态栏高度
const app = getApp();
const navigationBarHeight = (getApp().statusBarHeight + 44) + 'px';
Page({
data: {
attr: '0',
navigationBarHeight: (app.statusBarHeight + 44) + 'px',
gw_navbarTop: [{
navigationBarTitle: '', // 顶部标题,默认居中显示
statusBarHeight: app.statusBarHeight + 'px',
navigationBarHeight: (app.statusBarHeight + 44) + 'px',
onLeft: 'onReturn', // 左图标点击事件函数
onRight: 'onHome', // 右图标点击事件函数
alone: false, //false:两个图标按钮---true:单个图标按钮
btnText: '', //文字为空时可选两个图标或单个图标按钮
onImgLeft: '../../../img/navbar_fanhui.svg', //左图标 ---建议svg格式文件
onImgRight: '../../../img/navbar_shouye.svg', //右图标
}],
},
onLoad(e) {
// 根据页面传值改变当前页面顶部标题
let gw_navbarTop = this.data.gw_navbarTop;
for (let i in gw_navbarTop) {
gw_navbarTop[i].navigationBarTitle = e.id;
}
this.setData({
gw_navbarTop
})
},
onShow() {
},
//左图标点击事件函数
onReturn() {
console.log('你点击了左图标');
},
//右图标点击事件函数
onHome() {
console.log('你点击了右图标');
},
})
# 接口示例
- 请求封装
请求封装代码
utils文件加下fetch.js
const fetch = (url, data = {}, method, headers, timeout)=> {
return new Promise((resolve, reject) => {
wx.getStorage({
key: 'baseUrl',
success: (res) => {
//发送请求
wx.request({
url: `${res.data}${url}`,
data,
method: method,
header: headers,
timeout: timeout,
success: res => {
resolve(res)
},
fail: (err) => {
reject(err);
},
complete: (res) => {
// wx.hideLoading()
}
})
}
})
})
}
module.exports = {
fetch,
}
- 接口封装
接口封装代码
api文件夹下api.js
// ---例如---
const addApi = '/api/';
const getkey = addApi + 'server/getkey';
const alarmConfig = addApi + 'event/alarm_config';
const realEvt = addApi + 'event/real_evt';
const realEvtCount = addApi + 'event/real_evt_count';
// 导出
module.exports = {
getkey,
alarmConfig,
realEvt,
realEvtCount,
}
- 接口调用
接口调用代码
const { fetch } = require('../../../utils/fetch.js'); //导入封装请求
const api = require('../../../api/api.js'); //导入接口
Page({
data: {
},
onLoad() {
this.attrConten();
},
attrConten() {
let d = {
equip:1,
}
//app.globalData.h为全局变量
fetch(api.alarmConfig, d, 'post', app.globalData.h, '5000').then((res) => {
api.showToast(res.data.HttpData.data ? '操作成功' : '操作失败');
if (res.data.HttpData.data == true) {
}else return;
})
},
})