当前位置: 首页 > news >正文

【微信小程序实战教程】之微信小程序原生开发详解

微信小程序原生开发详解

微信小程序的更新迭代非常频繁,几乎每个月都会有新版本发布,这就会让初学者感觉到学习的压力和难度。其实,我们小程序的每次版本迭代都是在现有小程序架构基础之上进行更新的,如果想要学好小程序开发技术,打牢基础是必不可少的学习环节。本章就对小程序的基础架构进行详细地讲解。熟练掌握本章的小程序框架基础知识,对后面学习小程序开发至关重要。

1 小程序代码组成

1.1 小程序与传统前端开发

小程序开发与传统的前端开发有着很大的区别,不管什么类型的前端技术,都是由以下三种技术组成:

  • 静态标签文件(HTML),静态标签决定了前端页面的基本骨架是如何构成的;
  • 样式文件(CSS),样式文件可以让前端的页面凸显自身的美术风格;
  • 动态脚本文件(JavaScript),动态脚本可以让前端页面与用户进行交互。

静态标签组成了前端的骨架,让渲染工具明白前端是由哪些标签组成的。但是原始的静态标签是没有样式的,并不具备很强的观赏性,如果想要让前端产品更加美观,并且具有独特的美术风格,那么就需要使用到样式文件。样式文件主要由不同类型的选择器组成,开发人员可以将样式通过不同范围的选择器添加到页面的UI组件上。如果只是静态标签和样式是无法让一个前端页面动起来的,例如用户点击页面中的一个按钮,需要弹出一个提示框,这就需要使用到动态脚本,动态脚本决定了前端页面如何与用户进行交互,例如弹窗的时机、广告图片的滚动速度,以及向后端请求数据等,这些都是由动态脚本来实现的。

小程序虽然与传统的前端开发有所区别,但是也脱离不了前端的固定模式。小程序拥有四种文件类型,分别是:

  • wxml文件,类似于传统前端的HTML文件,用于静态标签的编写;
  • wxss文件,与传统前端的CSS文件功能类似,用于页面样式的编写;
  • js文件,与传统前端的JavaScript脚本功能类似,用于页面交互逻辑的编写;
  • json文件,在传统前端页面开发中没有json文件,小程序的json文件主要用于页面配置,如页面标题、颜色、样式的配置等。

新建一个小程序就会默认创建index和logs模块,每个模块都以单独的文件夹形式保存。页面文件在微信开发者工具中的效果如图1所示。
在这里插入图片描述
图1 首页下的四种文件

除了页面文件对应的模块文件夹之外,小程序还支持将一些工具型js独立保存,通过导入的方式为模块提供功能支持,例如新建小程序中自动创建的utils,效果如图2所示。
在这里插入图片描述
图2 utils模块

所有的全局文件都以app命名开头,全局文件内部声明的资源可以作用到所有模块中,效果如图3所示。
在这里插入图片描述
图3 小程序应用的全局文件

在过去,开发人员所积累的前端开发经验其实有很大一部分可以继续应用在小程序的开发上,例如小程序和普通网页都需要书写静态标签页面。小程序的样式和普通网页基本相同,而且小程序和普通网页都遵循了JavaScript的ES6标准,很多语法在两个平台都可以一起使用,例如模块的导入导出、箭头函数等。

但是小程序和传统网页开发毕竟还是两种不同的技术,二者之间还是有些许的区别。在普通网页中渲染线程和脚本线程是互斥的,而在小程序中二者不是互斥的。普通网页可以操作DOM和BOM对象,但是小程序的逻辑层运行在JSCore中,无法操作DOM和BOM对象,所以小程序在使用JS选择UI时,就没有父节点、子节点、ID选择器这些概念了。网页开发者需要面对的环境是各式各样的浏览器,在PC端需要面对IE、Chrome、QQ浏览器等,在移动端也需要面对各个系统中的WebView,而小程序开发过程中主要面对的是IOS和Android的微信客户端。目前小程序也支持在微信的PC客户端上运行,所以在开发过程中也需要考虑Windows或Mac环境的UI适配,以及代码兼容性的问题。

1.2 WXML模板

WXML(WeiXin Markup Language)是小程序框架设计的一套标签语言,结合小程序的基础组件、事件系统,可以构建出页面的结构。虽然在书写方式上WXML和HTML有很多相似之处,但是二者之间的语法结构又有很大的区别,WXML仅能在微信小程序开发工具中预览,而HTML可以在浏览器内预览。传统的HTML标签在WXML中是无法之间使用的,WXML对组件进行了重新封装,为后续的性能优化提供了可能,同时避免开发者写出低质量的代码。

WXML文件以 .wxml 作为后缀,一个完整的 WXML 语句由一段开始标签和结束标签组成,在标签中可以是内容,也可以是其他的WXML语句,这一点上与HTML是一致的。WXML基本语法如例1所示。

【例1】WXML基本语法

<!--pages/wxml/index.wxml-->
<text>pages/wxml/index.wxml</text>

WXML的语法校验是非常严格的,要求标签必须是严格闭合的,没有闭合将会导致编译错误。

1.3 WXSS样式

WXSS(WeiXin Style Sheets)是一套用于小程序的样式语言,用于描述WXML的组件样式,提升视觉上的效果。WXSS与传统前端开发中的CSS类似,为了更适合小程序开发,WXSS对CSS做了一个补充和扩展,例如尺寸单位、样式导入等。

在WXSS中使用rpx(responsive pixel)作为尺寸单位,可以根据屏幕宽度进行自适应。小程序中的rpx与传统CSS尺寸单位的px是以 1rpx = 0.5px 进行的换算。

1.4 JS脚本

