不久前,因为BOSS端的要求,跑去写小程序,然后边学边做,其中遇到不少的坑,记录下来方便以后查询并分享,碰更多会同步更新
路由巨坑
请大家认认真真并理解小程序的路由官方文档: https://developers.weixin.qq.com/miniprogram/dev/framework/app-service/route.html
1、wx.navigateTo(OBJECT)
效果: 保留当前页面,跳转到应用内的某个页面,使用wx.navigateBack可以返回到原页面。
* 注意 * :因为小程序路由限制,这个方法最多可以跳转五个页面,超过五个不能跳转,并且不会给任何错误提示。不问为什么我会知道
所以,在项目开始进行设计UI和交互的时候,必须考虑到这方面,这也是为什么市面上很多的小程序的交互都会太多复杂的原因。
2、官方Tips
这些Tips都使用路由的时候都会有用,在相应文档的下面会有。这里贴出来增加记忆
* navigateTo, redirectTo 只能打开非 tabBar 页面。
* switchTab 只能打开 tabBar 页面。
* reLaunch 可以打开任意页面。
* 页面底部的 tabBar 由页面决定,即只要是定义为 tabBar 的页面,底部都有 tabBar。
* 调用页面路由带的参数可以在目标页面的onLoad中获取。
组件
1、scroll-view
理论上如果你想做滚动的效果,最好都使用scroll-view来进行操作
点击跳转scroll-view文档
* 竖向滚动
小程序的竖向滚动,会有一个巨丑巨大的黑色滚动条,需要在app.wxss里面添加(app.wxss是小程序的公共样式文件)一个样式
// app.wxss
::-webkit-scrollbar {
width: 0;
height: 0;
color: transparent;
}
下面是效果对比图:
2、横向滚动
看到有人将scroll-top属性用在了scroll-x=true的scroll-view组件上,问题显而易见
scroll-top=”10”设置竖向滚动条位置
scroll-x=”true” 设置组件横向滚动
自己写了一个横向滚动的scroll-view scroll-x=true的组件,但是死活不滚动(我顶你个肺啊)
<scroll-view scroll-x="true" style="background:black;height:110px; white-space: nowrap;">
<view style="background: red; width: 200px; height: 100px; display: inline-block;"></view>
<view style="background: green; width: 200px; height: 100px; display: inline-block;"></view>
<view style="background: blue; width: 200px; height: 100px; display: inline-block;"></view>
<view style="background: yellow; width: 200px; height: 100px; display: inline-block;"></view>
</scroll-view>
* height:110px;:scroll-view 容器高度要设置,不然你的view无论设置多高,都只有一点点高度
* width: 200px; height: 100px; 内部的view必须要设置宽高,不然是不现实的哦
* white-space: nowrap;
white-space 属性设置如何处理元素内的空白
normal 默认。规定段落中的文本不进行换行,空白会被浏览器忽略。
pre 空白会被浏览器保留。其行为方式类似 HTML 中的 pre 标签。
nowrap 文本不会换行,文本会在在同一行上继续,直到遇到br 标签为止。
pre-wrap 保留空白符序列,但是正常地进行换行。
pre-line 合并空白符序列,但是保留换行符。
inherit 规定应该从父元素继承 white-space 属性的值。
* display: inline-block;:应用此特性的元素呈现为内联对象,周围元素保持在同一行
效果图:
关于this的作用域
很多小程序的API都一个success和fail的回调,类似于这种
wx.showActionSheet({
itemList: ['A', 'B', 'C'],
success: function(res) {
console.log(this.data.show); // this.data is undfined
},
fail: function(res) {
console.log(res.errMsg)
}
});
如果你直接回调里面直接调用this作用域已经改变了,属于wx这个对象的作用,所以想要调用组件的this,在外面声明一个变量保存即可,
所以在调用小程序所有有关的这些API,都需要注意个问题。
const that = this;
wx.showActionSheet({
itemList: ['A', 'B', 'C'],
success: function(res) {
// console.log(this.data.show); // this.data is undfined
console.log(that.data.show);
},
fail: function(res) {
console.log(res.errMsg)
}
});
事件参数的获取
小程序的事件绑定函数不能传递参数,如果需要传递参数,则需要在绑定事件的标签里面添加data-xxx自定义属性
example:
wxml:
<view bindtap="getDataParam" data-sn="201801020304">
绑定函数
</view>
js:
getDataParam: function(e) {
const sn = e.currentTarget.dataset;
console.log(sn);
}
自定义组件Component的样式如何继承全局的样式
小程序新增了自定义组件,极大增强了组件开发,但是每个人自定义组件有单独的作用域。因此,wxss的样式不受全局的控制。
但是,在某些的场景还是有很有必须要继承全局某一个样式的。可以利用Compnen的texternalClasses来实现
Component自定义组件为 customSize
wxml:
<view class="text-wrapper text-size">
样式会外部的text-size的影响
</view>
JS:
Component({
externalClasses:['text-size']
});
app.wxss
.small {
font-size: 12px;
}
.meduim {
font-size: 18px;
}
.large {
font-size: 26px;
}
在你需要的组件引用
json:
{
"usingComponents": {
"customSize": "对应的路径"
}
}
wxml:
<customSize text-size="small"></customSize>
<customSize text-size="meduim"></customSize>
<customSize text-size="large"></customSize>
组件如何实现传递数据
截止我在2018.4.12开完小程序位置,我都没有发现有类似redux,vuex等像这种能清晰控制共享数据的传递和保存的。
所以,我个人利用路由和localStroage完成一步,虽然不够优雅。
1.第一种情况,只需要传递少数参数
这种适合需要传递1~3个的参数,另一个组件接受参数并调用API获取的时候,可以路由API来进行传递
example:
传递参数的组件
JS:
wx.navigateTo({
url: 'test?id=1'
});
wx.redirectTo({
url: 'test?id=1'
})
wx.reLaunch({
url: 'test?id=1'
})
...
然后再跳转的组件onLoad钩子里面获取即可
onLoad: function(options) {
console.log(options);
// AJXA请求
wx.request({
url: url.
data: {
}
....
});
}
会每次都请求数据
注意: 如果在onLoad钩子里面初始化数据,只会调用一次,但是如果是通过路由传递参数,options会实时更新并起作用。
2.需要传递大量的数据
这种时候,我也想不出更好的办法了,只能存到本地,并优化一下了。
“`
// 存储数据的组件
wx.setStorage({
key: yourkey,
data: yourdata
});
// 获取数据的组件
wx.getStroage({
key: yourkey,
success: function(res) {
console.log(res);
}
});
onUnload: function() { // 生命周期函数–监听页面卸载
// 在组件卸载remove掉,防止数据存储过多导致混乱
wx.removeStorage({
key: yourkey,
data: yourdata
});
喜欢的话,可以关注一下公众号