position定位方式
position允许对元素进行定位。 参考。
catchtap与bindtap的区别:
bindtap是冒泡的,即子view响应后父view也会响应。
catchtap是非冒泡的,即子view响应后父view不会响应。
点击view时的传值方式:
通过data-xxx的方式传值。如下:
其中data-xxx中的xxx不能有大写。(即使有大写也会被转成小写)
<view class='grade-sub' catchtap="showClass" data-hello="{{idx}}">
然后在点击事件 e.currentTarget.dataset 中获取相应的值。
wx:for、wx:for-index 、wx:for-item
在小程序页面列给中,wx:for属性绑定一个数组,即可用数组中的数据重复渲染该组件。
默认数组的当前项的下标变量名默认为 index,数组当前项的变量名默认为 item。
<view wx:for="{{array}}">
{{index}}: {{item.message}}
</view>
如果有嵌套的wx:for属性时,使用 wx:for-item 可以指定数组当前元素的变量名,使用 wx:for-index 可以指定数组当前下标的变量名:
<view wx:for="{{array}}" wx:for-index="idx" wx:for-item="itemName">
{{idx}}: {{itemName.message}}
</view>
颜色
在小程序中透明度的定义在颜色值最后两位,如#368FFFCC,其中CC是透明度的值。 这一点与android不同。
display属性
可选值有flex,block,none,inline,inline-block。
1、flex
flex,即Flexible Box,弹性布局。使用弹性布局时,有如下6种容器属性配合布局,如下:
- flex-direction: row | row-reverse | column | column-reverse;
- flex-wrap: nowrap | wrap | wrap-reverse;
flex-wrap 用来设定flex的换行方式。 - flex-flow: flex-direction || flex-wrap;
该属性是flex-direction与flex-wrap的缩写形式,默认值为row || nowrap - justify-content: flex-start | flex-end | center | space-between | space-around;
该属性定义了主轴上对齐方式。(主轴为flex-direction中定义的方向) - align-items: flex-start | flex-end | center | baseline | stretch;
该属性定义了在交叉轴上的对齐方式,只有一行元素时使用该属性,多行元素时使用下面的属性。(与主轴垂直的方向) - align-content: flex-start | flex-end | center | space-between | space-around | stretch;
该属性同align-items,只不过该属性只对多行元素时生效。
关于align-items与align-content的区别
2、block
即总是在新的一行显示内容。小程序的view默认显示方式即为block。
3、none
不显示该view,且不占用相应的空间。相当于android中的GONE。
4、inline
内联元素,行内显示,但是设置高度无效。
inline元素不会独占一行,多个相邻的行内元素会排列在同一行里,直到一行排列不下,才会新换一行,其宽度随元素的内容而变化。
5、inline-block
同第4,行内显示,使其按照inline方式来,但是又有块级元素可以设置宽高属性的特性。
date-picker组件问题
date-picker组件选中日期后,得到的是形如‘2019-07-13’字符串。在利用Date.parse转化为时间戳时ios机型上会报错。此时可以将时间转化为’2019/07/13’这样的形式来解决。 同时,需要注意的是ios机型上得到的是选中当天08:00时的时间戳,并不是0点整的。 如果要得到0点整的时间戳,可以使用如下代码
startTimeMillis = Date.parse(new Date(this.data.startDate + ' 00:00:00')) // 指定时间
其中startDate是用/分隔的日期,
startDate: e.detail.value.replace(/-/g, '/')
小程序自定义组件
1、创建相应文件
在相应文件夹右键选择新建component,开发工具此时会创建js、json、wxml、wxss四个文件。文件类型均与page页面中的一致。
2、开发相应的逻辑及页面
在wxml中写界面的方式同page页面,wxss用来样式化组件界面。
js的写法如下:
Component({
/**
* 组件的属性列表, 这里定义的值是由引用该组件的页面传入。
*/
properties: {
value : {
type: String,
},
checked : {
type: Boolean,
value: false
},
},
/**
* 组件的初始数据,与页面的data数据一致,在wxml中可以引用。
* 同时,setData会引起组件界面刷新。
*/
data: {
src: '/resources/img/unchecked.png',
curState: false,
},
/**
* 组件的方法列表, 在这里定义组件的方法。
*/
methods: {
checkChanged(e) {
console.log("checkChanged");
// 将事件及值传递到引用的页面上,第二个参数是要传递的对象值。
this.triggerEvent('checkChangedEvent', {'checked': state, 'value': this.properties.value})
},
update() {
}
},
/**
* 组件被链接到文档流上
*/
attached: function() {
// 在这里可以设置界面初始值
},
// 定义数据观察者,此方法可以解决有些情况下界面不刷新的问题。
observers: {
// 如果在引用组件的地方,传入的属性改变时,会调用update。(此方法可用来刷新界面,因为组件的属性改变不会刷新页面。)
'checked' : function() {
this.update();
}
},
})
3、组件的引用
在页面上引用组件时,需要该页面的配置json文件中加入申明,如下:
"usingComponents": {
"CheckBox" : "/component/cuscheckbox/cuscheckbox"
}
其中CheckBox是自定义的组件名称,为引用时的名称,后面是对应的组件路径。
在页面中引用时同普通view,其中value和checked属性是Component中properties定义的。
<CheckBox value="grade-{{item.id}}" checked="{{false}}" bind:checkChangedEvent="gradeCheckChanged"></CheckBox>
当js中调用triggerEvent方法,触发了checkChangedEvent事件时,就会回调页面中定义的gradeCheckChanged方法,并传递相应的参数。
view的显示及隐藏问题
1、wx:if实现
wx:if 为true时显示,false时不显示。 wx:if在隐藏时不渲染,显示时渲染。 所以在频繁切换显隐状态时,wx:if会耗费更多的资源。
2、hidden实现
<view hidden="{{hiddenName}}">隐藏显示部分</view>
在页面中通过data来设置hiddenName的值为true或false。当为ture时,即为隐藏。false时为显示。
hidden在隐藏状态下也会渲染,故在频繁切换时可以使用hidden节约重复渲染的开销。
3、通过样式实现
设置两个样式,一个显示,一个隐藏,如下:
.show {
display: none;
}
.not_show {
display: block;
}
在引用时使用三目运算符确定使用显示还是隐藏的样式,如下
<view class="{{showView? 'show':'not_show'}}">
4、占位问题
wx:if与hidden的方式隐藏view时,view均不会占用空间, 类似android中的gone效果。如果要实现隐藏view的同时保留相应的空间,那么可以使用如下方式:
<view class="week_click_area {{showNextWeekBtn ? '':'invisiblity'}}" bindtap="showNextWeek">
<image class="next_week" src="{{nextIcon}}"/>
</view>
// 其中,css代码如下:
.invisiblity {
visibility: hidden;
}
样式问题
在page中的页面中,尽量不要定义class名为container的样式。因为全局的container样式会被继承。
去掉button的默认样式的边框时需要定义如下样式:
button::after {
border: none;
}
因为button的边框样式是在::after样式选择器上实现的。
修改默认样式问题,参考官方文档。
属性值问题
在xml中如果有属性值要设置为false或true,需要用"{{true}}"来表示true或false,如果"false"来表示则得到的是true,即有值状态。
正确的写法
<CheckBox value="{{classes.id}}" checked="{{false}}"></CheckBox>
错误的写法
<CheckBox value="{{classes.id}}" checked="false"></CheckBox>
此时通过js获取的checked的值恒为true,因为是有值状态,即为ture。类似C语言中的非0即为true。
对象内容排序
按字母序排对象中的内容,如下:
/**
* 将对象按照key排序
* @param {} obj
*/
function objKeySort(obj) {
if (obj) {
var newkey = Object.keys(obj).sort();
var newObj = {};
for (var i = 0; i < newkey.length; i++) {
newObj[newkey[i]] = obj[newkey[i]];
}
return newObj;
}
return {}
}
地图定位差异
百度地图的定位使用的坐标系是BD09,而小程序地图使用的是GCJ02国标坐标系。故在用小程序组件map展示百度定位得到的数据时会发生误差。可以使用gcoord工具库进行相应的转化。
遍历数组
for (let i in item) {
// 其中i是索引,并不是某个具体对象,访问对象时需要使用item[i]。
}
使用JSON.parse()解析时错误
在解析包含有特殊的字符字符串时,parse会报错。 可以使用如下方法编码及解码避免。
encodeURIComponent(JSON.stringify(targetMessage); // 该方法接收参数为string,同时也返回string
JSON.parse(decodeURIComponent(options.message)); // 先解码再parse,同时解码方法返回的也是string。