小程序的主要开发语言是JavaScript,开发者使用JavaScript开发业务逻辑以及调用小程序的API,以此来完成业务需求。在大部分开发者看来,JavaScript和ECMAScript是指同一回事,但是从严格意义上来讲,二者之间的意义是完全不同的。ECMAScript是由ECMA国际组织通过ECMA-262标准化的脚本程序设计语言,该标准规定了ECMAScript主要包括脚本语法、数据类型、语句、关键字、操作符以及对象等基本的编程语言规范,而JavaScript是ECMAScript的一种具体实现。理解了这些概念,有助于开发者理解小程序中的JavaScript同浏览器的JavaScript以及Node中的JavaScript之间的区别。

浏览器中的JavaScript是由BOM(浏览器对象模型,全称 Browser Object Model)、DOM(文档对象模型,全称 Document Object Model)以及ECMAScript组成的,对于Web前端开发者来说,应该非常熟悉BOM和DOM这两个对象模型,它使得开发者可以去操作浏览器的一些表现,比如修改URL、修改页面呈现、记录数据等等。

Node中的JavaScript是由NPM、Native模块以及ECMAScript组成的,Node的开发者非常熟悉NPM的包管理工具,通过各种扩展包来快速实现一些功能,同时通过使用一些原生的模块来赋予Node语言本身不具有的能力,例如FS、HTTP、OS等。

小程序的JavaScript是由ECMAScript以及小程序的框架和API来实现的,与浏览器中的JavaScript相比没有BOM和DOM对象,所以类似于jQuery、Zepto这种浏览器类库是无法在小程序中运行起来的,同样的缺少Native模块和NPM包管理的机制。所以这就导致小程序中无法加载原生库,也无法直接使用大部分的NPM依赖包。

1.5 JSON配置

JSON(JS对象简谱,全称 JavaScript Object Notation)是一种轻量级的数据交换格式,是基于ECMAScript的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。JSON的语法易于阅读和编写,同时也易于程序解析和生成,是一种理想的网络传输格式,也可以作为项目的配置文件。由此可见,JSON仅是一种数据格式而非编程语言,在小程序中也作为一种重要的配置文件而存在。

JOSN文件作为小程序中的静态配置文件,在小程序运行之前就决定了小程序的一些表现,需要注意的是小程序无法在运行过程中去动态更新JSON配置,如果JSON配置文件的内容发生了更改,需要重新编译当前的项目才能生效。

2 小程序宿主环境

2.1 小程序的渲染机制

小程序是基于双线程模型的,包括渲染层和逻辑层。在这个模型中,小程序的渲染层和逻辑层是分开在不同的线程中运行的,这与传统的Web单线程模型有很大的区别。小程序渲染层的界面使用了WebView 进行渲染;逻辑层采用JsCore线程运行JS脚本。一个小程序存在多个界面,所以渲染层存在多个WebView线程,这两个线程的通信会经由微信客户端做中转,逻辑层发送网络请求也经由Native转发,小程序的通信模型如图4所示。

在这里插入图片描述
图4 渲染层和逻辑层通信模型

在小程序的开发中,开发者对小程序最大的期望就是当用户点击某个小程序时,可以让小程序在最短的时间内加载完毕小程序的界面。由于小程序的宿主是微信,所以我们不太可能用纯客户端原生技术来编写小程序,因此,我们需要像Web技术那样,有一份随时可更新的资源包放在云端,通过下载到本地,动态执行后即可渲染出界面。

我们了解过模型背后的原理,下面再来看一下小程序是如何把脚本中的数据渲染到界面上的。小程序的WXML模板使用view标签,其子节点用“{{}}”的语法绑定一个msg的变量,如例2所示。

【例2】渲染WXML代码

<view>{{ msg }}</view>

在JS脚本中使用 this.setData() 方法把msg字段设置为“Hello World”,如例3所示。

【例3】用于渲染的JS脚本

Page({data: {msg: ''
},onLoad: function () {this.setData({ msg: 'Hello World' })}
})

上面的例子中,WXML页面通过模板语法的方式绑定了JS脚本的msg变量,当msg变量被修改后,页面展示的内容也会自动发生改变。在UI界面开发过程中,程序需要维护很多变量状态,同时还需要操作变量所对应的UI元素。但是随着界面的结构越来越复杂,程序需要维护的变量也随之增加,同时还要处理更多界面上的交互事件,整个程序就变得特别地复杂。如果使用某种方法将变量的状态和UI视图绑定在一起,当状态变更时,视图也会自动变更,那么开发者就可以省去编写修改视图的代码,提高开发效率。这种方法就是“数据驱动”。

小程序数据驱动的原理就是通过JS对象来表达DOM树的结构,而这棵DOM树实际上就是WXML的结构。WXML可以先转换成JS对象,然后再渲染出真正的DOM树,例2与例3的转换效果如图5所示。
在这里插入图片描述
图5 WXML结构转换示例图

假如我们把msg变量的值从“Hello World”改为“Hi”,这个过程必须通过调用 this.setData() 方法来完成,其产生的JS对象所对应的节点发生了变化,此时DOM树也会随之更改,从而达到更新UI界面的目的,这就是小程序“数据驱动”的原理。

通过上述讲解,我们理解了小程序的渲染层和逻辑层为什么是分开的,而且在渲染层中,小程序的宿主环境会把WXML转换成JS对象,而JS脚本是运行在逻辑层的。当逻辑层的数据发生变化时,通过 this.setData() 方法把数据从逻辑层再传递到渲染层,经过对比前后的差异,把更改后的数据应用在原来的DOM树上,以此实现UI界面的渲染,这就是小程序的渲染机制。

2.2 程序与页面

小程序的运行环境被分为了渲染层和逻辑层,渲染层主要是用于渲染页面视图,而逻辑层主要负责处理业务逻辑,这就要求我们必须要分清楚小程序中的程序与页面。站在逻辑组成的角度来说,一个小程序是由多个页面组成的程序,那么我们又要分清楚“小程序”和“程序”的概念。

我们常说的“小程序”其实指的是一个应用,这个应用是从产品的层面上来理解的,一个小程序就是一个软件应用的产品。而我们在本小节中所讲的“程序”是指在小程序应用内部的代码层面的程序实例。小程序的宿主环境提供了 App() 函数作为程序的构造方法,以此来注册一个程序的 App 对象,所以在本小节中,我们就以 App 作为代码层面的“程序”。

