typora-root-url: 图片
typora-copy-images-to: 图片
1.小程序简介
1.小程序与普通网页开发的区别
-
运行环境不同
-
网页运行在浏览器环境中
-
小程序运行在微信环境中
-
-
API不同
-
由于运行环境不同,所以小程序中,无法调用DOM和BOM的API。但是小程序可以调用微信环境提供的各种API,例如:地理定位 ,扫码 ,支付。
-
-
开发模式不同
-
网页开发模式:浏览器+代码编辑器小程序有自己的一套标注开发模式:申请小程序开发账号 ,安装小程序开发者工具 ,创建和配置小程序项目
-
2 . 了解项目的基本组成结构
-
pages (存放所有小程序的页面)
-
utils 用来存放工具性质的模块(例如:格式化时间的自定义模块)
-
app.js 小程序项目的入口文件
-
app.json 小程序项目的全局配置文件
-
app.wxss 小程序项目的全局样式文件
-
project.config.json 项目的配置文件
-
sitemap.json 用来配置小程序及其页面是否允许被微信索引
3. 小程序页面的组成部分
小程序官方建议把所有小程序的页面,都放在pages目录中,以单独的文件夹存在,如图:
其中,每个页面由4个基本文件组成,它们分别是:
-
xxx.js : 页面脚本文件,存放页面的数据,事件处理函数等
-
xxx.json : 当前页面的配置文件,配置窗口的外观,表现等
-
xxx.wxml : 页面的模板构成文件
-
xxx.wxss : 当前页面的样式表文件
2.小程序代码构成
1.JSON配置文件的作用:
JSON 是一种数据格式 ,在实际开发中 ,JSON总是以配置文件的形式出些 。小程序项目中也不例外 :通过不同的 .json配置文件 ,可以对小程序项目进行不同级别的配置。
小程序项目中有4种json配置文件 , 分别是:
-
项目根目录中的app.json
-
项目根目录中的project.config.json
-
项目根目录中的sitemap.json
-
每个页面文件夹中的 json
app.json 文件
app.json 是当前小程序的全局配置 ,包括了小程序的所有页面路径,窗口外观,界面表现 ,底部tab等。代码如下
{ "pages":[ "pages/index/index", "pages/logs/logs" ], "window":{ "backgroundTextStyle":"light", "navigationBarBackgroundColor": "#fff", "navigationBarTitleText": "Weixin", "navigationBarTextStyle":"black" }, "style": "v2", "sitemapLocation": "sitemap.json" }
简单了解代码中的四个配置作用:
-
pages : 用来记录当前小程序所有页面的路径
-
window : 全局定义小程序所有页面的背景色 ,文字颜色等
-
style : 全局定义小程序组件所使用的样式版本(V2最新版本如果想要使用老版本把它删除即可)
-
sitemapLocation :用来指明sitemap.json的位置
project.config.json 文件
project.config.json 是项目配置文件,用来记录我们对小程序开发工具做的个性化配置,例如:
-
setting 中保存了编译器相关的配置
-
projectname 中保存的是项目名称
-
appid 保存的是小程序的账号ID
sitemap.json 文件
微信已开放小程序内搜索,效果类似与PC网页的SEO 。 sitemap.json文件用来配置小程序页面是否允许微信索引。
当开发者允许微信索引时,微信会通过爬虫的形式,为小程序的页面内容建立索引。当用户的搜索关键字和页面的索引匹配成功的时候,小程序的页面将可能展示在搜索的结果中。
注意 :sitemap 的索引提示默认开启的,如果需要关闭sitemap 的索引提示,可在微信小程序项目配置文件 project.config.json的setting 中配置字段 checkSiteMap 为 false 即可!
页面的 .json配置文件
小程序的每一个页面,可以使用.json文件来对本页面的窗口外观进行配置,页面中的配置项会覆盖app.json的window中相同的配置项。例如:"navigationBarBackgroundColor": "#00b26a"
微信头顶颜色的配置 当页面配置和全局配置冲突的时候相同取页面的配置~
新建小程序页面
只需要在app.json-->pages中新增页面的存放路径,小程序开发者工具即可帮我们自动创建对应的页面文件
修改项目首页
只需要调整app.json-->pages 数组中页面路径的前后顺序,即可修改项目的首页。小程序会把排在第一位的页面,当作项目首页进行血染。
WXML模板
什么是WXML
wxml(WeiXin Markup Language) 是微信小程序框架设计的一套标签语言,用来构建小程序页面的结构,其作用类似于网页开发中的HTML
WXML和HTML的区别
-
标签名称不同
-
HTML (div , span , img , a)
-
WXML (view , text , image , navigator)
-
-
属性节点不同
-
< a href="#">超链接</a>
-
< navigator url="/pages/home/home"></navigator>
-
-
提供了类似Vue中的模板语法
-
数据绑定
-
列表渲染
-
条件渲染
-
WXSS样式
什么是WXSS
wxss(Weixin Style Sheets) 是一套样式语言 ,用于描述WXML组成样式 ,类似于网页开发中的CSS.
WXSS和CSS的区别
-
新增了rpx尺寸单位
-
CSS中需要手动进行像素单位换算 ,例如 rem
-
WXSS在底层支持新的尺寸单位rpx , 在不同大小的屏幕上小程序会自动进行换算
-
-
提供了全局的样式和局部样式
-
项目根目录中的app.wxss会作用所有小程序页面
-
局部页面的.wxss样式仅对当前页面生效
-
-
WXSS仅支持部分CSS选择器
-
.class 和 #id
-
element
-
并集选择器 ,后代选择器
-
::after 和 ::before 等伪类选择器
-
Js逻辑交互
小程序中的.js文件
一个项目仅仅提供界面展示是不够的 ,在微信小程序中 ,我们通过 .js 文件来处理用户的操作 。例如:响应用户的点击,获取用户的位置等等。
小程序中 .js 文件的分类
小程序中的 JS 文件分为三大类 ,分别是:
-
app.js
-
是整个小程序项目的入口文件 ,通过调用App()函数来启动整个小程序
-
-
页面的 .js文件
-
是页面的入口文件 ,通过调用page()函数来创建并运行页面
-
-
普通的 .js文件
-
是普通的功能模块文件,用来封装公共的函数或属性拱页面使用
-
3.小程序宿主环境
1.什么是宿主环境
宿主环境(host environment) 指的是程序运行必须的依赖环境 。例如:
Android 系统 和 iOS系统就是两个不同的宿主环境。安卓的微信app是不可以在ios 环境下运行的。所以Android是安卓软件的宿主环境,脱离了宿主环境的软件是没有任何意义的!
2.小程序的宿主环境
手机微信是小程序的宿主环境!!!
小程序借助宿主环境提供的能力,可以完成许多普通网页无法完成的功能,例如:微信扫码 ,微信支付 ,微信登录 ,地理定位,etc等。
3.小程序宿主环境包含的内容
-
通信模型
-
运行机制
-
组件
-
API
通信模型
1.通信的主体
小程序中通行的主体是渲染层和逻辑层 ,其次:
-
WXML模板和WXSS样式工作在渲染层
-
JS脚本工作在逻辑层
2.小程序的通信模型
小程序中的通信模型分为两个部分:
-
渲染层和逻辑层之间的通信
-
由微信客户端进行转发
-
-
逻辑层和第三方服务器之间的通信
-
由微信客户端进行转发
-
小程序的启动过程(运行机制)
1.把小程序的代码包下载到本地
2.解析app.json全局配置文件
3.执行app.js小程序入口文件,调用App()创建小程序实例
4.渲染小程序首页
5.小程序启动完成
页面的渲染过程
-
加载解析页面的.json配置文件
-
加载页面的.wxml模板和.wxss样式
-
执行页面的.js文件 ,调用Page()创建页面比例
-
页面渲染完成
小程序宿主环境——组件
1.小程序中组件的分类
小程序中的组件也是由宿主环境提供的,开发者可以基于组件快速搭建出漂亮的页面结构。官方把小程序的组件分为9大类,分别是:
-
视图容器
-
基础内容
-
表单组件
-
导航组件
-
媒体组件
-
map地图组件
-
canvas画布组件
-
开放能力
-
无障碍访问
2常见视图容器组件
1.view
-
普通视图区域
-
类似于HTML中的div , 是一个块级元素
-
常用来实现页面的布局效果
2.scroll-view
-
可滚动的视图区域
-
常用来实现滚动列表效果
3.swiper和swiper-item
-
轮播图容器组件 和 轮播图item组件
view组件的基本使用
实现flex横向布局效果:
代码如下:
list.wxml
<!--pages/list/list.wxml--> <view class="container1"> <view>A</view> <view>B</view> <view>C</view> </view>
list.wxml
/* pages/list/list.wxss */ .container1 view { width: 100px; height: 100px; text-align: center;/*文本居中*/ line-height: 100px;/*垂直局中*/ } /* 挑选3个view*/ .container1 view:nth-child(1){ background-color: aqua; } .container1 view:nth-child(2){ background-color: brown; } .container1 view:nth-child(3){ background-color: blue; } .container1{ display: flex;/*大盒子里的横向布局*/ justify-content: space-around;/*三个盒子中留空*/ }
scroll-view的使用
左右上下的划图盒子
代码如下:
aa.wxml
<!--pages/aa/aa.wxml--> <!--scroll-view滑动盒子 scroll-y y轴滑动--> <scroll-view class="aaa" scroll-y> <view>AS</view> <view>Ms</view> <view>GG</view> </scroll-view>
aa.wxss
/* pages/aa/aa.wxss */ .aaa view{ width: 100px; height: 100px; text-align: center; line-height: 100px; } .aaa view:nth-child(1){ background-color: chartreuse; } .aaa view:nth-child(2){ background-color: coral; } .aaa view:nth-child(3){ background-color: darkgreen; } .aaa { /*设置边框*/ border: 6px solid red; /*设置scroll-view的高为120px*/ height: 160px; width: 100px; }
swiper和swiper-item的使用
实现轮播效果图:
代码如下:
swiper.wxml
<!--pages/swiper/swiper.wxml--> <!--轮播图的结构 indicator-dots:轮播图下的小圆点 indicator-color="white:设置没有激活的小圆点为白色\ indicator-active-color="red":设置激活的小圆点为红色 autoplay:自动切换轮播图 默认时间为5s interval="1000":修改轮播图自己的轮播时间为一秒 circular="talse:开启衔接滑动 默认关闭 --> <swiper class="swiper-container" indicator-dots indicator-color="white" indicator-active-color="red" autoplay interval="1000" circular="talse"> <!--第一个轮播图--> <swiper-item> <view class="AA">A</view> </swiper-item> <!--第二个轮播图--> <swiper-item> <view class="AA">B</view> </swiper-item> <!--第三个轮播图--> <swiper-item> <view class="AA">C</view> </swiper-item> </swiper>
swiper.wxss
/* pages/swiper/swiper.wxss */ .swiper-container{ height: 150px; } .AA{ /*设置AA里的盒子高和swiper-container盒子的高一样*/ height: 100%; line-height: 150px; text-align: center; } /* 注意要空格 .AA要不然不显示颜色*/ swiper-item:nth-child(1) .AA{ background-color: red; } swiper-item:nth-child(2) .AA{ background-color:royalblue; } swiper-item:nth-child(3) .AA{ background-color:magenta; }
swiper的属性:
3.常见的基础内容组件
-
text
-
文本组件
-
类似于HTML中的span标签,是一个内行元素
-
-
rich-text
-
富文本组件
-
支持把HTML字符串渲染为WXML结构
-
text组件的基本使用
-
通过tetx组件的selectable属性 ,实现长按选中文本内容的效果:
text.wxml
<!--pages/text/text.wxml--> <view> 手机号支持长按选中效果 <text user-select="true">18586537371</text> </view>
rich-text组件的基本使用
通过rich-text组件nodes属性节点 ,把HTML字符串渲染为对应的UI结构:
text.wxml
<!--pages/text/text.wxml--> <view> 手机号支持长按选中效果 <text user-select="true">18586537371</text> </view> <rich-text nodes="<h1 style='color: red;'>凯尔库兹马</h1>"></rich-text>
4.其他组件
-
button(按钮组件)
-
按钮组件
-
功能比HTML里的按钮button按钮丰富
-
通过open-type属性可以调节用微信提供的各种功能(客服 ,转发 ,获取用户权限 ,获取用户信息等)
-
-
image(图片组件)
-
图片组件
-
image组件默认宽度约300px , 高度约240px
-
-
navigator (导航组件 类似a标签)
-
页面导航组件
-
类似于HTML中的a链接
-
button按钮
button.wxml
<!--pages/button/button.wxml--> <text>pages/button/button.wxml</text> <view>---------------通过type指定按钮类型---------------</view> <!--通过type属性指定按钮颜色类型--> <!--按钮组件的基本使用--> <button>普通按钮</button> <button type="primary">主色调按钮</button> <button type="warn">警告按钮</button> <view>---------------size="mini"尺寸按钮类型------------</view> <!--size="mini" 小尺寸按钮--> <button size="mini">默认按钮</button> <button type="primary" size="mini">主色调按钮</button> <button type="warn" size="mini">警告按钮</button> <view>----------------plain镂空按钮类型------------------</view> <!--plain 镂空按钮--> <button size="mini" plain>默认按钮</button> <button type="primary" size="mini" plain>主色调按钮</button> <button type="warn" size="mini" plain>警告按钮</button>
image组件
image组件的mode属性用来指定图片的剪裁和缩放模式 ,常用的mode属性值如下:
mode值
scaleToFill (默认值) 缩放模式 不保持纵横比缩放图片 使图片的宽高完全拉伸至填满image元素
aspectFit 缩放模式 保持纵横比缩放图片 使图片能完全显示出来 但是会有空白缝隙
aspecFill 缩放模式 保持纵横比图片 只保证图片的短边显示出来 也就是说 会有另一个方向将发生截取
widthFix 缩放模式 宽度不变 高度自动变化 保持原图宽高比不变
heightFix 缩放模式 高度不变 高度自动变化 保持原图宽高比不变
4.小程序API
1.小程序API概述
小程序中的API是由宿主环境提供的,通过这些丰富的小程序API,开发者可以方便的调用微信提供的功能,例如:获取用户信息 ,本地储存 ,支付功能等
2.小程序API的3大分类
-
事件监听API
-
其特点:以on开头 ,用来监听某些事件的触发
-
举例: wx.onWindowResize(function callback)监听窗口尺寸变化的事件
-
-
同步API
-
特点1:以Sync结尾的API都是同步API
-
特点2:同步API的执行结果,可以通过函数返回值直接获取,如果执行出现错误会抛出异常
-
举例:wx.setStorageSync('Key' , 'value')向本地存储写入内容
-
-
异步API
-
特点:类似于jQuery中的$.ajax(options)函数,需要通过success ,fall ,complete接收调用的结果
-
举例:wx.request() 发起网络数据请求 ,通过success回调函数接收数据
-
5.协同工作
1.了解权限管理需求
在中大型的公司里面 ,人员的分工非常仔细:同一个小程序项目,一般会有不同岗位 , 不同角色的员工同时参与设计和开发。
此时出于管理需求 ,我们迫切需要对不同岗位的员工的权限进行边界的划分,使她们能够高效的进行协同工作
2.了解项目成员的组织结构
-
项目管理者(统筹整个项目的进展和风险把控小程序对外发布的节奏)
-
产品组(提需求)
-
设计组(出设计方案)
-
开发组(代码开发)
-
测试组(项目测试)
-
3.小程序的开发流程
-
1.产品组(提出需求)
-
2.设计组(设计)
-
3.开发组(开发)
-
4.产品组 设计组(体验)
-
5.测试组(测试)
-
6.管理者(发布)
4.小程序成员管理
1.成员管理的两个方面
-
管理者 添加删除(体验成员)
-
项目成员
-
运营者 添加删除(体验成员)
-
开发者 添加删除(体验成员)
-
数据分析 添加删除(体验成员)
-
-
小程序成员管理体现在管理员对小程序项目成员及体验成员的管理:
-
1.项目成员
-
表示参与小程序开发 ,运营的成员
-
可登录小程序管理后台
-
管理员可以添加 ,删除项目成员 ,并且设置项目成员的角色
-
-
2.体验成员
-
表示参与小程序内测体验的成员
-
可使用体验版小程序 ,但不属于项目成员
-
管理员及项目成员均可以添加删除体验成员
-
2.不同项目成员对应的权限
1.开发者权限:开发者
2.体验中权限:运营者 ,开发者 ,数据分析者
3.登录: 运营者 ,开发者 ,数据分析者
4.数据分析:数据分析者
5.微信支付:运营者
6.推广:运营者
7.开发管理:运营者
8.开发设置:开发者
9.暂停服务:运营者
10.解除关联公众号:运营者
11.腾讯云管理:开发者
12.小程序插件:运营者
13.游戏运营管理:运营者
3.开发者的权限说明
-
1.开发者权限:可使用小程序开发者工具及对小程序的功能进行代码开发
-
2.体验者权限:可使用体验版小程序
-
3.登陆权限:可登录小程序管理后台,无需管理员确定
-
4.开发设置:设置小程序服务器域名,消息推送及扫描普通二维码打开小程序
-
5.腾讯云管理:云开发相关设置
6.发布上线
1.小程序发布上线的具体步骤
一个小程序的发布上线,一般要经过 代码上传------》
提交审核------》发布 三个步骤
-
1.上传代码
-
点击开发者工具顶部栏中的 “上传” 按钮
-
填写版本号以及项目备注
-
-
2.提交审核
-
为什么需要提交审核:为了保证小程序的质量 ,以及符合相关的规范 ,小程序的发布是需要腾讯官方审核的
-
提交审核的方式:在开发版本中的列表中 ,点击“提交审核” 按钮之后,按照页面提示填写相关的信息 ,就能把小程序提交到腾讯官方进行审核
-
-
3.发布
-
审核通过之后 ,管理员的微信中会收到小程序通过审核的通知 ,此时在审核版本的列表中 ,点击“发布”按钮之后 ,即可把 “审核通过”的版本发布为“线上版本” ,供所有小程序用户的访问使用。
-
2.在后台查看之前上传的版本
登录小程序管理后台----》管理---》版本管理---》开发版本 ,即可查看提交上传的版本
3.运营数据
1.查看小程序运营数据的两种方式
-
在 “小程序后台” 查看
-
1.登录小程序管理后台
-
2.点击侧边栏的“统计”
-
3.点击相应的tab可以看到相关的数据
-
-
使用“小程序数据助手” 查看
-
1.打开微信
-
2.搜索“小程序数据助手”
-
3.查看已发布的小程序相关的数据
-
7.前期的小总结
-
1.知道怎么创建小程序项目、
-
微信开发者工具的使用 ,appID的获取
-
-
2.清楚小程序的基本组成结构
-
app.js , app.json , app.wxss , pages文件夹
-
-
3.知道小程序页面由几部分组成
-
WXML , WXSS , JSON , JS
-
-
4.知道小程序中常见的组件如何使用
-
view , text , image
-
-
5.知道小程序如何进行协同开发和发布
-
成员管理 , 发布小程序 , 查看运营数据
-
开始学习目标
-
使用WXML模板语法渲染页面结构
-
使用WXSS样式美化页面结构
-
使用app.json对小程序进行全局性配置
-
使用page.json对小程序页面进行个性化配置
-
知道如何发起网络数据请求
8.WXML模板语法
数据绑定
1.数据绑定的基本原则
-
1.在data中定义数据
-
2.在wxml中使用数据
2.在data中定义页面数据
在页面对应的.js文件中 ,把数据定义到data对象中即可
3.Mustache 语法的格式
把data中的数据绑定到页面中渲染 ,使用Mustache语法(双大括号)将变量包起来即可。
shujubangding.js
// pages/shujubangding/shujubangding.js Page({ /** * 页面的初始数据 */ data: { ggg: 'hello world' }, /** * 生命周期函数--监听页面加载 */ onLoad: function (options) { }, /** * 生命周期函数--监听页面初次渲染完成 */ onReady: function () { }, /** * 生命周期函数--监听页面显示 */ onShow: function () { }, /** * 生命周期函数--监听页面隐藏 */ onHide: function () { }, /** * 生命周期函数--监听页面卸载 */ onUnload: function () { }, /** * 页面相关事件处理函数--监听用户下拉动作 */ onPullDownRefresh: function () { }, /** * 页面上拉触底事件的处理函数 */ onReachBottom: function () { }, /** * 用户点击右上角分享 */ onShareAppMessage: function () { } })
shujubangding.wxml
<!--pages/shujubangding/shujubangding.wxml--> <view>{{ggg}}</view>
4.Mustache语法的应用场景
-
绑定内容
-
绑定属性
-
运算(三元运算 ,算数运算)
5.动态绑定内容
页面的数据如下:
页面的结构如下:
6.动态绑定
页面数据如下:
页面结构如下:
7.三元运算
页面数据如下:
页面的结构如下:
8.算数运算
页面数据如下:数据放data里
页面结构如下:
模拟器结果:
事件绑定
1.什么是事件
事件是渲染到逻辑层的通讯方式。通过事件可以将用户在渲染层产生的行为,反馈到逻辑层进行业务的处理。
2.小程序中常用的事件、
-
类型: tap
-
绑定方式:bindtap 或 bind:tap
-
事件描述:手指触摸以后马上离开 ,类似HTML 的click
-
-
-
类型:input
-
绑定方式:bindinput 或 bind:input
-
事件描述:文本框的输入事件
-
-
-
类型:change
-
绑定事件:bindchange 或 bind:change
-
事件描述: 状态改变时触发
-
-
3.事件对象的属性列表
当事件回调触发的时候,会收到一个事件对象event ,它的详细属性如下表:
属性 | 类型 | 说明 |
---|---|---|
type | String | 事件类型 |
timeSta | Integer | 页面打开到触发事件所经过的毫秒数 |
target | Object | 触发事件的组件的一些属性集合 |
currentTarget | Object | 当前组件的一些属性值集合 |
detail | Object | 额外信息 |
touches | Array | 触摸事件,当前停留在屏幕中的触摸点信息的数组 |
changedTouches | Array | 触摸事件,当前变化的触摸点信息的数组 |
4.target和current Target的区别
target是触发该事件的源头组件 ,而currentTarget则是当前事件绑定的组件。举例如下:
代码如下:
点击内部的按钮时 ,点击事件以冒泡的方式向外扩散 ,也会触发外层view的tap事件处理函数 。此时 ,对于外层的view来说:
e.target指向的是触发事件的源头组件 , 因此 ,e.target是内部的按钮组件
e.currentTarget指向的是当前正在触发事件的那个组件 ,因此 ,e.currentTarget是当前view组件
5.bindtap 的语法格式.
在小程序中 , 不存在HTML中的onclick鼠标点击事件 ,而是通过tap事件来响应用户的触摸行为。
-
通过bindtap ,可以为组件绑定tap触摸事件 ,语法如下:
-
在页面的 .js文件中定义对应的事件处理函数 ,事件参数通过形参event(一般缩写成 e)来接收
6.在事件处理函数中为data中的数据赋值
通过调用this.setData(dataObject)方法 ,可以给页面data中的数据重新赋值 ,示例如下:
count变6原因如下:
.wxml
.js
7.事件传参
小程序中的事件传参比较特殊 ,不能在绑定事件的同时为事件处理函数传递参数 。例如,下面代码将不能正常工作:
因为小程序会把bindtap的属性值,统一当作事件名称来处理,相当于要调用Count Change(123)的事件处理函数
正确传参:
可以为组件提供data-*自定义属性传参,其中 *代表的是参数的名字 ,示例代码如下:
最终:
-
info会被解析为参数的名字
-
数值2会被解析为参数值
在事件处理函数中 ,通过event.target.dataset.参数名 即可获得具体参数的值 ,示例代码如下:
.wxml
<button type="primary" bindtap="bindtap2" data-info="{{2}}">+2</button>
.js data外写
bindtap2(e){ this.setData({ count:this.data.count + e.target.dataset.info }) },
8.bindinput的语法格式
在小程序中 ,通过input事件来响应文本框的输入事件 ,语法格式如下:
-
通过bind input ,可以为文本框绑定输入事件:
.wxml
<input bindinput="kkk"></input>
.js
//input 输入框的事件处理函数 kkk(e) { //e.detail.value 是变化过后文本框最新的值 console.log(e.detail.value) },
效果如下:
9.如何实现文本框和data之间的数据同步
实现步骤:
-
1.定义数据
.js
data: { // ggg: 'hello world', // imgSrc:'../../images/公牛.webp' // randomNum: Math.random() * 10 //随机生成10以内的随机数 // s: Math.random().toFixed(2) //生成一个带两位小数的随机数 例如:0.23 // count:0 msg: '你好啊!' },
-
2.渲染结构
.wxml
<input bindinput="kkk" value="{{msg}}"></input>
-
3.美化样式
.wxss
/*所有输入框美化 margin: 横向大小 padding: 高低大小 border-radius: 直角变圆 */ input{ border: 3px solid red; margin: 60px; padding: 7px; border-radius: 50px; }
-
4.绑定input事件处理函数
.js
//input 输入框的事件处理函数 kkk(e) { //e.detail.value 是变化过后文本框最新的值 // console.log(e.detail.value) this.setData({ msg:e.detail.value }) },
效果如图:
条件渲染
1.wx.if
在小程序中,使用wx:if="{{condition}}" 来判断是否需要渲染该代码块 其中也含有wx:elif和wx:else来判断代码如下:
<view wx:if="{{type ==1}}">男生</view> <view wx:elif="{{type ==2}}">女生</view> <view wx:else="">保密</view>
data: { // ggg: 'hello world', // imgSrc:'../../images/公牛.webp' // randomNum: Math.random() * 10 //随机生成10以内的随机数 // s: Math.random().toFixed(2) //生成一个带两位小数的随机数 例如:0.23 // count:0 msg: '你好啊!', type:1 },
2.hidden
在小程序中 ,直接使用hidden=“{{omg}} 也能控制元素的显示与隐藏:
<view hidden="{{omg}}">条件为 true 隐藏,条件为 false显示</view>
3.wx:if 与 hidden的对比
-
1.运行方式不同
-
wx:if 以动态创建和移除元素的方式 ,控制元素的展示与隐藏
-
hidden 以切换式的方式(display:none/block;),控制元素的显示与隐藏
-
!omg 意思是取反值
当我们赋值的omg改为false时 wx:if就会消失所以说它是动态创建的元素
-
2.使用建议
-
频繁使用时 ,建议用hidden
-
控制条件复杂时,建议使用wx:if 搭配wx:elif ,wx:else 进行展示与隐藏的切换
-
列表渲染
1.wx:for
通过wx:for 可以根据指定的数组,循环渲染重复的组件结构 ,语法示例如下:
.js
data: { arr1:['苹果','华为','小米','三星'] }
wxml
<view wx:for="{{arr1}}"> 索引是:{{index}} ,item项是:{{item}} </view>
默认情况下 ,当前循环项的索引用index表示 ;当前循环项用item表示
2.手动指定索引和当前项的变量名*
其道理是修改index 和item 名 ,重新命名而已!!!
wx:for-index='xxx' wx:for-item='xxx'
3.wx:key 的使用
类似于Vue 列表中的 :Key ,小程序在实现列表渲染时,也建议为渲染出来的列表项指定唯一的key值,从而提高渲染的效率,实例代码如下:
data: { userlist:[ {id:1,name:'小红'}, {id:2,name:'小王'}, {id:3,name:'小罗'}, {id:4,name:'小潘'}, ],}
<view wx:for="{{userlist}}" wx:key="id"> {{item.name}} </view>
9.WXSS样式模板
1.什么是wxss
wxss(weixin Style Sheets)是一套样式语言,用于美化wxml的组件样式,类似于网页开发中的CSS。
2.wxss和css的关系
wxss具有css大部分特性,同时,wxss还对css进行了扩充以及修改,以适应微信小程序的开发。相对css相比,wxss扩展的特性有:
-
rpx尺寸单位
-
@import样式导入
rpx
1.什么是rpx尺寸单位
rpx是微信小程序独有的,用来解决屏适配的尺寸单位。
2.rpx的实现原理
rpx的实现原理非常简单:鉴于不同设备屏幕的大小不同,为了实现屏幕的自动适配,rpx把所有设备的屏幕,在宽度上等分为750份(即:当前屏幕总宽度为750rpx)。
-
在较小的设备上,1rpx所代表的宽度较小
-
在较大的设备上,1rpx所代表的宽度较大
小程序在不同设备上运行的时候,会自动把rpx的样式单位换算成对应的像素单位来渲染,从而实现屏幕适配。
样式导入
@import的语法格式
@import后跟需要导入的外联样式表的相对路径,用;表示句结束。示例如下:
1.全局样式和局部样式
全局样式
定义在app.wxss中的样式为全局样式,作用于每一个页面。
局部样式
在页面的 .wxss 文件中定义的局部样式,只作用于当前页面。
注意:
-
1.当局部样式和全局样式冲突时,根据就近原则,局部样式会覆盖全局样式
-
2.当局部样式的权重大于或等于全局样式的权重时,会覆盖全局的样式
10.全局配置
1.全局配置文件及其常用的配置项
小程序根目录下的app.js文件是小程序的全局配置文件。常用的配置项如下:、
-
1.pages
-
记录当前小程序所有页面的存放路径
-
-
2.window
-
全局设置小程序窗口的外观
-
-
3.tabBar
-
设置小程序底部的tabBar效果
-
-
4.style
-
是否开启新版本的组件样式
-
2.了解window节点常用的配置项
3.设置导航栏的标题
设置步骤:app.json----->window----->navigationBarTitleText
4.设置导航栏的背景色
设置步骤: app.js--->window--->navigtionBarBackgroundColor
注意:颜色它只支持16进制的
5.设置导航栏的标题颜色
设置步骤:app.json--->window--->navigationBarTexStyle
注意:navigationBarTexStyle的可选值只有 black 和 white
6.全局开启下拉刷新功能
概念:下拉刷新是移动端的专有名词,通过手指在屏幕上的下拉滑动操作,从而重新加载页面数据的行为。
设置步骤:app.json--->window--->把enablePullDownRefresh的值设置为true
注意:在app.json中开启下拉刷新功能,会作用于每个小程序页面!
7.设置下拉刷新是窗口的背景色
当开启全局下拉刷新功能之后,默认的窗口背景为白色。如果自定义下拉刷新窗口背景色,设置步骤为:app.json--->window--->把backgroundColor指定16进制的颜色#efefef。效果如下:
8.设置下拉刷新时loading的样式
开启全局下拉刷新以后,默认窗口的loading样式为白色,如果要修改loading样式效果,设置步骤为:
app.json--->window--->为backgroundTextStyle指定dark值。效果为变成动态的三个点 灰色
9.设置上拉触底的距离
概念:上拉触底是移动端的专有名词,通过手指在屏幕上的上拉滑动操作,从而加载更多数据的行为。
设置步骤:app.json--->window--->为onReachBottomDistance 设置新的数值
注意:默认距离为50px,如果没有特殊需求,建议使用默认值即可。
10.tabBar
1.什么是tabBar
tabBar是移动端应用常见的页面效果,用于实现多页面的快速切换。小程序中通常将其分为:
-
底部tabBar
-
顶部tabBar
注意:
-
tabBar中只能配置最少2个,最多5个tab页签
-
当渲染顶部tabBar时,不显示icon,只显示文本
2.tabBar的6个组成
-
1.backgroundColor : tabBar的背景色
-
2.selectediconPath : 选中时候的图片路径
-
3.borderStyle : tabBar 上边框的颜色
-
4.iconPath : 未选中时的图片路径
-
5.selectedColor : tab上的文字选中时的颜色
-
6.color:tab上文子的默认(未选中)颜色
3.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页签的列表,(最少2个,最多5个) |
4.每个tab项的配置选项
属性 | 类型 | 必填 | 描述 |
---|---|---|---|
pagePath | String | 是 | 页面路径,页面必须在pages中预先定义 |
text | String | 是 | tab上显示的文字 |
iconPath | String | 否 | 未选中时的图标路径;当前postion为top时,不显示icon |
selectedIconPath | String | 否 | 选中的图标路径;当pastion为top时,不显示icon |
11.配置tabBar
1.需求描述
制作三个tab
-
首页
-
消息
-
联系我们
2.实现步骤
-
1.拷贝图标资源
-
把选中的images文件,拷贝到小程序根目录中
-
将需要用到的小图标分为3组,每组两个,其中;
-
图片名中包含 -active的是选中之后的图标
-
图片名中不包含 -active的是默认图标
-
-
-
2.新建3个对应的tab页面
-
配置tabBar选项
-
1.打开app.json配置文件 ,和pages ,window平级,新增tabBar节点!
-
2.tabBar节点中,新增list数组,这个数组中存放的,是每个tab项的配置对象
-
3.在list数组中,新增每个tab项的配置对象。对象中包含的属性如下:
-
pagePath 指定当前tab对应的页面路径 (必填)
-
text 指定当前tab对应的页面路径 (必填)
-
iconPath 指定tab未选中时候的图片路径
-
selectediconPath 指定当前tab被选中后高亮图片路径
-
-
效果如下图:
代码如下:
.wxml
<view><h1>欢迎来到首页</h1></view> <view><h1>消息页</h1></view> <view><h1>联系客服</h1></view>
.app.json
"pages":[ "pages/home/home", "pages/message/message", "pages/contact/contact", ] , "tabBar": { "list": [ { "pagePath": "pages/home/home", "text": "首页", "iconPath": "/images/index/index.png", "selectedIconPath": "/images/index/index-active.jpg" }, { "pagePath": "pages/message/message", "text": "消息", "iconPath": "/images/message/message.png", "selectedIconPath": "/images/message/message-active.jpg" }, { "pagePath": "pages/contact/contact", "text": "联系客服", "iconPath": "/images/contact/contact.png", "selectedIconPath": "/images/contact/contact-active.png" } ] },
11.页面的配置
1.页面配置文件的作用
小程序中每个页面都有自己的 .json配置文件 ,用来对当前页面的窗口外观,页面效果等进行配置。
2.页面配置和全局配置的关系
小程序中 ,app.json中的window节点,可以配置全局小程序中每个页面的窗口表现。
如果某些小程序页面想要特殊的窗口表现 ,此时,”页面级别的 .json配置文件“ 就可以实现这样的需求!!
注意:当页面配置和全局配置发生冲突的时候,根据就近原则,最终的效果以页面的配置为准!!!
3.页面配置中常用的配置项
属性 | 类型 | 默认值 | 描述 |
---|---|---|---|
navigationBarBackgroundColor | HexColor | #000000 | 当前页面导航栏背景色,如#000000 |
navigationBarTextStyle | String | white | 当前页面导航栏标题颜色,仅支持black/white |
navigationBarTitleText | String | 当前页面导航栏标题文字内容 | |
backgroundColor | HexColor | #ffffff | 当前窗口的背景色 |
backgroundTextStyle | String | dark | 当前页面下拉loading的样式,仅支持dark/light |
enablePullDownRefresh | Boolean | false | 是否为当前页面开启下拉刷新效果 |
onReachBottomDistance | Number | 20 | 页面上拉触底事件触发时距离页面底部距离 ,单位px |
12.网络数据请求
1.小程序中网络数据请求的限制
处于安全性方面的考虑,小程序官方对数据接口的请求做出了如下两个限制:
-
1.只能请求HTTPS类型的接口
-
2.必须将接口的域名添加到信任列表中
2.配置request合法域名
配置步骤:登录微信小程序管理后台--》开发--》开发设置--》服务器域名--》修改request合法域名。
注意事项:
-
1.域名只支持https协议
-
2.域名不能使用IP地址或localhost
-
3.域名必须经过ICP备案
-
4.服务器域名一个月内就可以改最多5次
下图是配置完成的:
3.发起GET请求
调用小程序提供的wx.request()方法,可以发起GET数据请求,示例如下:
4.发起POST请求
调用小程序提供的wx.request()方法,可以发起POST请求,示例如下:
5.在页面刚加载时请求数据
在很多情况下,我们需要在页面更加载的时候,自动请求一些初始化的数据。此时需要在页面的onLoad事件中调用获取数据的函数,示例代码如下:
6.跳过request合法域校验
如果后端程序员仅仅提供了HTTP协议接口,暂时没有提供https协议的接口。
此时为了不耽误开发的进度,我们可以在微信开发者工具中,临时开启【开发环境不校验请求域名,TLS版本及HTTPS证书;选项跳过request合法域名的校验、
注意:
跳过request合法域名校验的选项,仅限在开发阶段和调试阶段使用!
7.关于跨域和Ajax的说明
跨域问题只存在基于浏览器的Web开发中。由于小程序的宿主环境不是浏览器,而是微信客户端,所以小程序中不存在跨域问题。
Ajax技术的核心是依赖于浏览器中的XMLHttpRequest这个对象,由于小程序的宿主环境是微信客户端,所以微信小程序不能叫做”发起Ajax请求“ ,而是叫做 ”发起网络数据请求“。
案例-本地生活(首页)
1.首页效果以及实现步骤
-
1.新项目并梳理项目结构
-
2.配置导航栏
-
3.配置tabBar效果
-
4.实现轮播图效果
-
5.实现九宫格
-
6.实现图片布局
效果如下:
代码如下:
app.json
{ "pages":[ "pages/home/home", "pages/message/message", "pages/contact/contact" ], "window":{ "backgroundTextStyle":"light", "navigationBarBackgroundColor": "#2b4b6b", "navigationBarTitleText": "本地生活", "navigationBarTextStyle":"white" }, "tabBar": { "list": [ { "pagePath": "pages/home/home", "text": "首页", "iconPath": "/images/index/index.png", "selectedIconPath": "/images/index/index-active.jpg" }, { "pagePath": "pages/message/message", "text": "消息", "iconPath": "/images/message/message.png", "selectedIconPath": "/images/message/message-active.jpg" }, { "pagePath": "pages/contact/contact", "text": "联系客服", "iconPath": "/images/contact/contact.png", "selectedIconPath": "/images/contact/contact-active.png" } ] }, "style": "v2", "sitemapLocation": "sitemap.json" }
home.wxml
<!--pages/home/home.wxml--> <!--轮播图区域--> <swiper indicator-dots circular> <swiper-item wx:for="{{swiperList}}" wx:key="id"> <image src="{{item.image}}"></image> </swiper-item> </swiper> <!--九宫格区--> <view class="grid-list"> <view class="grid-item" wx:for="{{gridList}}" wx:key="id"> <image src="{{item.icon}}"></image> <text>{{item.name}}</text> </view> </view> <!--图片区--> <view class="img-box"> <image src="/images/公牛.webp" mode="aspectFill"></image> <image src="/images/奇才.webp" mode="aspectFill"></image> </view>
home.wxss
/* pages/home/home.wxss */ swiper { height: 350rpx; } swiper image{ width: 100%; height: 100%; } .grid-list { display: flex; flex-wrap: wrap; border-left: 1rpx solid #efefef; border-top: 1rpx solid #efefef; } .grid-item{ width: 33.33%; height: 200rpx; display: flex; flex-direction: column; align-items: center; justify-content: center; border-right: 1rpx solid #efefef; border-bottom: 1rpx solid #efefef; box-sizing: border-box; } .grid-item image{ width: 60rpx; height: 60rpx; } .grid-item text{ font-size: 24rpx; margin-top: 10rpx; } .img-box { display: flex; padding: 20rpx 10rpx; justify-content: space-around; } .img-box image{ width: 45%; }
总结:
-
1.能够使用WXML模板语法渲染页面结构
-
2.能够使用WXSS美化页面结构
-
3.能够使用app.json对小程序进行全局性配置
-
4.能够使用pages.json对小程序页面进行个性化配置
-
5.可以发起网络数据请求
视图与逻辑
目标:
1.能够知道如何实现页面之间的导航栏跳转
2.知道如何实现下拉刷星效果
3.知道如何实现上拉加载更多效果
4.知道小程序中常用的生命周期函数
1.页面导航
1.什么是页面导航
页面导航是页面之间的相互跳转。
2.小程序中实现页面导航的两种方式
-
1.声明式导航
-
在页面上声明一个<navigqator>
-
通过点击<navigator>组件实现页面跳转
-
1. 导航到tabBar页面:
tabBar页面指的是被配置为tabBar的页面
在使用<navigator>组件跳转到指定的tabBar页面时,需要指定url属性和open-type属性,其中:
-
url表示要跳转的页面地址,必须以 / 开头
-
open-type 表示跳转的方式,必须为switchTab
示例代码:
导航到tabBar页面
wxml
<navigator url="/pages/message/message" open-type="switchTab">导航到消息页</navigator>
2.导航到非tabBar页面
在使用<navigator>组件跳转到指定的非tabBar页面时,需要指定url属性和open-type属性,其中:
-
url表示要跳转的页面地址,必须以 / 开头
-
open-type 表示跳转的方式,必须为navigate
示例代码:
<navigator url="/pages/shujubangding/shujubangding" open-type="navigate">跳转到数据绑定页面</navigator>
注意:
跳转到非tabBar页面 open-type属性可以不写
3.后退导航
后退上一页面或多级页面,则需要指定open-type属性和delte属性,其中:
-
open-type的值必须是navigateBack ,表示要进行后退导航
-
delte的值必须是数字,表示要后退的层级
-
如果只跳转到上一页面 delte值可以省略 默认是1
示例代码如下:
<navigator open-type="navigateBack" delta="1">返回上一页</navigator>
-
2.编程式导航
-
调用小程序的导航API,实现页面的跳转
-
4.编程式导航到tabBar页面
调用wx.switchTab(Object object)方法,可以跳转到tabBar页面。其中Object参数对象的属性列表如下:
属性 | 类型 | 是否必填 | 说明 |
---|---|---|---|
url | String | 是 | 跳转的tabBar路径,路径后不可以带参数 |
success | function | 否 | 调用接口成功的回调函数 |
fail | function | 否 | 调用接口失败的回调函数 |
complete | function | 否 | 接口调用结束的回调函数(调成功,失败都会执行) |
示例代码如下:
5.编程式导航到非tabBar页面
示例代码如下:
6.编程式后退导航
示例代码如下:
3.导航传参
1.声明式传参
navigator组件的url属性用来指定将要跳转的页面的路径。同时,路径的后面还可以携带参数
-
参数于路径之间使用 ?分隔
-
参数建与参数值用 = 相连
-
不同参数用&分隔
示例代码如下:
<navigator url="/pages/shujubangding/shujubangding?name=zs&age=18" open-type="navigate">跳转到数据绑定页面</navigator>
注意:
跳转非tabBar页面的路径才可以带参数!!!
2.编程式传参
调用wx.navigateTo(Object object)方法跳转页面时,也可以携带参数,代码示例如下:
将导航传参的数送到data
2.下拉刷新事件
1.什么是下拉刷新
下拉刷新是移动端的专有名词,指的是通过手指在屏幕上的下拉滑动操作,从而重新加载页面数据的行为。
2.启动下拉刷新
启动下拉刷新有两种方式:
-
全局开启下拉刷新
在app.json的window节点中,将enablePullDownRefresh设置为true
-
局部开启下拉刷新
在页面的 .json配置文件中,将enablePullDownRefresh设置为true
3.配置下拉刷新窗口的样式
在全局域页面的.json配置文件中,通过backgroundColor和backgroundTextStyle来配置下拉刷新窗口的样式,其中;
-
backgroundColor用来配置下拉刷新窗口的背景颜色,仅支持16进制的颜色值
-
backgroundTextStyle用来配置下拉刷新loading的样式,仅支持dark和light
4.监听页面的下拉刷新事件
在页面的.js文件中,通过onPullDownRefresh()函数即可监听当前页面的下拉刷新事件。
实现下拉刷新将 count值变成1
代码如下:
message.wxml
<!--pages/message/message.wxml--> <view><h1>消息页</h1></view> <navigator open-type="navigateBack" delta="1">返回上一页</navigator> <view>count值是:{{count}}</view> <button bindtap="addCount">+1</button>
message.js
/** * 页面的初始数据 */ data: { count: 0 }, addCount(){ this.setData({ count:this.data.count+1 }) }, /** * 页面相关事件处理函数--监听用户下拉动作 */ onPullDownRefresh: function () { console.log('触发了message页面的下拉刷新!') this.setData({ count:0 }) //count为0以后自动关闭下拉刷新效果 wx.stopPullDownRefresh() },
5.停止下拉刷新的效果
当前处理完毕刷新后,下拉刷新的loading效果会一直显示,不会主动消失,所以需要手动隐藏loading效果。此时,调用wx.stoPullDownRefresh()可以停止当前页面的下拉刷新效果。示例代码如下:
3.上拉触底事件
1.什么是上拉触底
上拉触底是移动端的专有名词,通过手指在屏幕上的上拉滑动操作,从而加载更多数据的行为。
2.监听页面的上拉触底事件
在页面的.js文件中,通过onReachBdottom()函数即可监听当前页面的上拉触底事件。示例代码如下:
注意:需要高度大于屏幕的高度才可以上拉
3.配置上拉触底距离
上拉触底距离指的是触发上拉触底事件时,滚动距离页面底部的距离。
可以在全局配置或也买你的.json配置文件中,通过onReachBottomDistance属性来配置上拉触底的距离。
1.上拉触底案例
案例的实现步骤
-
定义获取随机颜色的方法
-
定义获取随机颜色的方法
-
// pages/contact/contact.js Page({ /** * 页面的初始数据 */ data: { colorList:[]//随机颜色的列表 }, getColors(){//获取随机颜色的方法 wx.request({//发起请求,获取随机颜色的数组 url: 'https://www.escook.cn/api/color', method:'GET', success:({data:res})=> ( this.setData({ //旧新数据的拼接 colorList:[...this.data.colorList, ...res.data] }) ) }) }, /** * 生命周期函数--监听页面加载 */ onLoad: function (options) { this.getColors() }, /** * 生命周期函数--监听页面初次渲染完成 */ onReady: function () { }, /** * 生命周期函数--监听页面显示 */ onShow: function () { }, /** * 生命周期函数--监听页面隐藏 */ onHide: function () { }, /** * 生命周期函数--监听页面卸载 */ onUnload: function () { }, /** * 页面相关事件处理函数--监听用户下拉动作 */ onPullDownRefresh: function () { }, /** * 页面上拉触底事件的处理函数 */ onReachBottom: function () { }, /** * 用户点击右上角分享 */ onShareAppMessage: function () { } })
-
-
在页面加载的时候获取初始数据
-
/** * 生命周期函数--监听页面加载 */ onLoad: function (options) { this.getColors() },
-
-
渲染UI结构并且美化页面效果
-
contact.wxml
<view wx:for="{{colorList}}" wx:key="index" class="nmu-item" style="background-color: rgba({{item}});">{{item}}</view>
contact.wxss
/* pages/contact/contact.wxss */ .nmu-item { border: 1rpx solid #efefef; border-radius: 8rpx; line-height: 200rpx; margin: 15rpx; text-align: center; text-shadow: 0rpx 0rpx 5rpx #fff; box-shadow: 1rpx 1rpx 6rpx #aaa; }
-
-
在上拉触底时调用获取随机颜色的方法
-
js
/** * 页面上拉触底事件的处理函数 */ onReachBottom: function () { //调用随机颜色的方法函数 this.getColors() },
-
-
添加loading提示效果
-
getColors(){//获取随机颜色的方法 //展示loading效果 wx.showLoading({ title: '数据加载中', }) wx.request({//发起请求,获取随机颜色的数组 url: 'https://www.escook.cn/api/color', method:'GET', success:({data:res})=> ( this.setData({ //旧新数据的拼接 colorList:[...this.data.colorList, ...res.data] }) ), //隐藏loading效果 complete: ()=>{ wx.hideLoading() } }) },
-
-
对上拉触底进行节流处理
-
当我们在加载数据的时候 不可以下滑再加载数据 所以进行节流 除非我们没有加载数据就直接下滑很多加载底下数据
-
在data中定义isloading节流阀
-
false表示当前没有进行任何数据的请求
-
true表示当前进行数据请求
-
-
在getColors()方法中修改isloading节流阀的值
-
在刚调用getColors时将节流阀设置为true
-
在网络请求的complete回调函数中,将节流阀重置为false
-
-
在哦那ReachBottom中判断节流阀的值,从而对数据请求进行节流控制
-
如果节流阀的值为false,则发起数据请求
-
如果节流阀的值为true,则阻止当前请求.
-
-
代码如下:
/** * 页面的初始数据 */ data: { colorList:[],//随机颜色的列表 isloding:false//可以进行数据请求 }, getColors(){//获取随机颜色的方法 //正在发起数据网络请求 isloding:true //展示loading效果 wx.showLoading({ title: '数据加载中...', }) wx.request({//发起请求,获取随机颜色的数组 url: 'https://www.escook.cn/api/color', method:'GET', success:({data:res})=> ( this.setData({ //旧新数据的拼接 colorList:[...this.data.colorList, ...res.data] }) ), //隐藏loading效果 complete: ()=>{ wx.hideLoading() //数据上一次的数据加载完成了 this.setData({ isloding:false }) } }) }, /** * 页面上拉触底事件的处理函数 */ onReachBottom: function () { //判断isloding值 if(this.data.isloding) return //调用随机颜色的方法函数 this.getColors() },
拓展
自定义编译模式
如果我们在修改其他页面而不是首页 修改完成后我们还是跳到首页需要点击才可以去到我们刚刚修改的页面 相当麻烦 所以我们可以去设置 自定义编译模式直接跳到我们修改的页面
生命周期
1.什么是生命周期
生命周期(Life Cycle)是指一个对象从创建-->运行-->销毁 的整个阶段 ,强调的是一个时间段。例如;
-
张三出生,表示这个人生命周期的开始
-
张三的离世 ,表示这个人的生命周期的结束
-
其中张三的一生,就是张三的生命周期
我们可以把每个小程序运行的过程,也概括为生命周期:
-
小程序的启动,生命周期的开始
-
小程序的关闭,生命周期的结束
-
中间小程序的运行过程,就是小程序的生命周期
2.生命周期的分类
小程序中,生命周期分为两大类:
-
应用生命周期
-
特指小程序启动--->运行--->销毁 的过程
-
-
页面的生命周期
-
特指小程序中,每个页面的加载--->渲染--->销毁的过程
-
其中,页面的生命周期范围较小,应用程序的生命周期范围比较大!!
3.什么是生命周期函数
生命周期函数:是由小程序框架提供的内置函数,会伴随着生命周期,自动按次序执行。
生命周期函数的作用:允许程序员在特定的时间点,执行某些特定的操作。例如,页面加载的时候,可以在onLoad生命周期函数中初始化页面的数据。
注意:生命周期强调的是一个时间段,生命周期函数强调的是时间点。
4.生命周期函数的分类
小程序中的生命周期函数有两类:
-
应用的生命周期函数
-
特定小程序从启动-->允许-->销毁期间依次调用的那先函数
-
-
页面的生命周期函数
-
特定小程序中,每个页面加载--->渲染--->销毁期间依次调用的那些函数
-
5.应用的生命周期函数
小程序的应用生命周期函数需要在app.js中进行声明,示例代码如下;
App({ /** * 当小程序初始化完成时,会触发 onLaunch(全局只触发一次) */ onLaunch: function () { }, /** * 当小程序启动,或从后台进入前台显示,会触发 onShow */ onShow: function (options) { }, /** * 当小程序从前台进入后台,会触发 onHide */ onHide: function () { }, /** * 当小程序发生脚本错误,或者 api 调用失败时,会触发 onError 并带上错误信息 */ onError: function (msg) { } })
6.页面的生命周期函数
小程序的页面生命周期函数需要在页面的.js文件中进行声明,示例代码如下
Page({ /** * 页面的初始数据 */ data: { }, /** * 生命周期函数--监听页面加载 */ onLoad: function (options) { }, /** * 生命周期函数--监听页面初次渲染完成 */ onReady: function () { }, /** * 生命周期函数--监听页面显示 */ onShow: function () { }, /** * 生命周期函数--监听页面隐藏 */ onHide: function () { }, /** * 生命周期函数--监听页面卸载 */ onUnload: function () { }, /** * 页面相关事件处理函数--监听用户下拉动作 */ onPullDownRefresh: function () { },
WXS脚本
1.什么是WXS
WXS(WeiXin Script)是小程序独有的一套语言脚本语言,结合WXML,可以构建出页面的结构。
2.WXS的应用场景
wxml中无法调用页面的.js中定义的函数,但是,wxml中可以调用wxs中定义的函数。因此,小程序中wxs的典型应用场景就是“过滤器”。
3.wxs和JavaScript的关系
虽然wxs的语法类似于JavaScript,但是JavaScript和wxs是完全不一样的两种语言;
-
1.wxs有自己的数据类型
-
number 数组类型
-
String 字符串类型
-
Boolean 布尔类型
-
object 对象类型
-
function 函数类型
-
array 数组类型
-
date 日期类型
-
regexp 正则
-
-
2.wxs不支持类似于ES6及以上的语法形式
-
不支持:let const 解构赋值 展开运算符 箭头函数 对象属性简写 etc
-
支持:var定义变量 普通function函数等类似于ES5的语法
-
-
3.wxs遵循CommonJS规范
-
module 对象
-
require()函数
-
module.exports 对象
-
4.基础语法
1.内嵌wxs脚本
wxs代码可以编写在wxml文件中的<wxs>标签内,就像Javascript代码可以编写在HTML文件中的<script>标签内一样。
wxml文件中的每一个<wxs></wxs>标签,必须提供module属性,用来指定当前wxs的模块名称,方便在wxml中访问模块中的成员。
data: { count: 0, username:'zangshan' },
<view>{{m1.toUpper(username)}}</view> <wxs module="m1"> //将文本转换为大写 module.exports.toUpper=function(str){ return str.toUpperCase() } </wxs>
2.定义外联的wxs脚本
wxs代码可以编写在以 .wxs为后缀的文件内,就像JavaScript代码可以写在 .js后缀的文件中
示例代码:
在utils目录下创建 tools.wxs文件
//定义一个函数 tools.wxs function toLower(str){ //将字符串大写变成小写 return str.toLowerCase() } module.exports={ toLower:toLower }
3.使用外联wxs脚本
在wxml中引入外联的wxs脚本时,必须为<wxs>标签添加modlue和src属性,其中:
-
module用来指定模块的名称
-
src用来指定引入的脚本路径,且必须是相对路径
示例代码:
/** * 页面的初始数据 */ data: { count: 0, username:'zangshan', country:'CHINA' }, tools.wxs文件 //定义一个函数 function toLower(str){ //将字符串大写变成小写 return str.toLowerCase() } module.exports={ toLower:toLower }
<!--调用m2模块的方法--> <view>{{ m2.toLower(country)}}</view> <wxs src="../../utils/tools.wxs" module="m2"></wxs>
5.wxs的特点
1.与JavaScript不同
wxs语言设计上大量借鉴了JavaScript的语法。但是本质上,wxs和JavaScript是完全不同的两种语言!
2.不能为组件的事件回顾
wxs典型的应用场景就是“ 过滤器”,经常配合Mustache语法使用,例如:
<view>{{m2.toLowe(country)}}</view>
但是,在wxs中定义的函数不能作为组件的事件回调函数。例如,下面的用法错误:
<button bindtap="m2.toLower"> 按钮 </button>
3.隔离性
指wxs的运行环境和其他JavaScript代码是隔离的,体现如下:
-
wxs不能调用 js定义的函数
-
wxs不能调用小程序提供的API
4.性能好
-
在iOS设备上,小程序内的wxs会比JavaScript代码快2~20倍
-
在Android设备上,二者的运行效率无差异
案例(本地生活)
九宫格列表页面
1.列表页面的API接口
以分页的形式,加载指定分类下商铺页表的数据:
-
接口地址
-
URL地址中的:cate_id是动态参数,表示分类的id
-
请求方式
-
GET
-
-
请求参数
-
_page第几页的数据
-
_limit每页请求几条数据
-
功能:
-
页面导航传参(针对九宫格)
<!--九宫格区--> <view class="grid-list"> <navigator class="grid-item" wx:for="{{gridList}}" wx:key="id" url="/pages/shoplist/shoplist?id={{item.id}}&title={{item.name}}"> <image src="{{item.icon}}"></image> <text>{{item.name}}</text> </navigator> </view>
动态设置标题为 name的值:
/** * 页面的初始数据 */ data: { //存放动态标题 query:[] }, /** * 生命周期函数--监听页面加载 * 导航传参的值放在此函数中 */ onLoad: function (options) { //给query赋值 this.setData({ query:options }) }, /** * 生命周期函数--监听页面初次渲染完成 */ onReady: function () { wx.setNavigationBarTitle({ title: this.data.query. title, }) },
获取商铺列表的数据:
/** * 页面的初始数据 */ data: { //存放动态标题 query:[], //存放所有商铺信息 shopList:[], //默认情况下进商铺页面就看第一页 page:1, //每页请求多少数据10条 pageSize: 10, //获取所有的数据条数 total:0, }, /** * 生命周期函数--监听页面加载 * 导航传参的值放在此函数中 */ onLoad: function (options) { //给query赋值 this.setData({ query:options }) this.getShopList() }, getShopList(){ wx.request({ url: `https://www.escook.cn/categories/${this.data.query.id}/shops`, method:'GET', //发送到服务器的参数 data:{ _page: this.data.page, _limt: this.data.pageSize }, success:(res) =>{ //数据拼接赋值 this.setData({ shopList:[...this.data.shopList,...res.data], total: res.header['X-Total-Count'] - 0 }) } }) },
渲染商铺列表:
wxml
<!--pages/shoplist/shoplist.wxml--> <view class="shop-item" wx:for="{{shopList}}" wx:key="id"> <view class="thumb"> <image src="{{item.images[0]}}"></image> </view> <view class="info"> <text class="shop-title">{{item.name}}</text> <text>电话:{{item.phone}}</text> <text>地址:{{item.address}}</text> <text>营业时间:{{item.businessHours}}</text> </view> </view>
wxss
/* pages/shoplist/shoplist.wxss */ .shop-item{ display: flex; /* 使图片不帖边框 */ padding: 15rpx; /* 盒子边框 */ border: 1rpx solid #000000; /* 每个盒子的间距 */ margin: 15rpx; /* 盒子圆角 */ border-radius: 8rpx; /* 盒子偏移 */ box-shadow: 1rpx 1rpx 15rpx #ddd; } .thumb image{ width: 250rpx; height: 250rpx; /*图片地下有距离消除*/ display: block; /* 图片和信息有间距 */ margin-right: 30rpx; } .info{ display: flex; /*纵向布局*/ flex-direction: column; /*分散对齐*/ justify-content: space-around; /* 文字变小 */ font-size: 24rpx; } .shop-title{ /* 加粗 */ font-weight: bold; }
-
上拉触底加载下一页数据
Page({ /** * 页面的初始数据 */ data: { //存放动态标题 query:[], //存放所有商铺信息 shopList:[], //默认情况下进商铺页面就看第一页 page:1, //每页请求多少数据10条 pageSize: 10, //获取所有的数据条数 total:0, //可以进行数据请求节流阀 isloding:false, }, /** * 页面上拉触底事件的处理函数 */ onReachBottom: function () { //判断isloding值 if(this.data.isloding) return this.setData({/*使page+1 */ page: this.data.page+1 }) this.getShopList() },
-
下拉刷新列表数据
{ "usingComponents": {}, "onReachBottomDistance": 200, "enablePullDownRefresh": true, "backgroundColor": "#66ccff", "backgroundTextStyle": "dark" }
/** * 页面相关事件处理函数--监听用户下拉动作 */ onPullDownRefresh: function () { //需要重置关键的数据 this.setData({ page:1, shopList:[], total:0 }) //重新发起数据请求 this.getShopList() },
2.判断是否还有下一页数据
下面公式成立,则证明没有下一页数据:
页码值*每页显示多少条数据>=总数据条数
page*pageSize>=total
目标:
1.知道如何自定义小程序组件
2.知道小程序组件中behavions作用
3.知道如何安装和配置vant-weapp组件库
4.知道如何使用Mobx实现数据共享
5.知道对小程序的API进行Promise化
1.组件的创建与引用
1.创建组件
-
1.在项目目录中,鼠标右键,创建components--->test文件夹
-
2.在components--->test文件夹上,鼠标右键,点击新建“Component”
-
键入组件的名称之后回车,会自动生产组件对应的4个文件,后缀名分别为 .js .json .wxml .wxss
注意:为了保证目录的清晰,建议把不同的组件,存放到单独目录中
2.引用组件
-
局部引用:组件只可以被当前页引用
-
全局引用:组件可以在每个小程序页面中引用
3.局部引用
在页面的 .json配置文件中引用组件的方式,叫"局部引用"!实例代码如下;
在 .json { "usingComponents": { "my-test1":"/components/test/test" } } 在 .wxml <!--pages/home/home.wxml--> <my-test1></my-test1>
4.全局引用
在app.json全局配置文件中引用的组件方式,就叫做"全局引用"!实例代码如下;
usingComponents和window同级
app.json "usingComponents": { "test2":"/components/test2/test2" }, .wxml <!--pages/contact/contact.wxml--> <view></view> <test2></test2>
5.组件和页面的区别
-
1.组件的 .json文件需要申明"component" : true 属性
-
2.组件的 .js文件中调用的是Component()函数
-
3.组件的事件的处理函数需要定义到methods节点中
自定义组件-样式
1.组件式隔离
默认情况下,自定义组件的样式只对当前组件生效,不会影响到组件之外的UI结构,
2.组件样式隔离的注意点
-
app.wxss中的全局样式对组件无效
-
只有class选择器会有样式隔离。id选择器,属性选择器,标签选择器不受样式隔离的影响!
建议:在组件和引用组件的页面中建议使用class选择器,不用id , 属性 ,标签选择器!
3.修改组件的样式隔离选项
默认情况下,自定义组件的样式隔离性能够防止组件内外样式互相干扰的问题。但有时,我们希望在外界能够控制组件内部的样式,通过stylelsolation修改组件的样式隔离选项,用法如下;
// components/test/test.js Component({ /** * 组件的属性列表 */ properties: { }, //开启组件隔离功能选项 options:{ styleIsolation:"isolated" },
4.stylelsolation的可选值
可选值 | 默认值 | 描述 |
---|---|---|
isolated | 是 | 启用样式隔离,在自定义组件内外,使用class指定的样式将不会受到互相影响 |
apply-shared(单方面) | 否 | 页面wxss样式将影响到自定义组件,但自定义组件wxss中指定的样式不会影响页面 |
shared(双向影响) | 否 | 表示页面wxss样式将影响到自定义组件,自定义组件wxss中指定的样式也会受到页面和其他设置了apply-shared或shared的自定义组件 |
数据,方法和属性
1.data数据
在小程序组件中,用于组件模板渲染的私有数据,需要定义到data节点中,实例如下;
// components/test/test.js Component({ /** * 组件的初始数据 */ data: { count: 0 }, })
2.methods方法
小程序组件中,事件处理函数和自定义方法需要定义到methods节点中,示例代码如下;
test.js data: { omg: 0 }, /** * 组件的方法列表(包含事件处理函数和自定义方法) */ methods: {//组件的方法列表(包含事件处理函数和自定义方法 addOmg(){//事件处理函数 this.setData({//让omg+1 omg: this.data.omg +1 }) this._showOmg()//通过this直接调用自定义方法 }, _showOmg(){ wx.showToast({ title: 'OMG值为:' +this.data.omg, icon:'none' }) } } test.wxml <view>OMG的值是:{{omg}}</view> <button bindtap="addOmg">+1</button> home.wxml <my-test></my-test> home.json { "usingComponents": { "my-test":"/components/test/test" } }
3.properties属性
小程序组件中,properties是组件的对外属性,用来接收外界传递到组件中的数据,示例代码如下;
控制OMG值不大于6;
// components/test/test.js Component({ /** * 组件的属性列表 */ properties: {//属性定义 max:{//完整定义属性的方式(当需要指定默认值时,建议使用此方式) type: Number,//属性值的数据类型 value: 6 //属性默认值 }, max: Number //简化定义属性的方式(不需要指定属性默认值时,可以使用简化方式 }, options:{ styleIsolation:"shared" }, /** * 组件的初始数据 */ data: { omg: 0 }, /** * 组件的方法列表(包含事件处理函数和自定义方法) */ methods: {//组件的方法列表(包含事件处理函数和自定义方法 addOmg(){//事件处理函数 if(this.data.omg >= this.properties.max) return this.setData({//让omg+1 omg: this.data.omg +1 }) this._showOmg()//通过this直接调用自定义方法 }, _showOmg(){ wx.showToast({ title: 'OMG值为:' +this.data.omg, icon:'none' }) } } }) <!--pages/home/home.wxml--> <my-test max="6"></my-test>
4.data和properties的区别
小程序组件中 ,properties属性和data数据的用法相同,它们都是可读可写的,只不过;
-
data倾向于储存组件的私有数据
-
properties更倾向于储存外界传递到组件中的数据
<!--components/test/test.wxml--> <button bindtap="showInfo">对比data和properties</button> methods: {//组件的方法列表(包含事件处理函数和自定义方法 showInfo(){ console.log(this.data)//输出结果:{omg: 0 , max: 6} console.log(this.properties)//输出结果:{omg: 0 , max: 6} //结果为 true,证明data数据和properties属性(在本质上是一样的,都是可读可写的) console.log(this.data==this.properties) } ,
5.使用setData修改properties的值
由于data数据和properties属性在本质上没有任何区别,因此properties属性的值也就可以用于页面渲染,或许使用setData为properties中的属性重新赋值,示例代码如下;
// components/test/test.js Component({ /** * 组件的属性列表 */ properties: {//属性定义 //定义max方式1 max:{//完整定义属性的方式(当需要指定默认值时,建议使用此方式) type: Number,//属性值的数据类型 }, //定义max方式2 // max: Number //简化定义属性的方式(不需要指定属性默认值时,可以使用简化方式 }, /** * 组件的方法列表(包含事件处理函数和自定义方法) */ methods: {//组件的方法列表(包含事件处理函数和自定义方法 showInfo(){ console.log(this.data)//输出结果:{omg: 0 , max: 6} console.log(this.properties)//输出结果:{omg: 0 , max: 6} //结果为 true,证明data数据和properties属性(在本质上是一样的,都是可读可写的) console.log(this.data==this.properties) } , addOmg(){//事件处理函数 if(this.data.omg >= this.properties.max) return this.setData({//让omg+1 omg: this.data.omg +1, max: this.properties.max +1 }) this._showOmg()//通过this直接调用自定义方法 }, _showOmg(){ wx.showToast({ title: 'OMG值为:' +this.data.omg, icon:'none' }) } } }) <!--components/test/test.wxml--> <text>components/test/test.wxml</text> <view></view> <view>OMG的值是:{{omg}}</view> <view>MAX的值为:{{max}}</view> <button bindtap="addOmg">+1</button> <view></view> <button bindtap="showInfo">对比data和properties</button>
数据监听
1.什么是数据监听
数据监听用于监听和响应任何属性和数据字段的变化,从而执行特定的操作,它的作用类似于vue中的watch侦听器。在小程序组件中,数据监听器的基本语法格式如下;
// components/test/test.js Component({ observers:{ '字段A,字段B':function(字段A的新值,字段B的新值){ //do something } }, /**
2.数据监听器的基本语法
组件的UI结构如下;
<!--components/test/test.wxml--> <view>{{n1}} + {{n2}}={{sum}}</view> <button size="mini" bindtap="addN1">n1自增</button> <button size="mini" bindtap="addN2">n2自增</button>
组件的 .js文件代码如下;
// components/test2/test2.js Component({ /** * 组件的属性列表 */ properties: { }, /** * 组件的初始数据 */ data: { n1: 0, n2: 0, sum: 0, }, /** * 组件的方法列表 */ methods: { //方法addN1 addN1(){ this.setData({ n1: this.data.n1+1 }) }, //方法addN2 addN2(){ this.setData({ n2: this.data.n2+1 }) }, }, observers:{ //数据监听节点 监听n1 n2数据变化 'n1,n2': function(n1 ,n2){ //通过监听器,自动计算sum值 this.setData({sum: n1+n2}) }, } })
3.监听对象属性的变化
数据监听器支持监听对象中单个或多个属性的变化,示例语法如下;
Component({ observers: { '对象.属性A , 对象.属性B': function(属性A的新值 , 属性 B的新值){ //触发此监听器的三种情况 1.【为属性A赋值】使用setData设置 this.data.对象.属性A 时触发 2.【为属性B赋值】使用setData设置 this.data.对象.属性B 时触发 3.【直接为对象赋值】 使用setData设置 this.data.对象 } } })
数据监听器--案例
1.定义对象定义字符串
data: { //rgb对象 rgb: { r: 0, g: 0, b:0 }, //字符串 fullColor: '0,0,0' },
2.渲染UI结构
<!--components/test3/test3.wxml--> <text>components/test3/test3.wxml</text> <view style="background-color: rgb({{fullColor}});" class="colorBxo">颜色值:{{fullColor}}</view> <button size="mini" bindtap="changeR" type="default">R</button> <button size="mini" bindtap="changeG" type="primary">G</button> <button size="mini" bindtap="changeB" type="warn">B</button> /* components/test3/test3.wxss */ .colorBxo{ line-height: 200rpx; font-size: 24rpx; color: white; text-shadow: 0rpx 0rpx 2rpx black; text-align: center; }
3.定义button的事件处理函数
/** * 组件的方法列表 */ methods: { //changeR方法 changeR(){ //修改rgb 对象上r属性的值 this.setData({ //之前的默认值加5如果大于255就一直等于255否则只增加5就可以 'rgb.r': this.data.rgb.r + 5 >255 ? 255 : this.data.rgb.r + 5 }) }, //changeG方法 changeG(){ this.setData({ 'rgb.g': this.data.rgb.g + 5>255?255 : this.data.rgb.g +5 }) }, //changeB方法 changeB(){ this.setData({ 'rgb.b':this.data.rgb.b +5>255?255:this.data.rgb.b+5 }) } }
纯数据字段
1.什么是纯数据字段
概念: 不用于界面渲染的data字段
应用场景:某些data的字段不会展示在界面上,也不会传递给其他组件,仅仅在当前组件内部使用。带这种特性的data字段适合设置为纯数据字段。
好处:纯数据字段有助于页面更新的性能
2.使用规则
在Component构造器options节点中,制定pureDataPattern为一个正则表达式,字段名符合这个规则 表达式的字段将成为纯数据字段,示例代码如下;
3.使用纯数据字段改造数据监听案例
示例代码如下;
注意:将rgb开头的全换为_rgb
// components/test3/test3.js options:{ //指定所有 _开头字段为纯数据字段 pureDataPattern: /^_/ }, /** * 组件的初始数据 */ data: { a: true,//普通数据字段 _b: true,//纯数据字段 //rgb对象 将rgb改造为以 _ 开头的纯数据字段 _rgb: { r: 0, g: 0, b:0 },
组件的生命周期函数
1.组件全部的生命周期函数
小程序组件可用全部生命周期如下列表:
生命周期函数 | 参数 | 描述说明 |
---|---|---|
created | 无 | 在组件实例刚刚被创建时执行 |
attached | 无 | 在组件实例刚刚进入页面节点树时执行 |
ready | 无 | 在组件试图层布置完成后执行 |
moved | 无 | 组件实例被移动到节点树另一个位置时执行 |
detached | 无 | 在组件实例被从页面节点树移动时执行 |
error | Object Error | 每当组件方法抛出错误时执行 |
2.组件主要的生命周期函数
在小程序组件中,最总要的生命周期函数有3个,分别是created,attached,detached。它们各自的特点如下;
-
1.组件实例刚被创建好的时候,created生命周期函数会被触发
-
此时还不i能调用setData
-
通常在这个生命周期函数中,只应该用于组件的this添加一些自定义的属性字段
-
-
2.在组件完成初始化完成,进入页面节点树后,attached生命周期函数会被触发
-
此时,this.data已被初始化完毕
-
这个生命周期很有用,绝大多数初始化的工作可以在这个时机进行(例如发请求获取初始化数据)
-
-
3.在组件离开页面节点树后,detached生命周期函数
-
此时适合做一些清理性质的工作
3.lifetimes节点
小程序组件中,生命周期函数可以直接定义在Component构造器的第一级参数中,可以在lifetimes字段内进行声明(这是推荐的方式,其优先级最高)。实例代码如下;
// components/test3/test3.js Component({ /** * 组件的属性列表 */ properties: { }, lifetimes:{ //推荐方法 attached(){},//在组件实例进入页面节点树时执行 detached(){}//在组件实例被从页面节点树移动时执行 }, //旧方法 attached(){},//在组件实例进入页面节点树时执行 detached(){}//在组件实例被从页面节点树移动时执行
组件所在页面的生命周期
1.什么是组件所在页面的生命周期
有时,自定义组件的行为依赖页面的变化,此时就需要用到组件所在页面的生命周期。
组件所在页面的生命周期函数有如下3个;
生命周期函数 | 参数 | 描述 |
---|---|---|
show | 无 | 组件所在页面展示时执行 |
hide | 无 | 组件所在页面被隐藏时执行 |
resize | Object Size | 组件所在页面尺寸变化时执行 |
2.pageLifetimes节点
组件所在页面的生命周期函数,需要定义在pageLifetimes节点中,实例代码如下:
Component({ /** * 组件的属性列表 */ properties: { }, pageLifetimes:{ show:function(){console.log('show')},//页面被展示 hide:function(){console.log('hide')},//页面被隐藏 resize:function(){console.log('resize')}//页面尺寸大小 },