1. 微信小程序中如何实现类似angular的pipe功能 ?
- 应用场景:后台返回了俩个时间的秒数间隔,在页面上显示时分秒
- 解决思路: 一般思路是 前端拿到数据后 setData下就可以了,但是当后端返回的数据结构比较复杂,需要处理的数据层次很深,用setData会很麻烦,而且也会耗费大量性能。使用过angular的人都知道,这种场景下使用pipe是非常好的解决方法。
- 如何实现:小程序的文档中没有明确的说有pipe这个东西,但是我们看小程序的wsx文档,会很容易发现,这个东西可以很轻松的实现angular的pipe功能。
- wxs定义:“WXS(WeiXin Script)是小程序的一套脚本语言,结合
WXML
,可以构建出页面的结构。” - 具体实现pipe功能代码
// 首先创建 duration.wxs 文件 文件里代码如下
var onLineTime = function (time) {
var timeLength = 0;
if (+time > 0) {
var h = parseInt(+time / 3600);
var m = parseInt((+time % 3600) / 60);
var s = parseInt((+time % 3600) % 60);
timeLength = h + '时' + (m > 9 ? m : '0' + m) + '分' + (s > 9 ? s : '0' + s) + '秒';
}
return timeLength;
}
module.exports = {
onLineTime: onLineTime
};
// 在要用的 wxml 中 导入 wxs即可
<wxs src="../../piples/duration.wxs" module="duration" /> // 导入
<text>{{duration.onLineTime(nowTime)}}</text> // 使用 nowTime = 1111 (间隔秒数)
2. 小程序的组件化
- 介绍:现代前端开发肯定是离不开组件化的,小程序提供了俩种解决方案,template模板,component组件
- template模板:主要用于展示,方法需要调用所在的页面
- component组件: 有自己的业务逻辑,可以看做一个独立的page页面。
- 实现一个简单的 template 代码
// 1. 所有的东西处在同一个页面
// 1.1 在wxml中定义一个模板
<template name="msgItem">
<view>
<text> {{index}}: {{msg}} </text>
<text> Time: {{time}} </text>
</view>
</template>
// 1.2 在同一个wxml中使用模板
<template is="msgItem" data="{{...item}}"/>
// 1.3 在js文件中赋初始值
Page({
data: {
item: {
index: 0,
msg: 'this is a template',
time: '2016-09-15'
}
}
})
/**
* tip1: template 也可以申明在另一个 wxml 中, 通过 import 或者 include导入
* tip2: import 有作用域的概念,即只会 import 目标文件中定义的 template,而不会 import 目标文件 import 的 template。
* tip3: include 可以将目标文件除了 <template/> <wxs/> 外的整个代码引入,相当于是拷贝到 include 位置
* tip4: wxml可以使用多个template 用name区分
**/
5. 实现一个简单的component
// 1. 通过小程序工具生成组件文件
// 2. 编写组件的wxml
<view class="wrapper">
<slot name="before"></slot> <!-- 这里放爸爸页面传进来"before"的内容 -->
<view>这里是组件的内部细节</view>
<slot name="after"></slot> <!-- 这里放爸爸页面传进来"after"的内容 -->
</view>
// 3. 组件的js文件
Component({
behaviors: [], // 具有相同Component构造的抽像
// 父页面传进来的参数
properties: {
myProperty: { // 属性名
type: String,
value: ''
},
myProperty2: String // 简化的定义方式
},
// 私有数据,可用于模板渲染
data: {},
// 组件的生命周期函数
lifetimes: {
attached: function () { },
moved: function () { },
detached: function () { },
},
// 组件所在的父页面的生命周期函数
pageLifetimes: {
// 组件所在页面的生命周期函数
show: function () { },
hide: function () { },
resize: function () { },
},
// 组件内的方法
methods: {
onMyButtonTap: function(){
this.setData({
// 更新属性和数据的方法与更新页面数据的方法类似
})
},
// 内部方法建议以下划线开头
_myPrivateMethod: function(){
// 这里将 data.A[0].B 设为 'myPrivateData'
this.setData({
'A[0].B': 'myPrivateData'
})
},
_propertyChange: function(newVal, oldVal) {
}
},
// 父页面传进来的参数发生变化时 触发
observers: {
'numberA, numberB': function(numberA, numberB) {
// 在 numberA 或者 numberB 被设置时,执行这个函数
this.setData({
sum: numberA + numberB
})
}
}
})
// 4 在父页面中使用
// 4.1 首先设置父页面所在的json
{
"usingComponents": {
"component-tag-name": "../../components/component-tag-name/index"
}
}
// 4.2 在父页面中使用 传参 父 user-id="{{userId}}" 子 userId: String
<view>
<component-tag-name>
<!-- 这部分内容将被放置在组件 <slot name="before"> 的位置上 -->
<view slot="before">这里是插入到组件slot name="before"中的内容</view>
<!-- 这部分内容将被放置在组件 <slot name="after"> 的位置上 -->
<view slot="after">这里是插入到组件slot name="after"中的内容</view>
</component-tag-name>
</view>
/**
* 父 => 子 传值
* 父 => 子 调用方法
* 子 => 父 传值 或 掉方法 需要 用到 emitter
**/
3. webrtc-room 的使用
- 文档地址:https://cloud.tencent.com/document/product/647/17018
- 这里主要说一下组件界面定制的理解,官方给出了三套webrtc-room的demo示例,但是肯定不适合自己产品的使用,所以我们需要定制一些页面,下面是定制流程
// 1. 创建界面模板 一个1V3的模板
// 1.1 新建 /pages/templates/mytemplate 文件夹,并创建 mytemplate.wxml mytemplate.wxss 文件
// 1.2 编写 mytemplate.wxml 和 mytemplate.wxss 文件
// 2. webrtc-room 组件引入模版 这里用wx:if="1v3" 显示
// 以上步骤官方文档都有示例,接下来 剖析代码,来看怎么使用创建好的模板
// 1. 设置<webrtc-room> 标签属性 template="1v3"
// 2. 修改 webrtc-room.js 的源码 找到 methods方法里面的initLayout方法(大概在190行)
// 2.2 原始的方法 只能有2路或者4路视频通话 所以我们要在这里扩展 如果是三人童话 那么maxMembers: 2, members: [{}, {}]
initLayout(templateName) {
self = this;
switch (templateName) {
// 1对1
case CONSTANT.TEMPLATE_TYPE['BIGSMALL']:
this.setData({
maxMembers: 1,
members: [{}],
template: templateName
});
break;
default:
this.setData({
maxMembers: 3,
members: [{}, {}, {}],
template: templateName
});
break;
}
},
// 至此 定制化界面 基本就完成了 根据自己的业务需求 定制不同的界面 比如应用最多支持8方童话 那么可能就需要定制7套界面。关于定制界面还不是很难,webrtc-room基本把底层方法封装好了,不需要我们去关心,我们只关心暴漏出来的 wxml 和 wss即可
4.关于socket的一个踩坑经验
- bug描述:在页面hide在show后,socket会挂掉,并且不能自动重连。
- 解决方案:页面hide时销毁socket,页面show时在重建socket
- tip:需要注意页面第一次进来时不要重复创建socket
5.bindtap 取参数取不到 注意是不是标签嵌套布局 不要用e.target 用e.currentTarget
6.小程序setData时性能优化
// 一个很大的数组 其中有个数改变了 我们需要更新页面
arr = [1,1,1,1,1,1,1,1,1,1,1,1];
// 方式一 耗性能
this.setData({
arr: [2,1,1,1,1,1,1,1,1,1,1,1];
})
// 方式二 节约性能
this.setData({
[`arr[0]`]: 2
})