构造方法 App() 需要声明在小程序项目的根目录下的 app.js 文件中,App 实例也是一个单例对象,其构造方法接收一个 Object 对象参数,参数对象中可以声明小程序全局生命周期函数,代码如例4所示。

【例4】全局生命周期方法

App({onLaunch: function(options) {}, // 小程序初始化完成时触发,并且只触发一次onShow: function(options) {}, // 小程序启动或切回前台显示时触发onHide: function() {}, // 小程序切到后台时触发onError: function(error) {} // 小程序发生脚本错误或API调用失败时触发
})

在其他的 JS 脚本中需要使用 getApp() 方法来获取 App 的实例,具体方法如例5所示。

【例5】获取 App 实例

var app = getApp()

我们都知道,一个小程序有很多页面组成,每个页面都是有界面、配置、逻辑三部分构成,这些页面的业务逻辑都需要编写到当前页面文件夹下的 page.js 文件中。宿主环境也提供了一个构造方法 Page() 来实现注册小程序页面,Page() 在页面脚本 page.js 中调用。与 App() 相同,Page() 方法也是要接收一个 Object 对象参数,参数对象的属性中除了要声明页面的生命周期方法之外,还可以声明事件方法和页面的初始化数据data 属性,代码如例6所示。

【例6】页面构造方法 Page()

Page({data: { },  // 页面的初始化数据onLoad: function(options) { }, // 页面被加载时触发onReady: function() { }, // 页面初次渲染完成后触发onShow: function() { }, // 页面切回前台显示时触发onHide: function() { }, // 页面切到后台隐藏时触发onUnload: function() { }, // 页面被卸载时触发onPullDownRefresh: function() { },  // 页面被下拉时触发onReachBottom: function() { }, // 页面上拉触底时触发onShareAppMessage: function () { }, // 页面被转发时触发onPageScroll: function() { } // 页面被滚动时触发
})

开发者不需要主动调用 Page() 构造器中定义的生命周期方法,而是由微信客户端根据监听用户的操作而主动触发的,这就避免了程序调用上的混乱。学习过了小程序界面渲染的基本原理后,我们知道小程序的页面结构是由 WXML 进行描述的,WXML 可以通过数据绑定的语法来绑定逻辑层定义的数据对象,这个数据对象就是在 Page() 构造方法的参数中定义的 data 属性字段,data 字段的值也是在页面第一次被渲染时从逻辑层传递到渲染层的。

2.3 小程序的内置组件

组件化是前端最常见的一种开发方式,组件就是对应用视图层的拆分,一个小程序的页面也可以被拆分成多个组件,组件是小程序页面的基本组成单元。为了方便开发者可以快速进行开发,小程序的宿主环境提供了一系列的基础组件。除了小程序宿主环境提供的组件,还有开发者自行封装的视图组件和引入的外部第三方组件,所以为了区分这些组件,我们就把小程序宿主环境提供的基础组件称为小程序的内置组件。

组件是在 WXML 模板文件中声明使用的,其语法和 HTML 语法非常相似,但又有一些区别。小程序的 WXML 模板文件遵循 JSX(JavaScript XML) 语法规范,规定了每个组件标签都必须有开始标记和结束标记,所有组件名称和属性名称都必须是小写,多个单词之间使用“-”进行连接。WXML组件标签代码如例6所示。

【例7】WXML组件标签

<view><image id="logo" mode="scaleToFill" src="app-logo.png"></image><view class="app-list"><view class="item">hello</view><view class="item" style="color:red;">world</view></view>
</view>

组件标签的属性主要包含样式和事件绑定,除了一些公共属性之外,还可以拥有各自自定义的属性,组件可以使用这些属性对自身就行样式修饰和功能封装,以image组件为例,可以为图片标签上面定义图片的模式和加载方式,具体代码如8所示。

【例8】image图片组件

<image mode="scaleToFill" src="app-logo.png" lazy-load></image>

在 image 图片组件上可以使用 src 属性加载图片资源,还可以使用 mode 属性来定义图片的裁剪、缩放模式,组件上的 lazy-load 属性决定了图片是否开启懒加载。我们还可以定义图片的事件属性,例如 binderror、bindload 等。

2.4 小程序的API

为了方便开发者调用微信提供的能力和手机硬件能力,小程序宿主环境提供了丰富的 API(Application Programming Interface,应用程序接口)。小程序提供的 API 按照功能主要分为几大类:网络、媒体、文件、数据缓存、位置、设备、界面、微信开放能力等,而且对于 API 的调用小程序也做了约定,例如:

  • 小程序所有的API都挂载到名为wx的全局对象下;
  • 用于监听事件的 API 函数都是以 wx.on* 开头;
  • API的Object参数一般由success、fail、complete三个回调函数来接收接口调用的结果;
  • 在API中凡是以 wx.set*wx.get* 开头的都是用于写入数据和获取数据的接口;
  • 如果没有特殊说明,大部分的API函数都是异步函数,并且都接受一个Object作为参数。

以小程序发起网络请求为例,API接口调用的代码如例9所示。

【例9】发起网络请求

wx.request({url: 'http://192.168.1.10:8080/find', // 请求的服务地址data: {}, // 请求参数success: function(res) {// 请求成功后调用},fail: function() {// 发生网络错误时调用},complete: function() {// 成功或者失败都会调用}
})

2.5 小程序的事件处理

事件就是被控件所识别的操作,例如在页面中点击了确定按钮,小程序中的事件与传统Web开发的事件机制是一样的。当小程序UI界面的程序与用户之间发生了交互,渲染层就会通知逻辑层执行对应的事件方法,然后逻辑层再将处理好的结果传递给渲染层并向用户展示。但是有时候程序上的“行为反馈”不一定是用户主动触发的,例如视频播放过程中的进度变化,也需要对开发者进行返回,方便开发者在逻辑层中所响应的处理。

