目录
一、项目结构
(1)项目基本组成结构
-
pages用来存放所有小程序的页面.
-
utils 用来存放工具性质的模块.
-
app.js 是小程序项目的入口文件.
-
app.json是小程序项目的全局配置文件
-
app.wxss是小程序项目的全局样式文件.
-
project.config.json是项目的配置文件
-
sitemap.json是用来配置小程序及其页面是否允许被微信索引.
(2)小程序页面的组成部分
-
.js文件(页面的脚本文件,存放页面的数据、事件处理函数等)
-
.json文件(当前页面的配置文件,配置窗口的外观、表现等)
-
.wxml文件(页面的模板结构文件)
-
.wxss文件(当前页面的样式表文件)
(3)小程序代码的构成
JSON配置文件
-
.JSON配置文件作用--在实际开发中,JSON总是以配置文件的形式出现,通过不同的.json配置文件,可以对小 程序项目进行不同级别的配置.
-
app.json是当前小程序的全局配置,包括了小程序的所有页面路径、窗口外观、页面表底部tab等.
{ "pages": [ //pages:用来记录当前小程序所有页面的存放路径 "pages/index/index" ], "window": { //window:全局定义小程序窗口的外观 "backgroundTextStyle": "light", "navigationBarBackgroundColor": "#fff", "navigationBarTitleText": "Weixin", "navigationBarTextStyle": "black" }, "style": "v2", //style:全局定义小程序组件所使用的样式版本 "sitemapLocation": "sitemap.json" //该部分用来指明sitemap.json的位置 }
-
project.config.json是项目配置文件,用来记录我们对小程序开发工具所做的个性化配置.
[1]setting中保存了编译相关的配置.
[2]projectname中保存的是项目名称.
[3]appid中保存的是小程序的账号ID.
4. sitmap.json文件用来配置小程序页面是否允许微信索引.
(sitemap的索引提示是默认开启的,如需要关闭sitemap的索引提示,可在project.config.json的setting中配置 字段checkSiteMap为false)
5. 小程序中的每一个页面,可以使用.json文件对本页面的窗口外观进行配置,页面中的配置项会覆盖app.json的window中相同的配置项.
6. 新建小程序页面--只需要在app.json~pages中新增页面的存放路径,小程序开发者工具即可帮我们自动创建对 应的页面文件.
7. 只需要调整app.json~pages数组中页面路径的前后顺序,即可修改项目的首页,小程序会把排在第一位的页面当作项目首页进行渲染.
WXML模板
-
WXML是小程序框架设计的一套标签语言,用来构建小程序页面的结构,其作用类似于网页开发中的HTML.
WXSS模板
-
WXSS是一套样式语言,用于描述WXML的组件样式,类似于网页开发中的HTML.
-
项目根目录中的app.wxss会作用于所有小程序页面;局部页面的.wxss样式仅对当前页面生效.
JS逻辑交互
-
在小程序中,通过.js文件来处理用户的操作.(例如响应用户的点击、获取用户的位置等等)
-
app.js文件是整个小程序项目的入口文件,通过调用App( )函数来启动整个小程序.
-
页面的.js文件是页面的入口文件,通过调用Page( )函数来创建并运行页面.
-
普通的.js文件是普通的功能模块文件,用来封装公共的函数或属性供页面使用.
二、宿主环境
(1)简介
-
宿主环境指的是程序运行所必须的依赖环境,脱离了宿主环境的软件是没有任何意义的.
-
手机微信是小程序的宿主环境.(小程序借助宿主环境提供的能力,可以完成许多普通网页无法完成的功能)
-
小程序宿主环境包含的内容有:通信模型、运行机制、组件以及API.
(2)通信模型
-
小程序中通信的主体是渲染层和逻辑层.
-
WXML模板和WXSS样式工作在渲染层.
-
JS脚本工作在逻辑层.
-
渲染层和逻辑层之间的通信、逻辑层和第三方服务器之间的通信都是由微信客户端进行转发.
(3)运行机制
小程序启动过程
-
把小程序的代码包下载到本地.
-
解析app.json全局配置文件.
-
执行app.js小程序入口文件,调用App( )创建小程序实例.
-
渲染小程序首页.
-
小程序启动完成.
页面渲染的过程
-
加载解析页面的.json配置文件.
-
加载页面的.wxml模板和.wxss样式.
-
执行页面的.js文件,调用Page( )创建页面实例.
-
页面渲染完成.
(4)组件
分类
-
小程序中的组件也是由宿主环境提供的,开发者可以基于组件快速搭建出漂亮的页面结构.
-
官方把小程序的组件分为了9大类,分别是:[1]视图容器 [2]基础内容 [3]表单组件 [4]导航组件 [5]媒体组件 [6]map地图组件 [7]canvas画布组件 [8]开放能力 [9]无障碍访问.
视图容器类组件
-
view
[1]普通视图区域.
[2]类似于HTML中的div,是一个块级元素.
[3]常用来实现页面的布局效果.
2. scroll-view
[1]可滚动的视图区域.(scroll-y属性:允许纵向滚动 scroll-y属性:允许横向滚动)
[2]常用来实现滚动列表效果.
[3]使用竖向滚动时,必须给scroll-view一个固定高度.
3. swiper和swiper-item
[1]轮播图容器组件和轮播图item组件.
[2]swiper组件的常用属性
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
indicator-dots | boolean | false | 是否显示面板指示点 |
indicator-color | color | rgba(0,0,.3) | 指示点颜色 |
indicator-active-color | color | #000000 | 当前选中的指示点颜色 |
autoplay | boolean | false | 是否自动切换 |
interval | number | 5000 | 自动切换时间间隔 |
circular | boolean | false | 是否采用衔接滑动 |
基础内容组件
-
text
[1]文本组件.
[2]类似于HTML中的span标签,是一个行内元素.
[3]通过text组件的selectable属性,实现长按选中文本内容的效果.
2. rich-text
[1]富文本组件.
[2]支持把HTML字符串渲染为WXML结构.
[3]通过rich-text组件的nodes属性节点,把HTML字符串渲染为对应的UI结构.
其它常用组件
-
button
[1]按钮组件.
[2]功能比HTML中的button按钮丰富.
[3]通过open-type属性可以调用微信提供的各种功能(客服、转发、获取用户授权、获取用户信息等)
[4]通过type指定按钮类型.(primary属性值:主色调按钮 warn属性值:警告按钮)
[5]size="mini"小尺寸按钮可以一行显示.
[6]设置plain属性为镂空按钮.
2. image
[1]图片组件.
[2]image组件默认宽度约300px、高度约240px.
[3]使用src指向图片路径.
[4]mode属性
mode值 | 说明 |
---|---|
scaleToFill | (默认值)缩放模式,不保持纵横比缩放图片,使图片的宽高完全拉伸至填满image元素 |
aspectFit | 缩放模式,保持纵横比缩放图片,使图片的长边能完全显示出来 |
aspectFill | 缩放模式,保持纵横比缩放图片,只保证图片的短边能完全显示出来 |
widthFix | 缩放模式,宽度不变,高度自动变化,保持原图宽高比不变 |
heightFix | 缩放模式,高度不变,宽度自动变化,保持原图宽高比不变 |
3. navigator
[1]页面导航组件.
[2]类似于HTML中的a链接.
(5)API
-
小程序官方把API分为3大类:事件监听、同步、异步.
-
事件监听API以on开头,用来监听某些事件的触发.
-
同步API以Sync结尾,其执行结果可以通过函数返回值直接获取,如果执行出错会抛出异常.
-
异步API类似于jQuery中的$.ajax(option)函数,需要通过success、fail、complete接收调用的结果.
三、协同工作与发布
(1)协同工作
-
了解权限管理需求-出于管理需要,我们迫切需要对不同岗位、不同角色的员工的权限进行边界的划分,使他们能够高效的进行协同工作.
-
了解项目成员的组织结构:项目管理者>>产品组、设计组、开发组、测试组.
-
小程序的开发流程:
(2)成员管理
-
小程序成员管理体现在管理员对小程序项目成员及其体验成员的管理.
-
项目成员:[1]表示参与小程序开发、运营的成员.[2]可登录小程序管理后台.[3]管理员可以添加、删除项目成员,并设置项目成员的角色.
-
体验成员:[1]表示参与小程序内侧体验的成员.[2]可使用体验版小程序,但不属于项目成员.[3]管理员及项目成员均可添加、删除体验成员.
(3)发布
-
小程序的版本
版本阶段 | 说明 |
---|---|
开发版本 | 使用开发者工具,可将代码上传到开发版本中.开发版本只保留每人最新的一份上传的代码.开发版本可删除,不影响线上版本和审核中版本的代码. |
体验版本 | 可以选择某个开发版本作为体验版,并且选取一份体验版 |
审核中的版本 | 只能有一份代码处于审核中.有审核结果后可以发布到线上,也可直接重新提交审核,覆盖原审核版本. |
线上版本 | 线上所有用户使用的代码版本,该版本代码在新版本代码发布后被覆盖更新. |
2. 发布上线整体流程-一般要经过上传代码~提交审核~发布这三个步骤.
四、模板与配置
(1)WXML模板语法
数据绑定
-
数据绑定的基本原则:[1]在data中定义数据. [2]在WXML中使用数据.
-
在data中定义数据-在页面对应的.js文件中,把数据定义到data对象中即可.
-
把data中的数据绑定到页面中渲染,使用Mustache语法将变量包起来即可.语法格式为:
<view>{{ 要绑定的数据名称 }}</view>
事件绑定
-
事件是渲染层到逻辑层的通讯方式,通过事件可以将用户在渲染层产生的行为,反馈到逻辑层进行业务的处理.
-
小程序中常用的事件:
类型 | 绑定方式 | 事件描述 |
---|---|---|
tap | bindtap或bind:tap | 手指触摸后马上离开,类似于HTML中的click事件 |
input | bindinput或bind:input | 文本框的输入事件 |
change | bindchange或bind:change | 状态改变时触发 |
3. 当事件回调触发的时候,会收到事件对象event,它的详细属性如下表所示:
属性 | 类型 | 说明 |
---|---|---|
type | String | 事件类型 |
timeStamp | Integer | 页面打开到触发事件所经过的毫秒数 |
target | Object | 触发事件的组件的一些属性值集合 |
currentTarget | Object | 当前组件的一些属性值集合 |
detail | Object | 额外的信息 |
touches | Array | 触摸事件,当前停留在屏幕中的触摸点信息的数组 |
changedTouches | Array | 触摸事件,当前变化的触摸点信息的数组 |
4. target是触发事件的源头组件,而currentTarget则是当前事件所绑定的组件.
5. bindtap的语法格式
<button type="primary" bindtap="btnTapHandler">按钮</button> <!-- .wxml文件 -->
Page({ //.js文件
btnTapHandler(e){ //按钮的tap事件处理函数
console.log(e) //事件参数对象e
}
})
6. 通过调用this.setData(dataObject)方法,可以给页面data中的数据重新赋值.
7. 小程序中的事件传参比较特殊,不能在绑定事件的同时为事件处理函数传递参数.
8. 可以为组件提供data-*自定义属性传参,其中 * 代表的是参数名字,示例代码如下:
<!--info会被解析为参数的名字 数值2会被解析为参数的值-->
<button bindtap="btnHandler" data-info="{{2}}">事件传参</button>
9. 在事件处理函数中,通过event.target.dataset.参数名即可获取到具体参数的值.
10. bindinput的语法格式
<input bindinput="inputHandler"></input> <!-- .wxml文件 -->
Page({ //.js文件
inputHandler(e){
//e.detail.value是变化过后,文本框最新的值
console.log(e.detail.value)
}
})
条件渲染
-
在小程序中,使用wx:if="{{condition}}"来判断是否需要渲染该代码块:
<view wx:if="{{condition}}"> True </view>
也可以用wx:elif和wx:else来添加else判断:
<view wx:if="{{type===1}}"> 男 </view>
<view wx:elif="{{type===2}}"> 女 </view>
<view wx:else> 保密 </view>
2. 如果要一次性控制多个组件的展示与隐藏,可以使用一个<block></bolck>标签将多个组件包装起来,并在<block>标签上使用wx:if控制属性,示例如下:
<block wx:if="{{true}}">
<view> view1 </view>
<view> view2 </view>
</block>
(<block>并不是一个组件,它只是一个包裹性质的容器,不会在页面中做任何渲染)
3. 在小程序中,直接使用hidden=“{{condition}}”也能控制元素的显示与隐藏.
4. wx:if与hidden的对比
[1]运行方式不同-wx:if以动态创建和移除元素的方式,控制元素的展示与隐藏;hidden以切换样式的方式(display:none/block;),控制元素的显示与隐藏.
[2]使用建议-频繁切换时,建议使用hidden;控制条件复杂时,建议使用wx:if搭配wx:elif、wx:else进行展示与隐藏的切换.
列表渲染
-
通过wx:for可以根据指定的数组,循环渲染重复的组件结构,语法示例如下:
<view wx:for="{{array}}"> <!--默认情况下,当前循环项的索引用index表示;当前循环项用item表示-->
索引是:{{index}} 当前项是:{{item}}
</view>
2. 使用wx:for-index可以指定当前循环项的索引的变量名.
3. 使用wx:for-item可以指定当前项的变量名.
4. 使用wx:key可以为渲染出来的列表项指定唯一的key值,从而提高渲染的效率.
(2)WXSS模板样式
-
WXSS是一套样式语言,用于美化WXML的组件样式,类似于网页开发中的CSS.
-
rpx是微信小程序独有的,用来解决屏适配的尺寸单位. (鉴于不同设备屏幕的大小不同,为了实现屏幕的自动适配,rpx把所有设备的屏幕在宽度上等分为750份)
-
使用WXSS提供的@import语法,可以导入外联的样式表. (@import后跟需要导入的外联样式表的相对路径,用 ; 表示语句结束)
-
当局部样式的权重大于或等于全局样式的权重时,才会覆盖全局的样式.
(3)全局配置
-
了解window节点常用的配置项
属性名 | 类型 | 默认值 | 说明 |
---|---|---|---|
navigationBarTitleText | String | 字符串 | 导航栏标题文字内容 |
navigationBarBackgroundColor | HexColor | #000000 | 导航栏背景颜色 |
navigationBarTextStyle | String | white | 导航栏标题颜色,仅支持black/white |
backgroundColor | HexColor | #ffffff | 窗口的背景色 |
backgroundTextStyle | String | dark | 下拉loading的样式,仅支持dark/light |
enablePullDownRefresh | Boolean | false | 是否全局开启下拉刷新 |
onReachBottomDistance | Number | 50 | 页面上拉触底事件触发时距页面底部距离,单位为px |
2. 下拉刷新是移动端的专有名词,指的是通过手指在屏幕上的下拉滑动操作,从而重新加载页面数据的行为.
3. 上拉触底是移动端的专有名词,通过手指在屏幕上的上拉滑动操作,从而加载更多数据的行为.
4. tabBar是移动端应用常见的页面效果,用于实现多页面的快速切换. (tabBar中只能配置最少2个、最多5个tab页签) (当渲染顶部tabBar时,不显示icon,只显示文本)
5. tabBar节点的配置项
属性 | 类型 | 必填 | 默认值 | 描述 |
---|---|---|---|---|
position | String | 否 | bottom | tabBar的位置,仅支持bottom/top |
borderStyle | String | 否 | black | tabBar上边框的颜色,仅支持black/white |
color | HexColor | 否 | tab上文字的默认(未选中)颜色 | |
selectedColor | HexColor | 否 | tab上的文字选中时的颜色 | |
backgroundColor | HexColor | 否 | tabBar的背景色 | |
list | Array | 是 | tab页签的列表 |
6. 每个tab项的配置选项
属性 | 类型 | 必填 | 描述 |
---|---|---|---|
pagePath | String | 是 | 页面路径,页面必须在pages中预先定义 |
text | String | 是 | tab上显示的文字 |
iconPath | String | 否 | 未选中时的图标路径;当postion为top时,不显示icon |
selectedIconPath | String | 否 | 选中时的图标路径;当postion为top时,不显示icon |
(4)网络数据请求
-
只能请求HTTPS类型的接口.(不能使用IP地址或localhost,必须经过ICP备案)
-
必须将接口的域名添加到信任列表中.
-
调用微信小程序提供的wx.request( )方法,可以发起GET数据请求,示例代码如下:
wx.request({
url:'https://www.escook.cn/api/get', //请求的接口地址,必须基于https协议
method:'GET', //请求的方式
data:{ //发送到服务器的数据
name:'zs',
age:22
},
success:(res)=>{ //请求成功之后的回调函数
console.log(res)
}
})
4.在很多情况下,我们需要在页面刚加载的时候,自动请求一些初始化的数据,此时需要在页面的onLoad事件中调用获取数据的函数.
5. 跨域问题只存在于基于浏览器的Web开发中,由于小程序的宿主环境不是浏览器,而是微信客户端,所以小程序中不存在跨域的问题.
6. Ajax技术的核心是依赖于浏览器中的XMLHttpRequest这个对象,由于小程序的宿主环境是微信客户端,所以小程序中不能叫做“发起Ajax请求”,而是叫做“发起网络数据请求”.
五、视图与逻辑
(1)页面导航
-
页面导航指的是页面之间的相互跳转.
-
小程序中实现页面导航的两种方式
[1]声明式导航:在页面上声明一个<navigator>导航组件,通过点击该组件实现页面跳转.
[2]编程式导航:调用小程序的导航API,实现页面的跳转.
3. 声明式导航
[1]导航到tabBar页面
<!-- url表示要跳转的页面的地址,必须以 / 开头 -->
<!-- open-type表示跳转的方式,必须为switchTab -->
<navigator url="/pages/xx/xx" open-type="switchTab">导航到xx页面</navigator>
[2]导航到非tabBar页面
<!-- url表示要跳转的页面的地址,必须以 / 开头 -->
<!-- open-type表示跳转的方式,必须为navigate (可以省略该属性) -->
<navigator url="/pages/xx/xx" open-type="navigate">导航到xx页面</navigator>
[3]后退导航
<!-- open-type表示跳转的方式,必须为navigateBack,表示要进行后退导航 -->
<!-- delta的值必须是数字,表示要后退的层级 -->
<!-- 如果只是后退到上一页面,则可以省略delta属性,因为其默认值就是1 -->
<navigator open-type="navigateBack" delta='1'>返回上一页</navigator>
4. 编程式导航
[1]导航到tabBar页面
调用wx.switchTab(Object object)方法,可以跳转到tabBar页面,其中Object参数对象的属性列表如下:
属性 | 类型必填 | 说明 | |
---|---|---|---|
url | string | 是 | 需要跳转的tabBar页面的路径,路径后不能带参数 |
success | function | 否 | 接口调用成功的回调函数 |
fail | function | 否 | 接口调用失败的回调函数 |
complete | function | 否 | 接口调用结束的回调函数 |
[2]导航到非tabBar页面
调用wx.navigateTo(Object object)方法,可以跳转到非tabBar页面,其中Object参数对象的属性列表同上.
[3]后退导航
调用wx.navigateBack(Object object)方法,可以返回上一页面或多级页面,其中Object的属性列表如下:
属性 | 类型 | 默认值 | 必填 | 说明 |
---|---|---|---|---|
delta | number | 1 | 否 | 返回的页面数,如果delta大于现有页面数,则返回到首页 |
success | function | 否 | 接口调用成功的回调函数 | |
fail | function | 否 | 接口调用失败的回调函数 | |
complete | function | 否 | 接口调用结束的回调函数 |
5. 导航传参
[1]声明式导航传参(在路径的后面携带参数)
<!-- 参数与路径之间使用?分隔 -->
<!-- 参数键与参数值用=相连 -->
<!-- 不同参数用&分隔 -->
<navigator url="/pages/info/info?name=zrl&age=19">跳转到info页面</navigator>
[2]编程式导航传参
<button bindtap="gotoInfo">跳转到info页面</button>
gotoInfo(){
wx.navigateTo({
url:'/pages/info/info?name=zrl&age=19'
})
}
[3]在onLoad中接收导航参数
通过声明式导航传参或编程式导航传参所携带的参数,可以直接在onLoad事件中直接获取到,示例代码如下:
/**
*生命周期函数--监听页面加载
*/
onLoad:function(options){
//options就是导航传递过来的参数对象
console.log(options)
}
(2)页面事件
-
在页面的.js文件中,通过onPullDownRefresh( )函数即可监听当前页面的下拉刷新事件.
-
当处理完下拉刷新后,下拉刷新的loading效果会一直显示,不会主动消失,所以需要手动隐藏loading效果,此时,调用wx.stopPullDownRefresh( )可以停止当前页面的下拉刷新.
-
在页面的.js文件中,通过onReachBottom( )函数即可监听当前页面的上拉触底事件.
-
调用wx.showLoading(Object object)可以显示loading提示框. (需主动调用wx.hideLoading( )才能关闭提示框)
属性 | 类型 | 默认值 | 必填 | 说明 |
---|---|---|---|---|
title | string | 是 | 提示的内容 | |
mask | boolean | false | 否 | 是否显示透明蒙层,防止触摸穿透 |
success | function | 否 | 接口调用成功的回调函数 | |
fail | function | 否 | 接口调用失败的回调函数 | |
complete | function | 否 | 接口调用结束的回调函数 |
5. 调用wx.setNavigationBarTitle(Object object)可以动态设置当前页面的标题.
属性 | 类型 | 必填 | 说明 |
---|---|---|---|
title | string | 是 | 页面标题 |
success | function | 否 | 接口调用成功的回调函数 |
fail | function | 否 | 接口调用失败的回调函数 |
complete | function | 否 | 接口调用结束的回调函数 |
6. 调用wx.showToast(Object object)可以显示消息提示框.
属性 | 类型 | 默认值 | 必填 | 说明 |
---|---|---|---|---|
title | string | 是 | 提示的内容 | |
icon | string | 'success' | 否 | 图标 |
image | string | 否 | 自定义图标的本地路径,image的优先级高于icon | |
duration | number | 1500 | 否 | 提示的延迟时间 |
mask | boolean | false | 否 | 是否显示透明蒙层,防止触摸穿透 |
success | function | 否 | 接口调用成功的回调函数 |
(3)生命周期
-
生命周期是指一个对象从创建>>运行>>销毁的整个阶段,强调的是一个时间段.
-
小程序的启动,表示生命周期的开始;小程序的关闭,表示生命周期的结束.
-
应用生命周期特指小程序从启动>>运行>>销毁的过程.
-
页面生命周期特指小程序从加载>>渲染>>销毁的过程.
5. 生命周期函数-是由小程序框架提供的内置函数,会伴随着生命周期,自动按次序执行.
6. 生命周期函数的作用-允许程序员在特定的时间点,执行某些特定的操作.
7. 生命周期强调的是时间段,生命周期函数强调的是时间点.
8. 小程序的应用生命周期函数需要在app.js中进行声明,示例代码如下:
App({
//小程序初始化完成时,执行此函数,全局只触发一次,可以做一些初始化的工作
onLaunch:function(options){},
//小程序启动,或从后台进入前台显示时触发
onShow:function(options){},
//小程序从前台进入后台时触发
onHide:function(){}
})
9. 小程序的页面生命周期函数需要在页面的.js中进行声明,示例代码如下:
Page({
onLoad:function(options){}, //监听页面加载,一个页面只调用1次
onShow:function(){}, //监听页面显示
onReady:function(){}, //监听页面初次渲染完成,一个页面只调用1次
onHide:function(){}, //监听页面隐藏
onUnload:function(){} //监听页面卸载,一个页面只调用1次
})
(4)WXS脚本
-
WXS是小程序独有的一套脚本语言,结合WXML,可以构建出页面的结构.
-
wxml中无法调用在页面的.js中定义的函数,但是,wxml中可以调用wxs中定义的函数,因此,小程序中wxs的典型应用场景就是"过滤器",经常配合Mustache语法进行使用.
-
在wxs中定义的函数不能作为组件的事件回调函数.
-
虽然wxs的语法类似于JavaScript,但是wxs和JavaScript是完全不同的两种语言:
[1]wxs有自己的数据类型. [2]wxs不支持类似于ES6及以上的语法形式. [3]wxs遵循CommonJS规范.
5. 内嵌wxs脚本
[1]wxs代码可以编写在wxml文件中的<wxs>标签内,就像Javascript代码可以编写在html文件中的<script>标签内一样.
[2]wxml文件中的每个<wxs></wxs>标签,必须提供module属性,用来指定当前wxs的模块名称,方便在wxml中访问模块中的成员.
<view>{{m1.toUpper(username)}}</view>
<wxs module="m1">
<!-- 将文本转为大写形式 -->
module.exports.toUpper=function(str){
return str.toUpperCase()
}
</wxs>
6. 定义外联的wxs脚本
[1]wxs代码还可以编写在以.wxs为后缀名的文件内,就像javascript代码可以编写在以.js为后缀名的文件中一样.
function toLower(str){
return str.toLowerCase()
}
module.exports={
toLower:toLower
}
7. 使用外联的wxs脚本
[1]在wxml中引入外联的wxs脚本时,必须为<wxs>标签添加module和src属性.
[2]module用来指定模块的名称;src用来指定要引入的脚本的路径,且必须是相对路径.
<!-- 调用m2模块中的方法 -->
<view>{{m2.toLower(country)}}</view>
<!-- 引用外联的tools.wxs脚本,并命名为m2 -->
<wxs src="../../utils/tools.wxs" module="m2"></wxs>
六、自定义组件
(1)组件的创建与引用
组件的创建
-
在项目的根目录中,鼠标右键,创建components>>test文件夹.
-
在新建的components>>test文件夹上,鼠标右键,点击"新建Component".
-
键入组件的名称之后回车,会自动生成组件对应的4个文件,后缀名分别为.js,.json,.wxml,.wxss.
组件的引用
-
在页面的.json配置文件或app.json全局配置文件中引用组件的方式,示例代码如下:
//在.json文件中,引入组件
{
"usingComponents":{
"my-test-1":"/components/test1/test1"
}
}
<!-- 在页面的.wxml文件中,使用组件-->
<my-test1></my-test1>
2. 组件和页面的.js与.json文件有明显的不同:
[1]组件的.json文件中需要声明"component":true属性.
[2]组件的.js文件中调用的是Component( )函数.
[3]组件的事件处理函数需要定义到methods节点中.
(2)样式
-
组件样式隔离-默认情况下,自定义组件的样式只对当前组件生效,不会影响到组件之外的UI结构.
-
app.wxss中的全局样式对组件无效.
-
只有class选择器会有样式隔离效果,id选择器、属性选择器、标签选择器不受样式隔离的影响.
-
修改组件的样式隔离选项
//在组件的.js文件中新增如下配置
Component({
options:{
styleIsonlation:'isolated'
}
})
//或在组件的.json文件中新增如下配置
{
"styleIsonlation":"isolated"
}
可选值 | 默认值 | 描述 |
---|---|---|
isolated | 是 | 表示启用样式隔离,在自定义组件内外,使用class指定的样式将不会相互影响 |
apply-shared | 否 | 表示页面页面wxss样式将影响到自定义组件,但自定义组件wxss中指定的样式不会影响页面 |
shared | 否 | 表示页面wxss样式将影响到自定义组件,自定义组件wxss中指定的样式也会影响页面和其他设置apply-shared或shared的自定义组件 |
(3)数据、方法和属性
-
data数据-在小程序组件中,用于组件模板渲染的私有数据,需要定义到data节点中.
-
methods方法-在小程序组件中,事件处理函数和自定义方法需要定义到methods节点中.
-
properties属性-在小程序组件中,properties是组件对外属性,用来接受外界传递到组件中的数据,示例代码如下:
Component({
//属性定义
properties:{
max:{ //完整定义属性的方法(当需要指定属性默认值时,使用该方式)
type:Number, //属性值的数据类型
value:10 //属性默认值
},
max:Number //简化定义属性的方法(不需要指定属性默认值时,可以使用简化方式)
}
})
<my-test1 max="10"></my-test1>
4. data更倾向于存储组件的私有数据;properties更倾向于存储外界传递到组件中的数据.
5. 由于data数据和properties属性在本质上没有任何区别,因此properties属性的值也可以用于页面渲染,或使用setData为properties中的属性重新赋值.
(4)数据监听器
-
数据监听器用于监听和响应任何属性和数据字段的变化,从而执行特定的操作.
-
数据监听器的基本语法格式:
Component({
observers:{
'字段A,字段B':function(字段A的新值,字段B的新值){
//do something
}
}
})
3. 如果某个对象中需要被监听的属性太多,为了方便,可以使用通配符**来监听对象中所用属性的变化,示例代码如下:
observers:{
'rgb.**':function(obj){
this.setData({
fullColor:`${obj.r},${obj.g},${obj.b}`
})
}
}
(5)纯数据字段
-
纯数据字段指的是那些不用于界面渲染的data字段.(纯数据字段有助于提升页面更新的性能)
-
使用-在Component构造器的options节点中,指定pureDataPattern为一个正则表达式,字段名符号这个正则表达式的字段将成为纯数据字段,示例代码如下:
Component({
options:{
//指定所有 _ 开头的数据字段为纯数据字段
pureDataPattern:/^_/
},
data:{
a:true //普通数据字段
_b:true //纯数据字段
}
})
(6)组件的生命周期
-
组件全部的生命周期函数
生命周期函数 | 参数 | 描述说明 |
---|---|---|
created | 无 | 在组件实例刚刚被创建时执行 |
attached | 无 | 在组件实例进入页面节点树时执行 |
ready | 无 | 在组件在视图层布局完成后执行 |
moved | 无 | 在组件实例被移动到节点树另一个位置时执行 |
detached | 无 | 在组件实例被从页面节点树移除时执行 |
error | Object Error | 每当组件方法抛出错误时执行 |
2.组件主要的生命周期函数
[1]组件实例刚被创建好的时候,created生命周期函数会被触发.
>>此时还不能调用setData.
>>通常在这个生命周期函数中,只应该用于给组件的this添加一些自定义的属性字段.
[2]在组件完全初始化完毕、进入页面节点树后,attached生命周期函数会被触发.
>>此时,this.data已被初始化完毕.
>>这个生命周期很有用,绝大数初始化的工作可以在这个时机进行(例如发请求获取初始数据)
[3]在组件离开页面节点树后,detached生命周期函数会被触发.
>>退出一个页面时,会触发页面内每个自定义组件的detached生命周期函数.
>>此时适合做一些清理性质的工作.
3. lifetimes节点-在小程序组件中,生命周期函数可以直接定义在Component构造器的第一级参数中,可以在lifetimes字段内进行声明.(这是推荐的方式,其优先级最高)
4. 组件所在页面的生命周期 (有时,自定义组件的行为依赖于页面状态的变化,此时就需要用到组件所在页面的生命周期)
生命周期函数 | 参数 | 描述 |
---|---|---|
show | 无 | 组件所在的页面被展示时执行 |
hide | 无 | 组件所在的页面被隐藏时执行 |
resize | Object Size | 组件所在的页面尺寸变化时执行 |
5. 组件所在页面的生命周期函数,需要定义在pageLifetimes节点中.
(7)插槽
-
定义-在自定义组件的wxml结构中,可以提供一个<slot>节点,用于承载组件使用者提供的wxml结构.
-
在小程序中,默认每个自定义组件中只允许使用一个<slot>进行占位,这种个数上的限制叫做单个插槽.
-
启用多个插槽-在小程序的自定义组件中,需要使用多<slot>插槽时,可以在组件的.js文件中,通过如下方式进行启用,示例代码如下:
Component({
option:{
multipleSlots:true //在组件定义时的选项中启用多slot支持
},
properties:{/*...*/},
methods:{/*...*/}
})
4. 可以在组件的.wxml中使用多个<slot>标签,以不同的name来区分不同的插槽.
5. 使用多个插槽-在使用带有多个插槽的自定义组件时,需要用slot属性来将节点插入到不同的<slot>中.
(8)父子组件之间的通信
-
通信方式
[1]属性绑定-用于父组件向子组件的指定属性设置数据,仅能设置JSON兼容的数据.
[2]事件绑定-用于子组件向父组件传递数据,可以传递任意数据.
[3]获取组件实例-父组件还可以通过this.selectComponent("id或class选择器")获取子组件实例对象,这样就可以直接访问子组件的任意数据和方法.
2. 属性绑定
[1]属性绑定用于实现父向子传值,而且只能传递普通类型的数据,无法将方法传递给子组件.
[2]子组件在properties节点中声明对应的属性并使用.
3. 事件绑定步骤
[1]在父组件的js中,定义一个函数,这个函数即将通过自定义事件的形式,传递给子组件.
//在父组件中定义syncCount方法
//将来,这个方法会被传递给子组件,供子组件进行调用
syncCount(){
console.log('syncCount')
}
[2]在父组件的wxml中,通过自定义事件的形式,将步骤1中定义的函数引用,传递给子组件.
<!-- 使用bind:自定义事件名称(推荐:结构清晰) -->
<my-test3 count="{{count}}" bind:sync="syncCount"></my-test3>
<!-- 或在bind后面直接写上自定义事件名称 -->
<my-test3 count="{{count}}" bindsync="syncCount"></my-test3>
[3]在子组件的js中,通过调用==this.triggerEvent('自定义事件名称',{/* 参数对象 */}),将数据发送到父组件.
[4]在父组件的js中,通过e.detail获取到子组件传递过来的数据.
(9)behaviors
-
behaviors是小程序中,用于实现组件间代码共享的特性.
-
每个behavior可以包含一组属性、数据、生命周期函数和方法,组件引用它时,它的属性、数据和方法会被合并到组件中.(每个组件可以引用多个behavior,behavior也可以引用其它behavior)
-
创建behavior (调用Behavior(Object object)方法即可创建一个共享的behavior实例对象,供所有的组件使用)
//调用Behavior()方法,创建实例对象
//并使用module.exports将behavior实例对象共享出去
module.exports=Behavior({
//属性节点
properties:{},
//私有数据节点
data:{username:'zs'},
//事件处理函数和自定义方法节点
methods:{},
//其他节点...
})
4. 导入并使用behavior-在组件中,使用require( )方法导入需要的behavior,挂载后即可访问behavior中的数据或方法,示例代码如下:
//1.使用require()导入需要的自定义behavior模块
const myBehavior=require("../../xx/xx1")
Component({
//2.将导入的behavior实例对象,挂载到behaviors数组节点中,即可生效
behaviors:[myBehavior],
//组件的其它节点...
})
5. 组件和它引用的behavior中可以包含同名的字段,对这些字段的处理方法如下:
[1]如果有同名的属性或方法:
>>若组件本身有这个属性或方法,则组件的属性或方法会覆盖behavior中的同名属性或方法.
>>若组件本身无这个属性或方法,则在组件的behavior字段中定义靠后的behavior的属性或方法会覆盖靠前的 同名属性或方法.
>>若存在嵌套引用behavior的情况,则规则为:父behavior覆盖子behavior中的同名属性或方法.
[2]如果有同名的数据字段:
>>若同名的数据字段都是对象类型,会进行对象合并.
>>其余情况会进行数据覆盖,优先级高的覆盖优先级低的.
[3]生命周期函数不会相互覆盖,而是在对应触发时机被逐个调用:
>>对于不同的生命周期函数之间,遵循组件生命周期函数的执行顺序.
>>对于同种生命周期函数,遵循优先级低的优先执行.
>>如果同一个behavior被一个组件多次引用,它定义的生命周期函数只会被执行一次.