为了账号安全,请及时绑定邮箱和手机立即绑定
2. 国际化

上述例子发现输出的结果是英文的,显然是不适合在国内环境使用,moment.js 提供了国际化支持,在现有的库中,moment 支持的语言可以说是相对完备了。通过引入对应的国际化资源(语言文件),来切换语言。<script src="https://cdn.bootcdn.net/ajax/libs/moment.js/2.27.0/moment.min.js"></script><script src="https://cdn.bootcdn.net/ajax/libs/moment.js/2.27.0/locale/zh-cn.min.js"></script><script> var now = moment().calendar(); console.log(now);// 输出当前日历时间 moment().startOf('hour').fromNow(); // 相对这个小时过去了多少分钟 var timestamp = 1593933593236; // 2020年7曰5日下午15点20分38秒 moment(timestamp).fromNow(); // 相对时间戳多久前</script>有关国际化的更多内容可以参考文档。

3. 国际化

国际化的功能离不开错误码的支持,客户端指定语言到服务端去请求,当出错了服务端会根据错误码和语言找到对应的国际化提示语。从上面图中我们发现,错误码不仅仅是客户端与服务端的交互,后台各个服务间的交互也需要约定的一套错误码。一般一个系统的错误码 code 都是唯一确定的。msg 不同场景下可能不一样,提供给用户的肯定是需要友好且不能暴露底层细节,给开发人员看的就要详细专业的错误内容。网关服务上面维护着多套不同语言的错误码提示语,响应的时候会根据客户端带的 Lang 信息进行国际化转译。模块模块编码错误编码底层描述中文提示语英文提示语库存10001商品规格表关联有误商品不存在goods don’t exist一般国际化的系统中会有多份 xxx_lang.properties文件,每一份代表一种语言的消息提示语。中文一般会转为 Unicode 编码进行存储(这个过程一般开发工具可以设置自动转),这样的处理可以规避不同开发环境下不同编码导致中文乱码。

3.1 微信小程序 API

uni-app 的 API 与微信小程序 API 基本一致。掌握微信小程序 API 对后面的开发很有帮助。微信小程序 API 文档:https://developers.weixin.qq.com/miniprogram/dev/api/

视频页面:ViewPager

ViewPager 是一种可以让用户通过左右滑动来切换页面的控件,通过它我们可以展示超过屏幕尺寸大小的内容,在某种程度上它可以说是实现多页面的最佳方式,同时 ViewPager 还支持任意动态的添加/删除页面。比如我们可以将不同的类别的内容分别放在不同页面当中,然后通过滑动切换不同的类别从而给用户展示不同的页面,这个在类似百度App等新闻类App中非常适用。在 ViewPager 中插入“娱乐”、“国际”、“体育”、“星座”等等新闻类别,然后在不同的 View 中展示不同的新闻内容,还可以根据用户的喜好动态增加/删除某些页面,接下来就一起来看看如何完成多页视图。

3.1 打包为微信小程序

注册微信小程序账号,获取到 AppID,我们后面配置的时候会用到。在 HBuilderX 工具栏,点击发行,选择小程序-微信。输入小程序名称和 AppID,单击发行就可以了。这样我们就会获得一个微信小程序的打包文件,接下来我们来发布微信小程序项目,打开微信小程序开发者工具,导入刚刚生成的微信小程序项目的打包文件,在微信小程序开发者工具中先测试一下,项目运行是否正常,项目测试没有问题后,点击右上角>>按钮,上传代码就可以发布微信小程序了,最后等待微信团队审核通过,别人就可以在线上访问到你的项目了。

2.2 mpvue 框架与 uni-app 框架性能对比

uni-app 框架的技术团队对比过 wepy/mpvue/taro/uni-app/原生小程序的性能,测试项目包括长列表加载、组件状态更新这两个比较容易出现性能问题的实例。最终得出的结论是 uni-app 性能更优,具体结果如下:微信原生开发手工优化,uni-app>微信原生开发未手工优化,taro > wepy > mpvue官网性能对比的文章:小程序开发:用原生还是选框架(wepy/mpvue/taro/uni-app)链接:https://ask.dcloud.net.cn/article/35947我们可以看到 uni-app 不管从开发维护还是项目性能来讲,都是更优的。还有很多其他的优点,比如:uni-app 项目支持在更多的平台上面发布上线、生态更加完善等,这些都是我们更建议选择 uni-app 框架的原因。下面我们来看看如果将mpvue 项目转换成 uni-app 项目吧。