在小程序中,任何渲染层的行为事件都需要向开发者反馈,这种事件行为有可能是用户主动触发的,也有可能是组件状态改变而触发的,无论哪种状态的事件触发。无论哪种状态的事件触发行为,都需要被微信客户端捕获,然后由开发者在逻辑层中处理。整个事件传递过程如图6所示。
在这里插入图片描述
图6 渲染层与逻辑层的事件传递

以页面按钮点击事件交互为例,具体代码如例10所示。

【例10】页面按钮点击事件

<!-- page.wxml -->
<button data-msg="Hello" bindtap="onBtnClick"> 按钮 </button>
// page.js
Page({onBtnClick: function(event) {console.log(event)}
})

事件通过组件上绑定的 bindtap 属性触发,同时在页面构造方法 Page() 中声明对应的 onBtnClick() 方法来处理对应的事件,当用户点击页面的 button 按钮时就会触发 onBtnClick() 事件方法,同时得到event 事件对象,组件上的 data-msg 属性的值也会被封装到 event 事件对象中。

当事件回调函数触发时,会接收到一个事件对象。事件对象的属性如表1所示。
在这里插入图片描述

这里需要注意的是target和currentTarget的区别,currentTarget为当前事件所绑定的组件,而target则是触发该事件的源头组件。

3 小程序应用能力

3.1 原生CSS布局

在传统网页开发中,我们可以使用 CSS 的display、position、float等属性来实现页面布局,但是在小程序中需要考虑各种终端的尺寸适配,如果还是使用定位、浮动这类布局的话很难实现不同终端的适配,缺乏灵活性。在微信小程序中,建议使用flex弹性盒子布局。如果小程序需要兼容IOS8以下版本的话,需要开启样式自动补全,在小程序菜单栏中选择设置、项目设置,勾选“上传代码时样式自动补全”选项。

flex弹性盒子布局提供了一种灵活的布局模型,使容器能通过改变里面项目的高宽、顺序,来对可用空间实现最佳的填充,方便适配不同大小的内容区域。flex不单是一个属性,它包含了一套新的属性集。属性集包括用于设置容器,和用于设置项目两部分。设置容器的属性如表2所示。
表2  flex容器属性

设置项目的属性如表3所示。

在这里插入图片描述

flex在页面布局设计中应用非常广泛,例如在不固定高度的情况下,只需要在容器中设置flex的排列方向和主轴的对齐方式,即可实现内容不确定下的垂直居中效果,示例代码如例11所示。

【例11】flex设置容器内容垂直居中

.container{display: flex;flex-direction: column;justify-content: center;
}

3.2 界面交互反馈

微信小程序中常用的界面交互行为包括屏幕触摸反馈、弹框提示、界面滚动等。由于受到终端设备性能等因素的影响,频繁的用户与小程序交互的操作会导致系统延迟,操作的反馈耗时较长的情况,我们在开发小程序时应该尽可能的考虑到用户的使用体验。

一般在用户触摸某个事件按钮或view区域时,会改变对应区域的颜色,例如用户手指触摸view区域时,将该view区域的底色设置成浅灰色或其他具有明显对比的颜色,效果如图7所示。

在这里插入图片描述
图7 可触摸区域的用户操作反馈效果

这样做的目的就是为用户及时提示触摸的结果,以免用户触摸后不知道结果而反复的触发执行。设置了用户操作的反馈效果,大大提升了用户的使用体验。

除了这种设置区域不同的触发样式外,还有些常用的用户触发效果反馈,例如为button组件设置loading属性,在完成某个操作后弹出Toast提示框等效果。如果使用弹出框作为用户操作后的提示效果,需要在错误提示时明确告知用户具体出现错误的原因,并且需要用户手动关闭弹出框,如有需要的话还会附带下一步操作的引导。

3.3 HTTPS网络通信

在前后端分离开发的项目中,前端需要通过发送异步请求从服务器获取数据,小程序中也不例外。小程序作为客户端,需要通过宿主环境提供的 wx.request() 函数发起网络请求来实现从服务器拉取信息。小程序宿主环境要求request发起的网络请求必须是https协议请求,因此开发者服务器必须提供HTTPS服务的接口,同时为了保证小程序不乱用任意域名的服务,wx.request 请求的域名需要在小程序管理平台进行配置,如果小程序正式版使用 wx.request 请求未配置的域名,在控制台会有相应的报错。

wx.request() 方法的参数是一个Object对象,对象中最重要的属性包括:

  • url,服务器请求接口;
  • data,请求参数;
  • header,设置请求的header;
  • method,请求方法,默认值是GET;
  • success,收到开发者服务成功返回的回调函数。

小程序发出一个HTTPS网络请求,有时网络存在一些异常或者服务器存在问题,在经过一段时间后仍然没有收到网络回包,我们把这一段等待的最长时间称为请求超时时间。小程序request默认超时时间是60秒,一般来说,我们不需要这么长的一个等待时间才收到回包,可能在等待3秒后还没收到回包,就需要给用户一个明确的“服务不可用”的提示。在小程序项目根目录里边的app.json可以指定request的超时时间。

3.4 本地数据缓存

小程序的本地数据缓存能力在实际开发中应用非常广泛,本地数据缓存就是通过小程序将数据存储到当前设备的硬盘上,开发者可以使用本地数据缓存来存储一些服务端非实时的数据,从而提高小程序的渲染速度,减少用户的等待时间。
小程序提供了读写本地数据缓存的接口,通过 wx.getStorage/wx.getStorageSync 读取本地缓存,通过 wx.setStorage/wx.setStorageSync 写数据到缓存,其中Sync后缀的接口表示是同步接口,执行完毕之后会立马返回。小程序宿主环境会管理不同小程序的数据缓存,不同小程序的本地缓存空间是分开的,每个小程序的缓存空间上限为10MB,如果当前缓存已经达到10MB,再通过 wx.setStorage 写入缓存会触发fail回调。

