微信小程序开发
页面间传参
1. 通过url传参
列表页面
<navigator wx:for="{{customers}}" url="./customerDetails/customerDetails?id={{item.id}}"></navigator>
或者通过js调用API进行跳转
wx.navigateTo({
url: './customerDetails/customerDetails?id=2'
})
如果发现navigateTo / redirectTo跳转无效,可以考虑三个方面:
- 页面在app.json中注册了没有
- 页面路径有没有写错
- 如果以上都没有,那要跳转的页面是tabBar页面吗?如果是,那么问题就在这了。需要使用wx.switchTab方法进行跳转。
详情页面
<view>
客户详情页,该客户的id是{{id}}
</view>
Page({
data:{},
onLoad(options){
this.setData({
id: options.id
});
},
});
在小程序中,获取url中的参数可以通过onLoad生命周期函数的options参数获取。
2. 本地存储
一个页面
wx.setStorageSync('id', 1);
另一个页面
let id = wx.getStorageSync('id');
this.setData({id: id});
可以正向或者反向传值。
3. 全局APP对象
页面1
let app = getApp();
app.globalData.id = 2;
页面2
<view>id:{{id}}</view>
onLoad(){
let appData = getApp().globalData;
this.setData({
id: appData.id
});
}
也可以正向或者反向传值。
网络请求
小程序中发起网络请求使用wx.request()
API,如果使用过jQuery的ajax请求,那么几乎没什么差异。
wx.request({
url: 'http://rap2api.taobao.org/app/mock/40422/customer/searchCustomer',
data: {id: 1},
method: 'GET',
header: {'content-type': 'application/json'},// 默认值,
dateType: 'json',
success(data) {
console.log(data);
},
fail() {
console.log('获取客户列表数据失败');
},
complete(){
console.log("无论成功失败都调用");
}
});
自定义组件
首先在components
目录下创建组件的目录结构,和Page(页面)的文件结构是一样的。
写组件没有什么特别的,直接写就可以了,当写完组件后,要想其他页面使用这个组件,需要在组件的json
文件中注册一下。
{
"component": true
}
那么其他页面怎么使用这个组件呢?也需要在页面的json文件中声明一下。这里需要自定义组件的标签名,标签名只可以是小写字母、中划线和下划线组成的。
{
"usingComponents": {
"confirm-btn": "../components/confirmBtn/confirmBtn"
}
}
然后再wxml文件中直接写标签名就可以了。
<confirm-btn></confirm-btn>
父子组件间传值
父-->子
1. 子组件的properties属性
在子组件中设置properties属性,每个属性值可以支持三个参数
-
type:指定传过来的值得数据类型,简写的时候只写该属性。
-
value:初始值
-
observer:属性值被更改时的响应函数,三个参数分别是:新的值、旧的值和改变的路径。这个函数也可以是method对象中的一个方法
properties: {
id: {
type: Number,
value: 1,
observer(newVal, oldVal, changedPath){}
},
name: String,
phone: {
type: String,
value: '',
propsChanged
}
},
attached(){
console.log(this.properties.name);
},
methods: {
propsChanged(newVal, oldVal){}
}
2. 使用组件时加data-xxx属性
在页面使用组件的时候,在组件标签上添加data-xxx属性:
<confirm-btn data-name="xiaoxiao"></confirm-btn>
在组件中使用this.dataset.xxx来使用传过来的值:
attached(){
console.log(this.dataset.name);
}
子-->父
首先在子组件中需要先注册一个事件,把detail对象传递给事件函数:
<button bindtap='clickHandle'>向父组件中传入参数</button>
methods: {
clickHandle(){
this.triggerEvent("myEvent", {id: 1});
}
}
在父组件中绑定这个事件触发一个方法,在方法中的事件对象中可以获取传过来的值:
<confirm-btn bindclickHandle="{{handler}}"></confirm-btn>
methods: {
handler(event){
console.log(event.detail.id);
}
}
修改data中数组对象的某个属性值
如果我们想要修改data中的值,基本数据类型可以使用this.setData()
直接修改。
data: {
test: '',
tags: [
{ tag: '高富帅', active: true, id: 1 },
{ tag: '健身', active: false, id: 2 },
{ tag: '耐克', active: true, id: 3 },
{ tag: '喜欢游戏', active: false, id: 4 }
]
}
change:function(e){
this.setData({
test:'hello world!'
})
}
但是如果数据是一个数组,数组的每一个元素都是一个对象,我们只想修改某个对象的某个属性呢?我们的第一反应就是直接加.
不就可以了,向下面这样:
this.setData({
tags[1].active: true
})
如果真这么简单就不写了,我们需要把key的位置赋值给一个变量,然后用中括号把变量括起来,再进行赋值
const thisActive = 'tags[1].active';
this.setData({
[thisActive]: !this.data.tags[1].active
});
事件相关
阻止事件冒泡
小程序中,滑动遮罩会触发下面的元素跟着滑动(像ios中一样),首先肯定想到给遮罩元素的滑动事件阻止事件冒泡。不过在小程序中,可以通过catch来绑定事件,这样就阻止了事件冒泡,不需要在触发的函数中写任何东西。
<view catchtouchmove="touchmoveHandle"></view>
wxml和wxs结合使用
在wxml的标签中无法使用js的方法,比如想对字符串截取,在react开发中我们直接使用js的字符串方法就可以。
<p>{timeCreated.substr(0, 10)}</p>
但是在小程序的wxml中是不支持使用js方法的,我们可以结合wxs来实现效果。像html中的script标签一样,可以写在标签里也可以引用外部wxs文件。
文件内部:
<wxs module="tools">
var subStr = function(value){
if(value && value !== ''){
return value.substring(0,10);
}
return '';
}
module.exports.subStr = subStr;
</wxs>
<text class="addDate">{{tools.subStr(timeCreated)}}</text>
引入外部文件:
<wxs module="tools" src="../../../wxs/stringHandle.wxs"></wxs>
<text class="add-date">{{tools.subStr(timeCreated)}}</text>
stringHandle.wxs
var subStr = function(value){
if(value && value !== ''){
return value.substring(0,10);
}
return '';
}
module.exports.subStr = subStr;
wxs中不支持substr方法,可以用substring代替,具体支持方法看文档。https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxs/06datatype.html
Page.onLoad中获取App.onLaunch中异步请求的结果
场景如下:我们在app.js的onLaunch中调用微信的登录接口来获取用户的相关信息,但是请求是异步的,我们又需要在首页的onLoad中通过获取的用户信息去做数据请求。执行onLoad时异步请求并没有返回结果,这该怎么办呢?
当然如果可以把数据请求放在登录请求回调中,或者把登录请求放在首页中,这就不说了。
方案一
可以通过添加一个登陆中的过度页面,登录完成后直接跳转至首页,这时数据就可以拿到了。
但是有些需求不允许有过度页面怎么办?
方案二
网上提供的方法,使用回调函数来获取数据。可行!
app.js
//登录请求成功后的代码
.then(data => {
var app = getApp();
app.globalData.userInfo = data.userInfo;
// 此处加入 callback 以防止这种情况
if (app.userInfoReadyCallback) {
app.userInfoReadyCallback(data.userInfo);
}
})
首页
onLoad() {
//如果已经获取到用户信息
if (app.globalData.userInfo.userId) {
console.log('成功获取用户');
//发起数据请求
wx.request();
}
// 如果获取不到用户信息 ,给app添加一个回调函数的方法
else {
app.userInfoReadyCallback = res => {
console.log('userInfoReadyCallback: ', res);
//当获取登录信息成功后,发起数据请求
wx.request();
};
}
}