4.1 乐观锁数据表

乐观锁的使用十分广泛,我们也推荐你在实际的开发中使用乐观锁,接下来,我们以一个例子来详细的说明一下乐观锁。我们新建一个测试数据表 imooc_order :DROP TABLE IF EXISTS imooc_order;CREATE TABLE imooc_order( id int PRIMARY KEY, price decimal(10,2), -- version 字段作为乐观锁版本控制位 version int NOT NULL DEFAULT 0);INSERT INTO imooc_order(id,price,version)VALUES (1,23.2,1);注意: 我们已经在表中添加了 version 字段

3. Button 的样式

不同的系统会有不同的默认 Button 样式,但是它们都有一个共同点——丑。相比于 TextView 而言,Button 是一个互动感很强的控件,除了设置字体字号,还需要有形状、背景、颜色、点击态等等样式变化。特别是在游戏及娱乐类 App 中 ,Button 的样式及变化效果将直接影响用户体验,所以这里将重点讲解几种设置样式的方法。

6.2 Google App Engine

Google App Engine 提供一整套开发组件来让用户轻松地在本地构建和调试网络应用,之后能让用户在Google强大的基础设施上部署和运行网络应用程序,并自动根据应用所承受的负载来对应用进行扩展,并免去用户对应用和服务器等的维护工作。同时提供大量的免费额度和灵活的资费标准。在开发语言方面,支持多种语言,包括Java 、Python、 PHP、 Go 与 Node.js等等。创建 Google App Engine 项目,事先需要下载 App Engine SDK, 在创建项目时需要指定SDK所在路径。Google App Engine 在国内使用是受限制的,需要用 gmail 帐户注册与验证,所以用的不多,这里不再过多介绍。有兴趣的同学可以参考官网。

4. 乐观锁