小程序的本地缓存不仅仅通过小程序这个维度来隔离空间,考虑到同一个设备可以登录不同微信用户,宿主环境还对不同用户的缓存进行了隔离,避免用户间的数据隐私泄露。由于本地缓存是存放在当前设备,用户换设备之后无法从另一个设备读取到当前设备数据,因此用户的关键信息不建议只存在本地缓存,应该把数据放到服务器端进行持久化存储。

3.5 连接设备硬件

移动终端设备不同于PC端,在移动终端没有了PC端的键盘、鼠标等常用的输入设备和一些输出设备,但是移动终端中有很多传感器。而且移动终端屏幕尺寸也比PC端小了很多,所以在移动端屏幕上输入复杂信息的效率会很低。小程序的宿主环境提供了很多操作移动终端设备的能力,从而帮助开发者实现某些特定场景下的高效操作能力,例如扫描二维码、蓝牙连接、GPS定位等能力。

但是有的设备操作能力并不仅仅是为了解决高效输入的问题,更多的是提升用户的使用体验,例如获取设备的网络状态。手机连接网络的方式有2G、3G、4G、5G和wifi,每种连接方式的上传和下载速度有着很大的差异,而且计费方式不同。wifi连接相对于其他的移动网络连接来说,不仅访问速度快,而且不会对用户产生流量费用。用户在使用小程序观看视频或下载体积较大的文档时,为了避免用户耗费太多的数据流量,开发者就需要通过小程序提供的获取网络状态的能力,做出一些更加友好的提示,供用户自行选择。

3.6 微信开放能力

小程序是以微信为基座的一种应用,在很多场景下都需要获取微信的一些能力,所以小程序的宿主环境就提供了开放微信部分权限的能力,这种开放能力包括:获取微信登录凭证、获取微信用户的基本信息、分享到朋友圈或转发消息、收藏、卡券、发票、生物认证、微信运动等能力。以微信登录为例,开发者在已有的互联网产品中接入小程序时会面临一些与登录状态有关的问题,微信就对小程序开发了微信登录的接口。

4 小程序的组件化

4.1 小程序基础组件

小程序的视图是在WebView里渲染的,所以小程序的视图搭建离不开HTML标记语言。如果在小程序中直接使用HTML的话,其安全性就会大大降低,并且无法使用微信小程序的双线程模型实现数据绑定和页面的动态渲染。为了解决这一问题,小程序设计了一套名为Exparser的组件框架,基于这个框架,在小程序内设计了一套涵盖大部分功能的组件,方便开发者快速搭建出满足需求的界面。

基于Exparser框架设计的小程序内置组件,涵盖了视图容器类、表单类、导航类、媒体类、开放类等几十种组件。所有的内置组件都可以使用WXSS修饰,这样就解决了大部分的项目需求。

4.2 自定义组件

在实际的项目开发中,小程序的内置组件不一定能满足所有的需求,为了实现更高效的代码复用,小程序还允许开发者自行扩充组件,这些由开发者自行设计的组件被称为自定义组件。

在小程序中,每个组件都具有独立的逻辑空间,分别拥有自己的独立数据和setData方法调用。在使用自定义组件的小程序页面中,Exparser框架将接管所有的自定义组件注册和实例化。小程序的基础库中提供了Page和Component两个构造器,自定义组件使用的是Component构造器。

4.3 第三方组件库

小程序从基础库版本 2.2.1 开始支持使用 npm 安装第三方包,因此也支持开发和使用第三方自定义组件包。我们在开发微信小程序时,选择一款好用的UI组件库,可以达到事半功倍的效果。目前,市面上常用的小程序UI组件库有以下几款:

  • WeUI,是一套同微信原生视觉体验一致的基础样式库,由微信官方设计团队为微信 Web 开发量身设计,可以令用户的使用感知更加统一。
  • Vant Weapp,是有赞移动端组件库 Vant 的小程序版本,两者基于相同的视觉规范,提供一致的 API 接口,助力开发者快速搭建小程序应用。
  • iView Weapp,是由 TalkingData 发布的组件库,一套高质量的微信小程序 UI 组件库。
  • TaroUI,是由京东凹凸实验室倾力打造的多端开发解决方案,使用 Taro 可以将源代码分别编译出可以在不同端(微信小程序、H5、RN等)运行的代码。

5 本章小结

本章概述了微信小程序的代码结构、小程序宿主环境、小程序渲染机制和小程序应用能力。通过本章的学习可以让大家清晰地理解小程序开发流程,掌握小程序的核心API,为以后快速上手小程序开发打下基础。

相关文章:

【微信小程序实战教程】之微信小程序原生开发详解

微信小程序原生开发详解 微信小程序的更新迭代非常频繁&#xff0c;几乎每个月都会有新版本发布&#xff0c;这就会让初学者感觉到学习的压力和难度。其实&#xff0c;我们小程序的每次版本迭代都是在现有小程序架构基础之上进行更新的&#xff0c;如果想要学好小程序开发技术&…...

PHP身份证实名认证接口集成守护电商购物

在这个万物互联的世界里&#xff0c;网购已成为日常生活中不可或缺的一部分。然而&#xff0c;随着线上交易的增加&#xff0c;如何保护消费者和商家免受欺诈&#xff0c;确保每一笔交易的安全&#xff0c;成了亟待解决的难题。这时&#xff0c;身份证实名认证接口应运而生&…...

为什么有了MAC还需要IP?

目录 MAC地址&#xff08;Media Access Control Address&#xff09;IP地址&#xff08;Internet Protocol Address&#xff09;为什么需要两者&#xff1f; IP地址和MAC地址在网络通信中扮演着不同的角色&#xff0c;它们各自有独特的功能和用途。下面是它们的主要区别和为什么…...

SpringBoot中如何使用RabbitMq

一&#xff0c;RabbitMQ简介和基本概念 RabbitMQ 是一个开源的消息中间件&#xff0c;基于 AMQP&#xff08;高级消息队列协议&#xff09;实现。 它由 Erlang 语言开发&#xff0c;并且支持多种编程语言&#xff0c;包括 Java、Python、Ruby、PHP 和 C# 等&#xff0c; 下载…...

