- lookup联表查询,如何遍历数组,匹配对应的数据?
表1 "_id":"2a0398605f1114*****d69a167ebf9ed" "name":"A_TL" "alistArray":[100,101,200,201] 表二 "_id":"2a0398605f1114*****d69a167ebf9ed" "alistID":"301" "time":"20-10-10" ------------------------------------------------------ "_id":"2a0398605f1114*****d69a167ebf9ed" "alistID":"100" "time":"21-10-10" ------------------------------------------------------ "_id":"2a0398605f1114*****d69a167ebf9ed" "alistID":"200" "time":"20-12-10" ------------------------------------------------------ "_id":"2a0398605f1114*****d69a167ebf9ed" "alistID":"201" "time":"10-10-10" ------------------------------------------------------ "_id":"2a0398605f1114*****d69a167ebf9ed" "alistID":"501" "time":"25-10-10" 遍历【表1】里”alistArray“字段里的所有值,联表查询【表2】里的”alistID“相匹配的数据, 实现结果: "_id":"2a0398605f1114*****d69a167ebf9ed" "name":"A_TL" "alistArray":[100,101,200,201] "newlist":[ { "_id":"2a0398605f1114*****d69a167ebf9ed" "alistID":"100" "time":"21-10-10" }, { "_id":"2a0398605f1114*****d69a167ebf9ed" "alistID":"200" "time":"20-12-10" }, { "_id":"2a0398605f1114*****d69a167ebf9ed" "alistID":"201" "time":"10-10-10" } ]
2020-07-17 - 【笔记】云开发聚合实现分页,涉及跨表查询、逻辑计算、判断权限、数据格式化、限制输出
背景: 之前不会用聚合,因此把数据库结构分为了用户表、帖子表、喜欢表。小程序端请求一次列表,要根据帖子列表,循环查询用户表,并且还要做一系列的逻辑运算处理,计算当前帖子的权限、是否喜欢过、喜欢人数、是否有这个帖子管理权限等信息。 这样做有很多弊端: 处理速度慢,资源耗费严重,循环查询肯定慢且耗费资源,一个列表需要21次查询。需要写大量逻辑处理代码,如计算管理权限,喜欢数量、当前用户是否喜欢,格式处理等等。于是使用聚合进行了优化: 跨表查询数据格式化逻辑计算,权限判断、是否喜欢等数据统计,喜欢总人数权限判断,是否为管理员限制输出效果: 之前:上百行代码,多次查询,需要单独判断函数,处理时间在3000ms以上之后:几行代码,一次查询,直接查询时算出结果,处理时间在300ms以内 数据库结构 [图片] 代码实现: const { OPENID } = cloud.getWXContext(context) //构建查询条件 let query = null switch (Number(event.listType)) { case 0: query = db.collection('post').aggregate() .match({ //0我的 '_openid': OPENID }) .sort({ createTime: -1 }) .skip(20 * (event.pageNum - 1)) .limit(20) break; case 1: //1 随机 query = db.collection('post').aggregate() .match({ public: true, // feeling: _.gte(50) }) .sample({ size: 20 }) break; case 2: query = db.collection('post').aggregate() .match({ //2喜欢 likes: _.all([OPENID]) }) .sort({ createTime: -1 }) .skip(20 * (event.pageNum - 1)) .limit(20) break; case 4: query = db.collection('post').aggregate() .match({ //4指定 _id: event.id }) .sort({ createTime: -1 }) .skip(20 * (event.pageNum - 1)) .limit(20) break; } //使用聚合处理后续数据 let listData = await query .lookup({ from: "user", localField: "_openid", foreignField: "_id", as: "postList" })//联表查询用户表 .replaceRoot({ newRoot: $.mergeObjects([$.arrayElemAt(['$postList', 0]), '$$ROOT']) })//将用户表输出到根节点 .addFields({ day: $.dayOfMonth('$createTime'), month: $.month('$createTime'), year: $.year('$createTime'), isLike: $.in([OPENID, '$likes']), //是否喜欢 isLiked: $.in([OPENID, '$liked']), //是否喜欢过 isAdmin: $.eq([OPENID, 'oy0T-4yk7lCRFGDefpFC4Yvx_ppU']),//是否管理员 isAuthor: $.eq(['$_openid', OPENID]),//是否为作者 like: $.size('$likes'), //喜欢该帖子数 face: $.switch({ branches: [ { case: $.gte(['$feeling', 90]), then: 9 }, { case: $.gte(['$feeling', 80]), then: 8 }, { case: $.gte(['$feeling', 70]), then: 7 }, { case: $.gte(['$feeling', 60]), then: 6 }, { case: $.gte(['$feeling', 50]), then: 5 }, { case: $.gte(['$feeling', 40]), then: 4 }, { case: $.gte(['$feeling', 30]), then: 3 }, { case: $.gte(['$feeling', 20]), then: 2 }, { case: $.gte(['$feeling', 10]), then: 1 } ], default: 0 }) //根据心情值判断对应表情 }) .project({ postList: 0, userInfo: 0, liked: 0, likes: 0, city: 0, province: 0, country: 0, language: 0, nlp: 0, saveType: 0, }) //清楚掉不需要的数据 .end() return listData
2020-05-26 - 【云开发】数据库操作,在collectionA中筛选几千个id,在B中遍历id获取数据,有好办法吗?
本人是客户端开发,最近开始搞云开发 已经翻了一遍社区了,找到了关于联表的相关知识点 在我开始尝试之前,在这里发个问题,万一我失败了,这个帖子说不定就有大神回复了呢 主要是在collection A中,通过其中的“时间”这个属性,筛选出可能高达上万条的数据 这里有个有趣的点,A和B的主键都是玩家的openid,我筛选A其实也是想获得符合条件的openid 然后通过A筛选出的符合条件的id,去B中找到对应的数据,获取“通过的关卡个数” 全部加起来,最后算出这批玩家的“平均通关个数” 我在没有查社区之前,是通过遍历的方法,100个100个的筛选A的id,然后一个一个去B里找对应的数据 太慢啦!!! http调用竟然只有3秒,就超时了 各位大哥们有什么好的建议吗?
2020-07-23 - 关于云开发实时数据推送问题
[图片] [realtime listener] internal non-fatal error: sessionInfo lost after server event handling, this should never occur. (requestId ) 使用 云开发实时推送,watcher.close() 后再次监听会报这个错误 请问下,这个是什么原因导致的
2019-10-16 - security.mediaCheckAsync接口全部返回isrisky:0?
在服务端调用 security.mediaCheckAsync - 异步校验图片/音频是否含有违法违规内容接口 使用检测音频是否有违规内容 media_type:1 回调通知地址全部返回 isrisky:0 status_code: 0 尝试把media_url 设置为 https://baidu.com 回调参数同样为 isrisky:0 status_code: 0
2019-09-06 - security.mediaCheckAsync这个接口是失效了吗?根本检测不了
security.mediaCheckAsync是失效了吗,根本检测不了,传黄图和敏感语音也是返回正常没有风险,更骚的是随便写个字符串当作url,返回的status_code竟然是0!表明可以正常下载,求救
2019-08-08 - security.mediaCheckAsync 接口有问题?检测图片,无论什么都可以通过
同样的图片,在security.imgSecCheck,不能通过; 在security.mediaCheckAsync,都可以通过。 [图片]
2020-06-09 - security.mediaCheckAsync可以使用云函数调用吗?
使用云开发,录制音频安全校验可以使用云函数来调用嘛,文档没有很清晰的说明能或者不能,图片和文本的是可以使用云函数的,但是音频的可不可以?
2020-09-09 - ios打开h5网页很慢,尤其是前几次打开特别慢,后面打开就快了,请问什么原因导致的?
微信版本7.0.12,IOS版本13.4,网站ssl证书颁发者Let's Encrypt Authority X3 症状:微信扫码或直接打开请求地址后,页面白屏顶部进度条加载非常慢,大概要4-5秒请求才会到达我们服务器。 大多数是用户前几次打开页面的时候会出现,之后再打开会快一些。同样网络环境下,安卓手机打开很快,没有这个问题。最近4月份以后才出现这个问题,之前没有这种问题。 不是页面的问题,直接请求服务器地址跳转页面也会出现这个问题。
2020-07-07 - 云数据库中的Date属性字段,在wxs中如何格式化为日期字符?
在云数据库中的Date属性字段(db.serverDate创建的),读取到客户端显示的时候,用了wxs处理,但是把日期对象传递给wxs中的函数时,无法直接使用,提示getFullYear等方法不存在,用getDate(datefield)方法也提示非法格式。 请问在WXS中,如何正确格式化云数据库的日期对象?
2019-10-22 - 都 9102 年了,TypeScript 了解一下
前言 此文章为 SlugTeam 大前端技术沙龙 TypeScript 主题分享 PPT 文字内容。SlugTeam 大前端是腾讯互娱市场平台部营销技术中心下属几个开发组前端技术人员的联合,自去年 9 月起,SlugTeam 大前端每 3 个星期举行 1 次技术沙龙,沙龙主题由团队成员推荐并投票选出。 本次 3 月 28 日沙龙主题为 TypeScript。TypeScript 是由微软开发并开源的一门编程语言,其作为 Javascript 的超集被广大 Web 前端所熟知,即使在实际工作中尚未使用,也一定听说过 TypeScript。 接下来,让我们一起走近 TypeScript,了解这门越来越火的编程语言。 1. TypeScript 简介 1.1 JavaScript 的诞生 1995 年,网景公司发布了一门叫做 Javascript 的脚本语言,它由当时 34 岁的系统程序员 Brendan Eich 设计,仅仅用于在浏览器实现一些简单的网页互动,如表单验证。 Brendan Eich 做梦也没想到,自己花了十天仓促设计出来的 JavaScript,一经推出就被广泛接受,获得了全世界范围内大量的用户使用。JavaScript 这样连续的爆发式扩散增长,使得语言规格调整困难重重。 1996 年,微软公司也推出了自己的脚本 JScript。为了压制微软,网景公司决定申请 JavaScript 国际标准。 1997 年 6 月,第一个国际标准 ECMA-262 正式颁布。 从推出到颁布标准,JavaScript 仅用了一年半时间,语言的缺陷没有充分暴露,就已经被标准固化下来。 1.2 AJAX 的流行 在 2005 年以前,Web 应用程序开发还停留在完成简单的交互逻辑,受限于浏览器技术,Web 应用程序的交互行为十分单调,缺失像桌面应用那样丰富的交互,每次用户与服务器交互都需要重新刷新页面才能够看到效果。 2005 年初,Google 在其著名的 Web 交互应用程序中大量使用了 AJAX,如 Google、Google Map、Gmail等,无需刷新页面就能实现页面的异步更新。Google 对 AJAX 技术的实践,迅速提高了人们使用该项技术的意识。而使用了 AJAX 技术的 Web 应用程序,可以模拟出传统桌面应用的使用体验。 从此,Web 应用程序逐渐变得复杂而丰富,出现了越来越多的大型 Web 应用程序。 1.3 TypeScript 的由来 正如上面介绍的那样,JavaScript 设计之初就没考虑过可以用来编写大型应用。 JavaScript 诞生之初时的 Web 应用程序也就只有几十行或者几百行代码。到了 2010 年,Web 应用程序的代码已经达到了成千上万行。 2010 年的 JavaScript 标准为 ECMAScript 5.0 版本,尚未拥有类、模块等适合大型应用开发的概念。 与此同时 JavaScript 是动态脚本语言,这意味着没有静态类型,使得 IDE 无法提供诸如“代码补全”、“IDE 重构”(借助于 IDE 来对代码进行重构)、“属性查询”、“跳转到函数定义”等强大功能。 再加上 JavaScript 本身语言上的缺陷,使用 JavaScript 编写大型应用成了一件非常艰巨的任务。 微软卓越的工程师 Anders Hejlsberg(Delphi 和 C# 之父),留意到过去五年听到越来越多开发者吐槽 “JavaScript 难以编写大型应用程序”,使得他思考起未来 JavaScript 将何去何从。 Anders Hejlsberg 发现,不少开发者为了编写大型 Web 应用程序,会选择使用 GWT(Google Web Toolkit, 将 Java 代码编译成 JavaScript) 或者 Script# (将 C# 代码编译成 JavaScript),这样他们就可以借助 eclipse 这种强大的 IDE 辅助开发。 但是这种模式有着很大的缺点:在浏览器上面调试一堆由编译器生成的 JavaScript 是件很让人崩溃的事情。而且程序员写的是 Java,出来的是 JavaScript,这本身就是一件很违和的事情。 于是,Anders Hejlsberg 把心思放在了增强 JavaScript 能力上面,思考如何在提供诸如类、模块、可选的静态类型等概念的同时,又不牺牲 JavaScript 现有的优点。 2012 年 10 月,Anders Hejlsberg 带领团队开发出了首个公开版本的 TypeScript。 2 TypeScript 知识 按照官方的说法: (1) TypeScript 设计目标是开发大型应用 (2) TypeScript 是 JavaScript 的严格超集,任何现有的 JavaScript 程序都是合法的 TypeScript 程序,包括各种 JavaScript 库 (3) TypeScript 增加了静态类型、类、模块、接口和类型注解 接下来,我们将通过一些实际例子,来学习了解 TypeScript (非教程,若想深入学习请到官网)。 2.1静态类型批注 [代码]/** * @param (string) x */ function process(x){ x.name = 'foo'; var v = x + x; alert(v); } [代码] 以上是一段日常很常见的 JavaScript 代码,定义了一个名为 process 的函数,传入参数 x,并利用工具生成参数注释。 而在 TypeScript 中,我们可以选择给参数添加类型批注: [代码]function process(x:string){ x.name = 'foo'; var v = x + x; alert(v); } [代码] 加了类型批注后,编译时候就会启动类型检查:“name” 下面出现了红色的错误提示波浪线,将鼠标移动至上面,则提示 “Property ‘name’ does not exits on type ‘string’.”。 继续将鼠标移动到第二行的 “v” 上面,提示 “(local var) v:string”,TypeScript 根据 x 的类型批注,很智能地推断出了 v 的类型。 [代码]function process(x: boolean){ var v = x + x } [代码] 我们试着把 x 标注为 boolean 类型,修改后 ‘x + x’ 下面会出现错误提示波浪线,提示 “Operator ‘+’ cannot be applied to types ‘boolean’ and ‘boolean’.”。 [代码]function process(x:string[]){ x[0]. } [代码] 我们试着将 x 类型批注改为字符串数组,输入 ‘x[0].’ 后,编译器会显示对应的智能提示。 该功能十分强大,它使得开发者不需要记忆过多的 api 或 property,直接就能在右侧找到目标对应的 api 或者 property。 开发者也无需担心这些 api 或 property 会出现张冠李戴的问题,能展示出来的方法或者属性在语法上都是正确的。 像 sublime text 之类的编辑器插件,虽然也能够提供代码补全,但是有可能补全的 api 或者 property 是错误的,因为它们的原理是根据输入的字符串做一些简单的匹配。 例如输入 ‘document’,接着输入’.g’,也即是 ‘document.g’,插件匹配到该字符串后,代码补全提示仅仅显示 ‘getElementsByTagName’ 方法。 这在 TypeScript 未出现之前,的确为开发提供了很大的便利。但是和 TypeScript 的代码补全对比起来,还是显得不够智能。 传统的参数注释,遇上结构化的对象参数,就很束手无策了。而在 TypeScript 中,我们可以标注任何类型的参数: [代码]interface Thing{ a: number; b: string; c?: boolean; } function process(x: Thing){ return x.c; } var n = process({a:10, b:"hello"}); [代码] 上面代码中,在参数后面添加 ‘?’,表示参数可选。 [代码]interface Thing{ a: number; b: string; foo(s: string): string; foo(n: number): number; } function process(x: Thing){ return x.foo("12"); //return x.foo(2); } [代码] 此外,TypeScript 还支持方法重载。 上面的 foo 方法也可以写成下面的格式: [代码]interface Thing{ a: number; b: string; foo: { (s: string): string; (n: number): number; data: any; }; } function process(x: Thing){ return x.foo.data; //return x.foo(2); } [代码] 对于函数,TypeScript 也能够批注其为某个接口的实现。 [代码]interface Accumulator { clear(): void; add(x:number): void; result(): number; } function makeAccumulator(): Accumulator{ var sum = 0; return { clear: function() {sum = 0}, addx: function(value: number){sum += value}, result: function(){return sum} } } var a = makeAccumulator(); a.add(5); [代码] makeAccumulator 里面的 ‘addx: function(value: number){sum += value}’ 将会被标红,因为 Accumulator 接口并没有定义 addx 函数。 [代码]window.onmousemove = function(e){return e.clientX}; var hash = location.hash; [代码] TypeScript 内部维护了一份 DOM/BOM 的方法属性,省去了用户自己添加对应批注的功夫。例如将鼠标移动到 ‘hash’ 上面,会提示 ‘var hash: string’,TypeScript 就能自动推断出类型。 TypeScript 最终将会编译成 JavaScript,在 TypeScript 上面定义的类型,编译后实际上是不存在的。 [代码]addingTypes.ts function Greeter(greeting: string) { this.greeting = greeting; } Greeter.prototype.greet = function() { return "Hello, " + this.greeting; } let greeter = new Greeter("world"); let button = document.createElement('button'); button.textContent = "Say Hello"; button.onclick = function() { alert(greeter.greet()); }; document.body.appendChild(button); [代码] 上面 TypeScript 文件编译为 JavaScript 后,将是下面的样子: [代码]addingTypes.js function Greeter(greeting) { this.greeting = greeting; } Greeter.prototype.greet = function () { return "Hello, " + this.greeting; }; var greeter = new Greeter("world"); var button = document.createElement('button'); button.textContent = "Say Hello"; button.onclick = function () { alert(greeter.greet()); }; document.body.appendChild(button); [代码] 2.2 类 [代码]class Point{ x: number; y: number; private color: string; constructor(x: number, y: number){ this.x = x; this.y = y; this.color = "red"; } dist(){ return Math.sqrt(this.x * this.x +this.y * this.y);} static origin = new Point(0,0); } var p = new Point(10, 20); p.x = 10; p.y = 20; //p.color = "green" [代码] 在 TypeScript 的类中,访问修饰符 public、private、protected、static 和 JAVA、C# 等语言类似。 [代码]class Point{ private color: string; constructor(public x: number = 0, public y: number = 0){ this.color = "red"; } dist(){return Math.sqrt(this.x * this.x + this.y * this.y)} static origin = new Point(0,0); } var p = new Point(); p.x = 10; p.y = 20; [代码] TypeScript 支持默认值,用法和 ES6 类似。 接下来,我们看一下 TypeScript 如何实现类的继承。 [代码]class Point{ private color: string; constructor(public x: number = 0, public y: number = 0){ this.color = "red"; } dist(){return Math.sqrt(this.x * this.x + this.y * this.y)} static origin = new Point(0,0); } class Point3D extends Point{ constructor(x: number, y: number, public z:number){ super(x,y); } dist() { var d = super.dist(); return Math.sqrt(d * d + this.z * this.z) } } [代码] 让我们继续看下一段代码 [代码]class Tracker{ count = 0; start(){ window.onmousemove = function(e){ this.count++; console.log(this.count); } } } var t = new Tracker(); t.start(); [代码] 这段代码在 ‘count++’ 处有个错误提示, “Property ‘count’ does not exist on type ‘GlobalEventHandlers’”,这也是新手在写 JavaScript 时候容易犯的一个错误,而且还不容易察觉。 我们可以使用箭头函数来修复这错误。 [代码]class Tracker{ count = 0; start(){ window.onmousemove = e => { this.count++; console.log(this.count); } } } var t = new Tracker(); t.start(); [代码] 2.3 模块 [代码]module Utils{ export class Tracker{ count = 0; start(){ window.onmousemove = e => { console.log(this.count) } } } } module Utils { export var greeting = "hello" } var t = new Utils.Tracker(); t.start; [代码] 假如模块带有很长的命名空间,如下面的代码 [代码]module Acme.Core.Utils{ export class Tracker{ count = 0; start(){ window.onmousemove = e => { console.log(this.count) } } } } var t = new Acme.Core.Utils.Tracker(); t.start; [代码] 我们可以 import 的形式来缩短命名空间。 [代码]module Acme.Core.Utils{ export class Tracker{ count = 0; start(){ window.onmousemove = e => { console.log(this.count) } } } } import ACM = Acme.Core.Utils; var t = new ACM.Tracker(); t.start; [代码] 假如我们要使用诸如 Nodejs 的模块,我们要先安装对应的 @types 文件,基本上流行的库都有社区维护的 type 文件。 网站 [代码]https://microsoft.github.io/TypeSearch/[代码] 可以查询相关库的 type 文件。 接下来拿 Nodejs 做个演示。 [代码]yarn global add typescript cd typescript_demo tsc --init yarn add @types/node [代码] 在目录打开 [代码]tsconfig.json[代码] 文件,修改对应字段 [代码]"typeRoots": [ "./node_modules/@types" ], "esModuleInterop": true [代码] 创建 server.ts 和 hello.ts,代码分别如下 [代码]server.ts import * as http from 'http' //import http from 'http' //上面写法会报“TS1192: Module '"http"' has no default export” export function simpleServer(port: number, message: string){ http.createServer((req, res) => { res.writeHead(200, {'Content-Type': 'text/html'}); res.write(`<h1>${message}</h1>`); res.end() }).listen(port) } [代码] [代码]hello.ts import {simpleServer} from './server'; simpleServer(1337, "Greetings Channel 9"); console.log("Listening..."); [代码] 保存后,编译 hello.ts 并运行 hello.js。 [代码]tsc hello.ts node hello [代码] 在浏览器访问 [代码]localhost:1337[代码] 可看到页面输出 [代码]Greetings Channel 9[代码]。 2.4 Visual Studio Code 与 TypeScript Visual Studio Code 是前端界最流行的 IDE,由微软开发并开源。 Visual Studio Code 加上 TypeScript,代码重构将变得很轻松。 我们在进行代码重构的时候,常常会遇上这么一种情况:修改了方法名或者属性名,还得找到引用它们的地方,逐个修改。假如引用的地方很多,修改将很耗费时间,也很繁琐,而且还可能修改得不够彻底,造成程序错误。 有了 TypeScript 后,在 Visual Studio Code 上,只需要在方法或者属性定义处,右键选择“重命名符号”,输入新的名字,回车后所有的引用将自动更新该变化。 2.5 TypeScript 与热门前端框架 前端目前流行三大框架: Angular、React、Vue。 其中 Angular 基于 TypeScript 来开发,React 在开发的时候可以选择引入 TypeScript,而对于 Vue,作者是这么说的: 必须要承认的是,2.x 的 TS 支持显然跟 React 和 Angular 是有差距的,这也是为什么 3.0 要加强这一块 这里推荐看一下尤雨溪在知乎上面的回答:TypeScript 不适合在 vue 业务开发中使用吗? 虽然目前 Vue 对 TypeScript 的支持不是很完美,但是大部分 TypeScript 的功能还是可以用,应用到生产环境中是个不错的选择。 Vue CLI3 已经支持生成 TypeScript 项目,假如是使用 React 的话,可以选择用 create-react-app 创建项目。 3. TypeScript 相关 3.1 TypeScript 与 ESLint 在使用 TypeScript 的时候,一般也会加入 TSLint,TSLint 事实上已经是 TypeScript 项目的标准静态代码分析工具。TSLint 的生态由一个核心的规范集,社区维护的多种自定义规则以及配置包组成。 ESLint 是 JavaScript 的标准静态代码分析工具。相对于 TSLint,ESLint 支持 TSLint 所缺少的很多功能,如条件 lint 配置和自动缩进。 有一段时间,TypeScript 的代码检查主要有两个方案:使用 TSLint 或使用 ESLint + typescript-eslint-parser。 在 2019 年年初,由于效能问题, TypeScript 官方决定全面采用 ESLint。 接下来 ESLint 团队将不再继续维护 typescript-eslint-parser,他们会封存储存库,也不会在 Npm 发布 typescript-eslint-parser,原本使用 typescript-eslint-parser 的开发者应使用 typescript-eslint/ parser 替代 3.2 Deno “Node 现在太难用了!”,Nodejs之父 Ryan Dahl 去年年初要开发一款 JavaScript 数据互动分析工具的时候,忍不住抱怨自己十年前创造的技术。 尽管 Nodejs 大受欢迎,但是 Ryan Dahl 在 2018 年的演讲时,坦言 Nodejs 有十大设计错误。 Ryan Dahl 决定偿还当年的技术债,打造一个全新的服务端 JavaScript 运行环境,也就是 Deno 项目。 Deno 跟 Nodejs 一样采用了 V8 引擎,但 Deno 是以 TypeScript 为基础,提高了代码的准确性,并将编译器内置到 Deno 可执行文件中。 需要一提的是,Deno 项目现在属于飞速发展的阶段,源码随时可能更新。 4 总结 4.1 TypeScript 优点 解决了 IDE 无法智能提示的问题 函数文档化,无需看接口文档即可直观了解函数参数及对应类型 类型检查以及错误提示 放心地进行代码重构 提供了业界认可的类、泛型、封装、接口面向对象设计能力,以提升 JavaScript 的面向对象设计能力 4.2 TypeScript 缺点 npm 绝大多数模块没有类型注解,假如在 @types 里面也没有找到对应的类型定义文件 (*.d.ts),需要自己手写一份 额外的语法学习成本 TypeScript 配合 webpack 或者 babel 等工具时需要额外处理一些异常 5 后记 在沙龙最后的讨论阶段,SlugTeam 成员一致认为 TypeScript 代表了前端未来发展的方向,项目迁移成本不算高,可以逐步推广起来。 还没了解 TypeScript 的同学,强烈安利:)
2019-04-17 - 适配刘海屏和全面屏的一些小心得
今年开始各路刘海和全面屏手势的手机已经开始霸占市场,全面屏和刘海屏的适配也必须提上日程。 相信大家也一定会有第一次将未适配的小程序放到全面屏或刘海屏手机上的尴尬体验。 尤其是在导航栏设置为custom时,标题与胶囊对不齐简直逼死强迫症。。 微信官方也没有出一个官方的指导贴帮助开发者。 这里仅总结一下个人关于这个问题的一些处理方式,如有疏漏烦请指正补充。 适配的关键在两个位置即额头和下巴,头不用说自然是关于刘海的。 小程序的头的高度主要分为2个部分 1.statusBarHeight 该值可以在app onLaunch 调用wx.getSystemInfoSync() 获取到 a)刘海 高度44 [图片] b)无刘海 ios高度20 安卓各不相同 [图片] 2.胶囊高度 即下图高度 [图片] 在查阅社区问答后了解到小程序给到的策略是ios在模拟器下统一是44px,ios在真机下统一是40px(感谢指正@bug之所措 ),而安卓下统一是48px,因此我们又可以在wx.getSystemInfoSync() 中获取到系统之后得到胶囊高度。 总的导航栏高度即这两个高度之合。本人项目中是将导航做成组件并给到slot,方便各个页面配置。 开发者工具 1.02.1810190 及以上版本支持在 app.json 中声明 usingComponents 字段,在此处声明的自定义组件视为全局自定义组件,在小程序内的页面或自定义组件中可以直接使用而无需再声明。 目前小程序还支持在单个页面配置custom,也可以配合使用~ 另一个需要关注的则是底部,参考的文章是 https://www.jianshu.com/p/a1e8c7cf8821 重点是在于在全面屏的手机的底部需要流出34px的空白给到全面屏返回手势操作,此外由于全面屏屏幕圆边还可能使一些按钮或功能无法正常使用。 那么首先如何判断是否是全面屏呢?个人的做法是判断屏幕高度是否大于750,iphone的plus系列高度在736,正好在这个范围之内,当然750不一定准确,如果出现疏漏烦请补充。 涉及到底部的主要是弹出的操作菜单、tabBar和底部定位的按钮等。这里做了一个简单的代码片段。 https://developers.weixin.qq.com/s/fnU0n8mv7o5M 希望能够帮助到大家,也欢迎交流~
2019-01-03