乐观是一种积极的解决问题的态度。所谓乐观锁认为系统中的事务并发更新不会很频繁,即使冲突了也没事,大不了重新再来一次。基本思想:每次提交一个事务更新时,查看要修改的数据从上次读取以后有没有被其它事务修改过,如果修改过,那么更新就会失败。实现方案:在实体中增加一个版本控制字段,每次事务更新后就将版本 (Version) 字段的值加 1。Tips: 乐观锁本质就是版本控制管理的实现,记录的每一次更新操作都会以版本递增的方式进行记录。一个事务在更新之前,先获取记录的当前版本号,更新时,如果版本还是最新的则可以更新,否则说明有事务比你先更新,则需要放弃。或者重新查询到最新版本信息后再更新。所以,在乐观锁的实现中,冲突是常态。实现过程:在学生实体类中添加新属性,用来记录每次更新的版本号。public class Student implements Serializable {//省略…… @Versionprivate Long version;//省略…… }stu = (Student) session.get(Student.class, new Integer(1));System.out.println("当前版本号:"+stu.getVersion);//模拟延迟,如果在这个时间内有其它事务进行了更新操作,此事务的更新不会成功Thread.sleep(30000);stu.setStuName("Hibernate");transaction.commit();好了,悲观也好,乐观也好,只是一种解决问题的态度。对于这两种态度,咱们要总结一下。乐观锁:优势:性能好,并发性高。缺点:用户体验不好,可能会出现高高兴兴去更新,却告知已经有人捷足先登了。悲观锁:优势:锁住记录为我所用,没修改完成之前,其他事务只能瞪眼瞧着,时间虽然延迟,至少心里有底。缺点:并发性不好,性能不高。Hibernate 的其它性能优化:随时使用 Session.clear()及时清除 Session 缓存区的内容;1+N 问题 ( 一条 SQL 语句能解决的问题用了很多条 SQL 语句来实现) ;使用 Criteria 查询可以解决这个问题;Lazy 加载:需要时,使用 get() 方法发出 SQL 语句。使用类似于 from Student s left join s.classRoom c 的关联查询语句。缓存使用:在对象更新、删除、添加相对于查询要少得多时, 二级缓存的应用将不怕 n+1 问题,因为即使第一次查询很慢,之后直接缓存命中也是很快的,刚好又利用了 n+1。

2. 什么是时区

我们知道,地球上的不同地区是有时差的,因此想要准确定位一个时刻,还需要加上时区。时区有以下 3 种表示方式:GMT 或者 UTC 加时区偏移表示:例如:GMT+08:00 或者 UTC+08:00 表示东八区;缩写表示:例如:CST 表示 China Standard Time(中国标准时间),但是此缩写也可表示 Central Standard Time USA(美国中部时间),容易混淆不推荐使用;洲 / 城市:例如:Asia/Shanghai 表示上海所在地的时区。注意城市名称不是任意的城市,而是由国际标准组织规定的城市。

3. 乐观锁

定义:乐观锁是相对悲观锁来说的,它认为数据在一般情况下不会造成冲突,所以在访问记录前不会加排它锁,而是在进行数据提交更新的时候,才会正式对数据冲突与否进行检测。乐观锁的实现:依旧拿数据库的锁进行比较介绍,乐观锁并不会使用数据库提供的锁机制, 一般在表中添加 version 宇段或者使用业务状态来实现。 乐观锁直到提交时才锁定,所以不会产生任何死锁。Java 中的乐观锁:我们之前所学习的 CAS 原理即是乐观锁技术,当多个线程尝试使用 CAS 同时更新同一个变量时,只有其中一个线程能更新变量的值,而其它线程都失败,失败的线程并不会被挂起,而是被告知这次竞争中失败,并可以再次尝试。Tips:我们这里所说的对于乐观锁,当多个线程尝试使用 CAS 同时更新同一个变量时,只有其中一个线程能更新变量的值,而其它线程都失败。注意失败两字,失败意味着有操作,而悲观锁是等待,意味着不能同时操作。

3.1 乐观锁实施方案

乐观锁不全依赖于数据库,一般情况下我们都是在代码层面上来完成它的,主流的设计思路是这样的:我们在数据表中添加一个字段version,version 代表版本号,字段类型为整型。当我们获取数据时,假设得到它的version字段为n,执行完其它操作对该数据进行更新时,会执行UPDATE ... SET version=n+1 WHERE version=n。如果在更新时,数据已经被别人更新过了,那么该数据的version字段已经不是n了,那么此时修改就会失败,反之修改就会成功。可以看到,乐观锁就像它的名称一样乐观,适合数据读多写少的场景,因为实际上并没锁住数据,所以性能十分可观;而悲观锁则与之相反,适合写多读少的场景,盲目的排他性一定程度上会大幅影响性能。

4.3 运行uni-app

npm run dev:%PLATFORM%%PLATFORM% 可取值如下:值平台5天H5支付宝支付宝小程序mp-百度百度小程序mp-微信微信小程序头条字节跳动小程序mp-qqqq小程序Tips:dev 模式编译出的各平台代码存放于根目录下的 /dist/dev/ 目录,打开各平台开发工具选择对应的平台目录即可进行预览(h5 平台不会在此目录,存在于缓存中);build 模式编译出的各平台代码存放于根目录下的 /dist/build/ 目录,发布时选择此目录进行发布;dev 和 build 模式的区别:dev 模式有 SourceMap 可以方便的进行断点调试;build 模式进行代码进行压缩,体积更小更适合发布为正式版应用;进行环境判断时,dev 模式 process.env.NODE_ENV 的转换开发,构建模式 process.env.NODE_ENV 的转换生产。

4.3 乐观锁总结

可以看到,乐观锁虽然有缺陷,它会使更新失败,因此必须重复获取数据然后重试,但是它保证了数据的正确性和完整性。在读多写少的场景下,乐观锁不会出现太多的重试,当然如果出现了很多重试,证明场景已经可能不是读多写少了,可以尝试换方案了。乐观锁的实现也颇为简单,不需要任何第三方依赖,你完全可以自己直接实现,不过仍然有一些第三方框架提供了开箱即用的乐观锁,你可以根据自己的使用语言和生态去查找相应的乐观锁框架。

3.3. 乐观读模式

这是一种优化的读模式。乐观读模式相关的几个方法如下。tryOptimisticRead () 方法:非阻塞尝试乐观获取读锁,只有当写锁没有被获取时返回一个非 0 的 stamp 。乐观读取模式适用于短时间读取操作,降低竞争和提高吞吐量。在使用时一般需将数据存储到一个副本中,在后继处理中用于对比数据是否是最新状态;validate (long stamp) 方法:用于检查在获取到读锁 stamp 后,锁有没被其他写线程抢占。如果写锁没有被获取,那么 validate () 方法返回 true。可多次调用验证这一信息。另外,此类也提供了一组读写锁之间的转换方法:tryConvertToWriteLock (long stamp) 方法:尝试转换为写锁。转换条件:tryConvertToReadLock (long stamp) 方法:尝试转换为悲观读锁。tryConvertToOptimisticRead (long stamp) 方法:尝试转换为乐观读锁。注意此类的编程方法有这样一个共通特征:所有获取锁的方法,都返回一个邮戳(Stamp),Stamp 为 0 表示获取失败,其余都表示成功;所有释放锁的方法,都需要一个邮戳(Stamp),这个 Stamp 必须是和成功获取锁时得到的 Stamp 一致;下面我们举一个具体的编程例子。

4. 各平台小程序组件存放目录

uni-app 还有一个非常牛的地方,就是支持在 App 和小程序中使用小程序自定义的组件,支持情况如下:平台支持情况小程序组件存放目录 H5 从 HBuilderX2.4.7 起,支持微信小程序组件 wxcomponentsApp(不含 nvue)支持微信小程序组件 wxcomponents 微信小程序支持微信小程序组件 wxcomponents 支付宝小程序支持支付宝小程序组件 mycomponents 百度小程序支持百度小程序组件 swancomponents 字节跳动小程序支持字节跳动小程序组件 ttcomponentsQQ 小程序支持 QQ 小程序组件 wxcomponents

3.3 自定义平台

如果我们还有其他的开发需求,比如微信服务号开发,uni-app 中没有对应的平台,我们就可以自定义一个,在 package.json 文件中增加 uni-app 扩展节点。实例: "uni-app": { "scripts": { "wx-platform": { //自定义编译平台配置,可通过cli方式调用 "title":"微信服务号", // 自定义平台名称,在HBuilderX中会显示在 运行/发行 菜单中 "env": {//环境变量 "UNI_PLATFORM": "mp-weixin" //基准平台,仅限:h5、mp-weixin、mp-alipay、mp-baidu、mp-toutiao、mp-qq }, "define": { //自定义条件编译 "WX-PLATFORM": true //自定义条件编译常量,建议为大写 } } } }Tips:通过 HBuilderX 可视化界面创建的项目一般是没有 package.json 文件的。通过vue-cli命令行方式创建的项目默认有 package.json 文件;package.json文件中不允许出现注释,否则扩展配置无效,所以我们配置时需要将所有注释都删掉;使用自定义平台功能,vue-cli需更新到最新版,HBuilderX需升级到 2.1.6+ 版本。使用自定义平台实例:// #ifdef WX-PLATFORM console.log("微信服务号平台特有代码")// #endif

6. Atomic 操作实现乐观锁

为了更好地理解悲观锁与乐观锁,我们通过设置一个简单的示例场景来进行分析。并且我们采用悲观锁 synchronized 和乐观锁 Atomic 操作进行分别实现。Atomic 操作类,指的是 java.util.concurrent.atomic 包下,一系列以 Atomic 开头的包装类。例如 AtomicBoolean,AtomicInteger,AtomicLong。它们分别用于 Boolean,Integer,Long 类型的原子性操作。Atomic 操作的底层实现正是利用的 CAS 机制,而 CAS 机制即乐观锁。场景设计:创建两个线程,创建方式可自选;定义一个全局共享的 static int 变量 count,初始值为 0;两个线程同时操作 count,每次操作 count 加 1;每个线程做 100 次 count 的增加操作。结果预期:最终 count 的值应该为 200。悲观锁 synchronized 实现:public class DemoTest extends Thread{ private static int count = 0; //定义count = 0 public static void main(String[] args) { for (int i = 0; i < 2; i++) { //通过for循环创建两个线程 new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(10); } catch (Exception e) { e.printStackTrace(); } //每个线程让count自增100次 for (int i = 0; i < 100; i++) { synchronized (DemoTest.class){ count++; } } } }). start(); } try{ Thread.sleep(2000); }catch (Exception e){ e.printStackTrace(); } System.out.println(count); }}结果验证:200乐观锁 Atomic 操作实现:public class DemoTest extends Thread{ //Atomic 操作,引入AtomicInteger。这是实现乐观锁的关键所在。 private static AtomicInteger count = new AtomicInteger(0); public static void main(String[] args) { for (int i = 0; i < 2; i++) { new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(10); } catch (Exception e) { e.printStackTrace(); } //每个线程让count自增100次 for (int i = 0; i < 100; i++) { count.incrementAndGet(); } } }). start(); } try{ Thread.sleep(2000); }catch (Exception e){ e.printStackTrace(); } System.out.println(count); }}结果验证:200代码解读:此处主要关注两个点,第一个是 count 的创建,是通过 AtomicInteger 进行的实例化,这是使用 Atomic 的操作的入口,也是使用 CAS 乐观锁的一个标志。第二个是需要关注 count 的增加 1 调用是 AtomicInteger 中 的 incrementAndGet 方法,该方法是原子性操作,遵循 CAS 原理。

2. 实际原因

其实真实的原因是因为雪碧的英文名字是Sprite,而雪碧图的英文名是CSS Sprites,他俩同样都有Sprite这个词。左边是雪碧在国内的 Logo,右边是国外的 Logo。可以看到本来在没进入中国市场之前人家就叫Sprite(精灵),只不过进入了中国市场之后,中国区的负责人表示:用户去商店买汽水的时候如果对老板说:老板你这里有没有精灵?听起来就会感觉很奇怪,所以咱们不要被Sprite这个单词给限制住了,咱们应该起一个更符合中文语义的名字,于是乎“雪碧”诞生了。而雪碧图在国外叫做 CSS Sprite(CSS精灵)反正 Sprite 在国内被叫雪碧,那干脆不如咱们就叫它雪碧图吧!——来自最先接触到这项技术的人。所以后来接触这项技术的人也就跟随前人一起叫它雪碧图了。

3.4 平台标识

也就是%PLATFORM% 可取值如下:值平台APP-PLUS5+AppH5H5MP-WEIXIN微信小程序MP-ALIPAY支付宝小程序MP-BAIDU百度小程序MP-TOUTIAO头条小程序MP-QQQQ小程序MP微信小程序/支付宝小程序/百度小程序/头条小程序/QQ小程序

2.标准

HTML3.2 以前的标准是由 IETF 制定。IETF 互联网工程任务组(The Internet Engineering Task Force),成立于1985年底,是全球互联网最具权威的技术标准化组织,主要任务是负责互联网相关技术规范的研发和制定,当前绝大多数国际互联网技术标准出自IETF。 IETF 的工作成果主要以RFC文档的途径发布。HTML 3.2 开始,由 W3C 制定标准。W3C 万维网联盟( The World Wide Web Consortium )创建于1994年,是Web技术领域最具权威和影响力的国际中立性技术标准机构。到目前为止,W3C 已发布了200多项影响深远的Web技术标准及实施指南,如广为业界采用的超文本标记语言( HTML )、可扩展标记语言( XML )以及帮助残障人士有效获得Web内容的信息无障碍指南( WCAG )等,有效促进了Web技术的互相兼容,对互联网技术的发展和应用起到了基础性和根本性的支撑作用。

2.1 微框架

Flask 是一个 Python 实现的 Web 开发微框架,但是这个“微”并不代表着 Flask 功能比较简陋、有所欠缺。微框架中的 “微” 意味着:Flask 旨在保持核心简单而易于扩展;Flask 不会替用户做出太多决策,比如使用何种数据库;Flask 的选项(比如使用何种模板引擎) 通常有多个,用户很容易替换。默认情况下,Flask 不包含数据库抽象层、模板引擎、身份认证或其它任何已有多种库可以胜任的功能,如下图所示。然而,Flask 支持用扩展来给应用添加这些功能,应用程序可以很方便的集成这些扩展。众多的扩展提供了数据库集成、表单验证、上传处理、各种各样的开放认证技术等功能。

1. 简介

安全密钥交换与非对称密钥算法,推动了网络安全通信的发展,在认证与安全诉求越来越迫切的环境下,一些厂商嗅探到市场的机遇,逐渐推出了相应的认证服务。信息的安全关系到国家安全和经济利益,因此我国这几年也在积极探索网络安全的标准化建设,这些标准并不仅仅局限于证书的签名算法,也包括了物理厂房的建设,人员的管理流程规则制度。当然我们的网络安全建设一方面要保证自己足够安全,另一方面也要对接国际,毕竟今天的网络今天的经济都是全世界共同的。

ECharts 饼图

在日常工作学习中,我们经常需要把有限的内容按照一定的比例进行分开,比如一天的时间用来工作,学习,娱乐,休息这样的时间需要进行按比例合理划分。一般这样多比较占比的时候大家一般都会使用饼图表示。饼图又称饼状图,用于描述量、频率或百分比之间的相对关系。

2.1 微前端

微前端 尚处在发展时期,其核心概念和 微服务 相似。现阶段较为常用的微前端框架为 single-spa 和 qiankun,后者是基于前者实现的。该技术能做到 技术栈无关,即一个应用,能由多个不同技术的子应用构成,同时做到子应用的相互隔离,这里的隔离就可以选择采用 Web Components 实现。

3. for … in

for…in 循环可以用来遍历对象的属性名。var obj = { name: '小红', age: 12, hobby: ['打篮球', '唱歌'],};for (key in obj) { console.log(obj[key]);}// 输出:// "小红"// 12// ["打篮球", "唱歌"]每一次遍历拿到的 key 就是对象的某一个属性名,当属性名被遍历完后会自动退出循环。有部分 key 是无法遍历到的,具体规则可以参阅对象章节。

3. CDN

可以通过 CDN 引入 ECharts 文件:<!-- bootstrap 服务 --><!-- bootstrap 提供的免费CDN服务,亲测非常稳定 --><script src="//cdn.bootcss.com/echarts/4.5.0/echarts.common.js"></script><!-- 七牛云存储服务 --><!-- 国内速度稳定,开放性强 --><script src="//cdn.staticfile.org/echarts/4.5.0/echarts.common.js"></script><!-- jsdeliver 服务 --><!-- 微软的CDN服务,虽然国内访问速度比不上国内CDN,但速度不至于太慢,有国际化需求的可以试试 --><script src="//cdn.jsdelivr.net/npm/echarts@4.5.0/echarts.common.js"></script><!-- cdnjs 服务 --><!-- 一个非常全的CDN服务,存储了大多数主流的js、css、图片库 --><script src="//cdnjs.cloudflare.com/ajax/libs/echarts/4.5.0/echarts.common.js"></script>

3.1 Gradle 构建 app bundle

如果我们更喜欢从命令行生成 app bundle,请在应用的基础模块上运行 bundleVariant Gradle 任务。 例如,以下命令会为基础模块的调试版本构建 app bundle:./gradlew :base:bundleDebug如果我们要构建已签名的 bundle 以上传到 Play 管理中心,则需要先使用应用的签名信息来配置基础模块的 build.gradle 文件。如何配置 Gradle 来为我们的应用签名将在后面介绍。当我们配置好 build.gradle 之后,我们就可以构建应用的发布版本,Gradle 会自动生成 app bundle,并使用我们在 build.gradle 文件中提供的签名信息为其签名。

3.1 主体采用 uni-app

如果我们主体采用 uni-app 进行开发,只是部分功能的实现使用原生开发,这样可以找一些原生项目的插件用来配合开发。目前更多项目是使用原生插件扩展的方式来进行开发的。这样代码实现就不只是通过 uniapp 框架来实现的了,而是通过原生 API 实现的,uniapp 只是负责调用一下。这里需要注意的是,如果想要将项目离线打包,就不应该使用原生 SDK,而应该使用 App 离线 SDK。App 离线打包 SDK,是把 App 运行环境(runtime)封装为原生开发调用接口,开发者可以在自己的 Android 及 iOS 原生开发环境配置工程使用。参考资料:https://nativesupport.dcloud.net.cn/AppDocs/README接下来我们举个自定义扫码的例子,看看如何在 uni-app 中如何扩展 5+ 的原生界面控件。在 uni-app 开发中,平台其实给我们提供的扫码 API,但是并不能满足我们所有扫码的需求,比如想要自己自定义扫码框的颜色。实例:// uni-app 中的扫码功能直接调用 plus API就可以了,而扩展5+的原生界面控件要等 plusready 后再调用 plus API。var plusReady = function (callback) { if (window.plus && window.plus.isReady) { callback(); } else { document.addEventListener('plusready', function () { callback(); }, false); }};//创建 Barcode 实例对象,可以自定义扫码框的位置大小和颜色var barcode = plus.barcode.create('barcode', options.types, options.styles);

首页上一页1234567下一页尾页
直播
查看课程详情
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号