LangChain自定义Embedding封装 之 ERNIE Bot

LangChain自定义Embedding封装 之 ERNIE Bot 百度飞浆平台的 ERNIE Bot 导入下面方法 和 环境 &#xff0c;即可验证 embedding ERNIE_Bot_embedding() class ERNIE_Bot_embedding(BaseModel, Embeddings):client: Anyroot_validator()def validate_environment(cls, value…...

Git 安装教程

1、登录git 官方网站&#xff1a;https://git-scm.com/ 点击左边的 Downloads 或者 右边标识的下载标志&#xff0c;它根据电脑操作系统自动匹配版本 Downloads for Windows 2、以 windows 为例下载对应版本 网络有时可能不大好&#xff0c;阿里镜像下载超快。 下载好以后&a…...

Lua 类管理器

Lua 类管理器 -- ***** Class Manager 类管理*****‘local ClassManager {}local this ClassManagerfunction ClassManager.Class(className, ...)print(ClassManager::Class)--print(className)-- 构建类local cls {__className className}--print(cls)-- 父类集合local …...

实现领域驱动设计(DDD)系列详解:领域模型的持久化

领域驱动设计主要通过限界上下文应对复杂度&#xff0c;它是绑定业务架构、应用架构和数据架构的关键架构单元。设计由领域而非数据驱动&#xff0c;且为了保证定义了领域模型的应用架构和定义了数据模型的数据架构的变化方向相同&#xff0c;就应该在领域建模阶段率先定义领域…...

配置sublime的中的C++编译器(.sublime-build),实现C++20

GCC 4.8: 支持 C11 (部分) GCC 4.9: 支持 C11 和 C14 (部分) GCC 5: 完全支持 C14 GCC 6: 支持 C14 和 C17 (部分) GCC 7: 支持 C17 (大部分) GCC 8: 完全支持 C17&#xff0c;部分支持 C20 GCC 9: 支持更多的 C20 特性 GCC 10: 支持大部分 C20 特性 GCC 11: 更全面地支持 C20 …...

Android14 - 前台Service、图片选择器 、OpenJDK 17、其他适配

前台服务 1. 指定前台服务类型 以 Android 14(API 级别 34)或更高版本为目标平台的应用,需要为应用中的每项前台服务指定服务类型,因为系统需要特定类型的前台服务满足特定用例。具体介绍如下: 在Android 10 在 <service> 元素内引入了 android:foregroundServiceT…...

数据恢复教程:如何从硬盘、SD存储卡、数码相机中恢复误删除数据。

您正在摆弄 Android 设备。突然&#xff0c;您意外删除了一张或多张图片。不用担心&#xff0c;您总能找到一款价格实惠的数据恢复应用。这款先进的软件可帮助 Android 用户从硬盘、安全数字 (SD) 或存储卡以及数码相机中恢复已删除的数据。 Android 上数据被删除的主要原因 在…...

谷粒商城实战笔记-47-商品服务-API-三级分类-网关统一配置跨域

文章目录 一&#xff0c;跨域问题1&#xff0c;跨域问题产生的原因2&#xff0c;预检请求3&#xff0c;跨域解决方案3.1 CORS (Cross-Origin Resource Sharing)后端配置示例&#xff08;Spring Boot&#xff09; 3.2 JSONP (JSON with Padding)3.3 代理服务器Nginx代理配置示例…...

stm32平台为例的软件模拟时间,代替RTC调试

stm32平台为例的软件模拟时间&#xff0c;代替RTC调试 我们在开发项目的时候&#xff0c;如果用到RTC&#xff0c;如果真正等待RTC到达指定的时间&#xff0c;那调试时间就太长了。 比如每隔半个小时&#xff0c;存储一次数据&#xff0c;如果要观察10次存储的效果&#xff0…...

《设计模式之美》读书笔记2

从Linux学习应对大型复杂项目的方法&#xff1a; 1、封装与抽象&#xff1a;封装了不同类型设备的访问细节&#xff0c;抽象为统一的文件访问方式&#xff0c;更高层的代码就能基于统一的访问方式&#xff0c;来访问底层不同类型的设备。这样做的好处是&#xff0c;隔离底层设备…...

C++ STL set_difference 用法

一&#xff1a;功能 给定两个集合A&#xff0c;B&#xff1b;计算集合的差集&#xff0c;即计算出那些只包含在A中而不包含在B中的元素。 二&#xff1a;用法 #include <vector> #include <algorithm> #include <iostream>int main() {std::vector<int&…...

【基础算法总结】优先级队列

优先级队列 1.最后一块石头的重量2.数据流中的第 K 大元素4.前K个高频单词4.数据流的中位数 点赞&#x1f44d;&#x1f44d;收藏&#x1f31f;&#x1f31f;关注&#x1f496;&#x1f496; 你的支持是对我最大的鼓励&#xff0c;我们一起努力吧!&#x1f603;&#x1f603; 1…...

python-绝对值排序(赛氪OJ)

[题目描述] 输入 n 个整数&#xff0c;按照绝对值从大到小排序后输出。保证所有整数的绝对值不同。输入格式&#xff1a; 输入数据有多组&#xff0c;每组占一行&#xff0c;每行的第一个数字为 n ,接着是 n 个整数&#xff0c; n0 表示输入数据的结束&#xff0c;不做处理。输…...

成功者的几个好习惯,你具备了几个

每个人都想成为自己领域的佼佼者&#xff0c;然而&#xff0c;成功并非偶然&#xff0c;它往往与一系列良好的习惯紧密相连。这些习惯如同灯塔&#xff0c;指引着成功者在波涛汹涌的大海中稳健前行。 一、设定明确目标 没有明确的目标&#xff0c;就如同航海没有指南针&#…...

centos中zabbix安装、卸载及遇到的问题

目录 Zabbix简介Zabbix5.0和Zabbix7.0的区别监控能力方面模板和 API 方面性能、速度方面 centos7安装Zabbix(5.0)安装zabbix遇到的问题卸载Zabbix Zabbix简介 Zabbix 是一个基于 WEB 界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案。zabbix 能监视各种网络参…...

php编译安装

一、基础环境准备 # php使用www用户 useradd -s /sbin/nologin -M www二、下载php包 # 下载地址 https://www.php.net/downloads wget https://www.php.net/distributions/php-8.3.9.tar.gz三、配置编译安装 编译安装之前需要处理必要的依赖&#xff0c;在编译配置安装&…...

[K8S] K8S资源控制器Controller Manager(4)

文章目录 1. 常见的Pod控制器及含义2. Replication Controller控制器2.1 部署ReplicaSet 3. Deployment3.1部署Deployment3.2 运行Deployment3.3 镜像更新方式3.4 Deployment扩容3.5 滚动更新3.6 金丝雀发布(灰度发布)3.7 Deployment版本回退3.8 Deployment 更新策略 4. Daemon…...

C#,.NET常见算法

1.递归算法 1.1.C#递归算法计算阶乘的方法 using System;namespace C_Sharp_Example {public class Program{/// <summary>/// 阶乘&#xff1a;一个正整数的阶乘Factorial是所有小于以及等于该数的正整数的积&#xff0c;0的阶乘是1&#xff0c;n的阶乘是n&#xff0…...

KubeSphere介绍及一键安装k8s

KubeSphere介绍 官网地址&#xff1a;https://kubesphere.io/zh/ KubeSphere愿景是打造一个以 Kubernetes 为内核的云原生分布式操作系统&#xff0c;它的架构可以非常方便地使第三方应用与云原生生态组件进行即插即用&#xff08;plug-and-play&#xff09;的集成&#xff0…...

Spring 系列

SpringBoot 实体类&#xff08;Entity&#xff09;层 实体类&#xff08;Entity&#xff09;通常属于模型层&#xff08;Model Layer&#xff09;或领域层&#xff08;Domain Layer&#xff09;。它们代表应用程序中的核心业务数据结构&#xff0c;与数据库表结构紧密对应。在…...

基于opencv[python]的人脸检测

1 图片爬虫 这里的代码转载自&#xff1a;http://t.csdnimg.cn/T4R4F # 获取图片数据 import os.path import fake_useragent import requests from lxml import etree# UA伪装 head {"User-Agent": fake_useragent.UserAgent().random}pic_name 0 def request_pic…...

配置SSH公钥互信

目录 第一台主机&#xff1a;servera&#xff08;172.25.250.101&#xff09; 第一步&#xff1a;查看 . ssh目录下面是否为空 第二步&#xff1a;输入命令ssh-keygen 第三步&#xff1a; 再看查看一下. ssh目录 第四步&#xff1a; 输入命令 ssh-copy-id root172.25.250…...

WEB渗透Web突破篇-SQL注入(MSSQL)

注释符 -- 注释 /* 注释 */用户 SELECT CURRENT_USER SELECT user_name(); SELECT system_user; SELECT user;版本 SELECT version主机名 SELECT HOST_NAME() SELECT hostname;列数据库 SELECT name FROM master..sysdatabases; SELECT DB_NAME(N); — for N 0, 1, 2, ……...

DAY15

数组 冒泡排序 冒泡排序无疑是最为出名的排序算法之一&#xff0c;总共有八大排序 冒泡的代码还是相当简单的&#xff0c;两层循环&#xff0c;外层冒泡轮数&#xff0c;里层依次比较&#xff0c;江湖中人人尽皆知 我们看到嵌套循环&#xff0c;应该马上就可以得到这个算法的…...

pytest结合allure-pytest插件生成测试报告

目录 一、安装allure-pytest插件 二、下载allure 三、生成allure报告 四、效果展示 一、安装allure-pytest插件 二、下载allure 下载之后解压&#xff0c;解压之后还要配置环境变量&#xff08;把allure目录下bin目录配置到系统变量的path路径&#xff09;&#xff0c;下…...

详细解析用户提交咨询

上一篇文章中写到了使用Server-Sent Events (SSE)&#xff0c;并获取message里面的内容。 本篇文章主要是写&#xff0c;具体该如何实现的具体代码&#xff0c;代码见下方&#xff0c;可直接拿 async submitConsult() {this.scrollToBottom();if (!this.$checkLogin()) return;…...

UDP/TCP协议解析

我最近开了几个专栏&#xff0c;诚信互三&#xff01; > |||《算法专栏》&#xff1a;&#xff1a;刷题教程来自网站《代码随想录》。||| > |||《C专栏》&#xff1a;&#xff1a;记录我学习C的经历&#xff0c;看完你一定会有收获。||| > |||《Linux专栏》&#xff1…...

力扣94题(java语言)

题目 思路 使用一个栈来模拟递归的过程&#xff0c;以非递归的方式完成中序遍历(使用栈可以避免递归调用的空间消耗)。 遍历顺序步骤&#xff1a; 遍历左子树访问根节点遍历右子树 package algorithm_leetcode;import java.util.ArrayList; import java.util.List; import…...

JavaScript基础入门:构建动态Web世界的基石

简要介绍JavaScript作为互联网上最流行的编程语言之一&#xff0c;它在构建交互式网页、动态Web应用及服务器后端&#xff08;通过Node.js&#xff09;中的重要性。强调学习JS对于任何想要进入Web开发领域的人来说是不可或缺的。 1. JavaScript是什么&#xff1f; 定义JavaSc…...

01-client-go

想学习K8S源码&#xff0c;可以加 &#xff1a;mkjnnm 1、介绍 client-go 是用来和 k8s 集群交互的go语言客户端库&#xff0c;地址为&#xff1a;https://github.com/kubernetes/client-go client-go 的版本有两种标识方式&#xff1a; v0.x.y (For each v1.x.y Kubernetes…...

WebRTC QoS方法十三.2(Jitter延时的计算)

一、背景介绍 一些报文在网络传输中&#xff0c;会存在丢包重传和延时的情况。渲染时需要进行适当缓存&#xff0c;等待丢失被重传的报文或者正在路上传输的报文。 jitter延时计算是确认需要缓存的时间 另外&#xff0c;在检测到帧有重传情况时&#xff0c;也可适当在渲染时…...

PHP进阶:前后端交互、cookie验证、sql与php

单词&#xff1a;construct 构造 destruct 摧毁 empty 空的 trim 修剪 strip 清除 slash 斜线 special 特殊 char 字符 query 询问 构造方法&#xff08;魔术方法&#xff09; 构造方法是一种特殊的函数&#xff0…...

优思学院|ANOVA方差分析是什么?如何用EXCEL进行计算?

在数据分析、六西格玛管理领域中&#xff0c;ANOVA&#xff08;方差分析&#xff09;是一种基本的统计工具&#xff0c;广泛用于确定三组或三组以上的独立群体之间的平均值是否存在统计学上的显着差异。ANOVA的主要目的在于评估一个或多个因素的影响&#xff0c;通过比较不同样…...

Mindspore框架循环神经网络RNN模型实现情感分类|(三)RNN模型构建

Mindspore框架循环神经网络RNN模型实现情感分类 Mindspore框架循环神经网络RNN模型实现情感分类|&#xff08;一&#xff09;IMDB影评数据集准备 Mindspore框架循环神经网络RNN模型实现情感分类|&#xff08;二&#xff09;预训练词向量 Mindspore框架循环神经网络RNN模型实现…...

深度解读大语言模型中的Transformer架构

一、Transformer的诞生背景 传统的循环神经网络&#xff08;RNN&#xff09;和长短期记忆网络&#xff08;LSTM&#xff09;在处理自然语言时存在诸多局限性。RNN 由于其递归的结构&#xff0c;在处理长序列时容易出现梯度消失和梯度爆炸的问题。这导致模型难以捕捉长距离的依…...

安装好anaconda,打开jupyter notebook,新建 报500错

解决办法&#xff1a; 打开anaconda prompt 输入 jupyter --version 重新进入jupyter notebook&#xff1a; 可以成功进入进行代码编辑...

C++20之设计模式:状态模式

状态模式 状态模式状态驱动的状态机手工状态机Boost.MSM 中的状态机总结 状态模式 我必须承认:我的行为是由我的状态支配的。如果我没有足够的睡眠&#xff0c;我会有点累。如果我喝了酒&#xff0c;我就不会开车了。所有这些都是状态(states)&#xff0c;它们支配着我的行为:…...

数据库安全综合治理方案(可编辑54页PPT)

引言&#xff1a;数据库安全综合治理方案是一个系统性的工作&#xff0c;需要从多个方面入手&#xff0c;综合运用各种技术和管理手段&#xff0c;确保数据库系统的安全稳定运行。 方案介绍&#xff1a; 数据库安全综合治理方案是一个综合性的策略&#xff0c;旨在确保数据库系…...

人工智能:大语言模型提示注入攻击安全风险分析报告下载

大语言模型提示注入攻击安全风险分析报告下载 今天分享的是人工智能AI研究报告&#xff1a;《大语言模型提示注入攻击安全风险分析报告》。&#xff08;报告出品方&#xff1a;大数据协同安全技术国家工程研究中心安全大脑国家新一代人工智能开放创新平台&#xff09; 研究报告…...

【购买源码时有许多需要注意的坑】

购买源码时有许多需要注意的“坑”&#xff0c;这些坑可能会对项目的后续开发和使用造成严重影响。以下是一些需要特别注意的方面&#xff1a; 源码的完整性 编译测试&#xff1a;确保到手的源码能够从头至尾编译、打包、部署和功能测试无误。这一步非常关键&#xff0c;因为只…...

CAS的三大问题和解决方案

一、ABA问题的解决方案 变量第一次读取的值是1&#xff0c;后来其他线程改成了3&#xff0c;然后又被其他线程修改成了1&#xff0c;原来期望的值是第一个1才会设置新值&#xff0c;第二个1跟期望不符合&#xff0c;但是&#xff0c;可以设置新值。 解决方案&#xff1a; &a…...

EDA和统计分析有什么区别

EDA&#xff08;Electronic Design Automation&#xff09;和统计分析在多个方面存在显著的区别&#xff0c;这些区别主要体现在它们的应用领域、目的、方法以及所使用的工具上。 EDA&#xff08;电子设计自动化&#xff09; 定义与目的&#xff1a; EDA是电子设计自动化&…...

CentOS 7 修改DNS

1、nmcli connection show 命令找到设备名称 # nmcli connection show NAME UUID TYPE DEVICE enp4s0 99559edf-4e0a-4bae-a528-6d75065261e9 ethernet enp4s0 2、nmcli connection modify 命令修改dns nmcli connection modif…...

PHP基础语法-Part2

if-else语句、switch语句 与其他语言相同 循环结构 for循环while循环do-while循环foreach循环&#xff0c;搭配数组使用 foreach ($age as $avlue) //只输出值 {xxx; } foreach ($age as $key > $avlue) //键和值都输出 {xxx; }foreach ($age as $key >…...

数据结构门槛-顺序表

顺序表 1. 线性表2. 顺序表2.1 静态顺序表2.2 动态顺序表2.2.1 动态数据表初始化和销毁2.2.2 动态数据表的尾插尾删2.2.3 动态数据表的头插头删2.2.4 动态数据表的中间部分插入删除2.2.5 动态数据表的查询数据位置 3. 总结 1. 线性表 线性表&#xff08;linear list&#xff0…...

软件测试面试准备工作

1、 什么是数据库? 答&#xff1a;数据库是按照某种数据模型组织起来的并存放二级存储器中的数据集合。 2、 什么是关系型数据库? 答&#xff1a;关系型数据库是建立在关系数据库模型基础上的数据库&#xff0c; 借助集合代数等概念和方法处理数据库中的数据。目前主流的关…...