微信小程序笔记
项目构成
- pages存放小程序的页面
- utils存放工具性质的模块
- app.js小程序项目的入口文件
- app.json小程序的项目的全局配置文件
- app.wxss全局样式文件
- project.config.json项目配置文件
- sitemap.json用来配置小程序及其页面是否允许被微信索引
微信推荐页面都放到pages中
json配置文件
project.config.json
记录对小程序开发工具所做的个性化配置
{
“description”: “项目配置文件,详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html“,
“packOptions”: {
“ignore”: [],
“include”: []
},
“setting”: { //其他的一些配置
“bundle”: false,
“userConfirmedBundleSwitch”: false,
“urlCheck”: true,
“scopeDataCheck”: false,
“coverView”: true,
“es6”: true,
“postcss”: true,
“compileHotReLoad”: false,
“lazyloadPlaceholderEnable”: false,
“preloadBackgroundData”: false,
“minified”: true,
“autoAudits”: false,
“newFeature”: false,
“uglifyFileName”: false,
“uploadWithSourceMap”: true,
“useIsolateContext”: true,
“nodeModules”: false,
“enhance”: true,
“useMultiFrameRuntime”: true,
“useApiHook”: true,
“useApiHostProcess”: true,
“showShadowRootInWxmlPanel”: true,
“packNpmManually”: false,
“enableEngineNative”: false,
“packNpmRelationList”: [],
“minifyWXSS”: true,
“showES6CompileOption”: false,
“minifyWXML”: true,
“useStaticServer”: true,
“checkInvalidKey”: true,
“babelSetting”: {
“ignore”: [],
“disablePlugins”: [],
“outputPath”: “”
},
“disableUseStrict”: false,
“useCompilerPlugins”: false
},
“compileType”: “miniprogram”,
“libVersion”: “2.19.4”,
“appid”: “wx4de46425c2db08cb”, //运行别人的项目需要改成自己的ID
“projectname”: “miniprogram-92”, //与小程序名称名称不同
“condition”: {},
“editorSetting”: {
“tabIndent”: “insertSpaces”,
“tabSize”: 4
}
}
sitemap.json
支持小程序内的搜索、类似于PC网页的SEO
{
“desc”: “关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html“,
“rules”: [{
“action”: “allow”, //改为disallow表示不被微信索引
“page”: “*“
}]
}
页面.json
页面样式配置全局样式
新建页面
{
“pages”:[
“pages/list/list”,
“pages/index/index”,
“pages/logs/logs”
],
“window”:{
“backgroundTextStyle”:”light”,
“navigationBarBackgroundColor”: “#fff”,
“navigationBarTitleText”: “Weixin”,
“navigationBarTextStyle”:”black”
},
“style”: “v2”,
“sitemapLocation”: “sitemap.json”
}
将新建的页面放在第一位,就是当前编译器渲染的首页
WXML和HTML
WXSS和CSS
小程序.JS
app.js
// app.js
App({
onLaunch() {
// 展示本地存储能力
const logs = wx.getStorageSync(‘logs’) || []
logs.unshift(Date.now())
wx.setStorageSync(‘logs’, logs)
// 登录
wx.login({
success: res => {
// 发送 res.code 到后台换取 openId, sessionKey, unionId
}
})
},
globalData: {
userInfo: null
}
})
什么是宿主环境
- 程序运行必须的依赖环境
- 脱离了宿主环境的软件没有任何意义
- 小程序的宿主环境是微信
微信宿主环境
- 通信模型
- 运行机制
- 组件
- API
通信的主体
- 渲染层和逻辑层
- WXML和WXSS工作在渲染层
- JS脚本工作在逻辑层
通信模型
- 渲染层和逻辑层之间的通信
- 逻辑层和第三方服务器之间的通信
- 均由微信客户端转发
运行机制
启动过程
- 下载小程序的代码包到本地
- 解析app.json全局配置文件
- 执行app.js小程序入口文件,调用App()创建小程序实例
- 渲染小程序的首页
- 启动完成
渲染过程
- 加载解析页面的.json配置文件
- 加载页面的.wxml模板和.wxss样式
- 执行页面的.js文件,调用Page()创建页面实例
- 页面渲染完成
组件
容器组件
名称
用途
view
普通视图区域、类似于HTML中的div,是块级元素,用来布局
scroll-view
可滚动的视图区域、用来实现滚动列表的效果
swiper和swiper-item
轮播图容器组件和轮播图item组件,item是内部的轮播小组件
view
<view class = “container”>
<view>A</view>
<view>B</view>
<view>C</view>
</view>
/* pages/list/list.wxss */
.container1 view{
width: 100px;
height: 100px;
text-align: center;
line-height: 100px;
}
.container1 view:nth-child(1){
background-color: green;
}
.container1 view:nth-child(2){
background-color: blue;
}
.container1 view:nth-child(3){
background-color: pink;
}
.container1 {
display: flex;
justify-content: space-around;
}
scroll-view
<scroll-view class = “container1” scroll-y>
<view>A</view>
<view>B</view>
<view>C</view>
</scroll-view>
/* pages/list/list.wxss */
.container1 view{
width: 100px;
height: 100px;
text-align: center;
line-height: 100px;
}
.container1 view:nth-child(1){
background-color: green;
}
.container1 view:nth-child(2){
background-color: blue;
}
.container1 view:nth-child(3){
background-color: pink;
}
.container1 {
border: 1px solid red;
width: 100px;
height: 120px;
}
swiper
<swiper class=“swiper-container” indicator-dots indicator-color=“white” autoplay interval=“3000” circular>
<swiper-item>
<view class=“item”>A</view>
</swiper-item>
<swiper-item>
<view class=“item”>B</view>
</swiper-item>
<swiper-item>
<view class=“item”>C</view>
</swiper-item>
</swiper>
/*轮播图样式*/
.swiper-container {
height:150px
}
.item {
height: 100%;
line-height: 150px;
text-align: center;
}
swiper-item:nth-child(1) .item{
background-color: lightblue;
}
swiper-item:nth-child(2) .item{
background-color: lightgreen;
}
swiper-item:nth-child(3) .item{
background-color: lightyellow;
}
内容组件
text
只有text组件支持长按选中按钮
<view>
手机号支持长按选中效果
<text selectable>13800005056</text>
</view>
rich-text
<rich-text nodes=“
标题
“></rich-text>功能组件
button
- 默认按钮独占一行
<button>push</button>
<button type=“primary”>push-主色调</button>
<button type=“warn”>push-警告</button>
<button size=“mini”>push</button>
<button type=“primary” size=“mini”>push-主色调</button>
<button type=“warn” size=“mini”>push-警告</button>
<button size=“mini” plain>push</button>
<button type=“primary” size=“mini” plain>push-主色调</button>
<button type=“warn” size=“mini” plain>push-警告</button>
image
<image>同样占据一定空间</image>
<image src=“/image/1.png” mode=“aspectFill”></image>
image {
border: 1px solid red;
}
默认情况下,图片会被缩放或剪裁
API分类
协同工作和发布
发布上线,通过后台设置
数据绑定
基本原则,在data中定义数据,在wxml中使用数据
Mustache语法或者叫插值表达式Mustache应用场景
- 绑定内容
- 绑定属性
- 运算
动态绑定内容
// pages/list/list.js
Page({
/\*\*
\* 页面的初始数据
\*/
data: {
info: 'hello world'
},
})
<view> {{info}}</view>
动态绑定属性
// pages/list/list.js
Page({
/\*\*
\* 页面的初始数据
\*/
data: {
imgsrc: 'https://ts1.cn.mm.bing.net/th/id/R-C.2530400ae4fb46c851fb84505fad2319?rik=V%2bxQIfrRsCTlDw&riu=http%3a%2f%2fimg.crcz.com%2fallimg%2f202003%2f05%2f1583415058483289.jpg&ehk=UO4T%2b11wo2Pqv7DUHPfk5pd9gbne4a7uyQ9eUKbNmUY%3d&risl=&pid=ImgRaw&r=0&sres=1&sresct=1'
},
})
<image src=“{{imgsrc}}” mode=“widthFix”></image>
三元运算
Page({
/\*\*
\* 页面的初始数据
\*/
data: {
randomNum: Math.random() \* 10,
randomNum1: Math.random().toFixed(2)
},
})
<view>{{randomNum >= 5 ? ‘数字大于或等于5’:’数字小于5’}}</view>
<view>{{randomNum1*100}}</view>
事件绑定
事件是渲染层到逻辑层的通讯方式,通过事件可以将用户在渲染层产生的行为,反馈到逻辑层进行业务的处理。
常见事件
当事件回调触发的时候,会收到一个事件对象event,他的详细属性如下表所示
target和currentTarget的区别
target是出发该事件的源头组件,而currentTarget则是当前事件所绑定的组件。点击内部的按钮时,点击事件以冒泡的方式向外扩散,也会出发外层的tap事件处理函数,此时,对于外层的view来说
e.target指向的是触发事件的源头组件,也就是view当中的button
e.currentTarget指向的是当前正在触发事件的那个组件,也就是当前的view组件
bindtap的语法格式
page({
//定义按钮的事件处理函数
btnTapHandler(event){
console.log(event)
},
})
<button type=“primary” bindtap=“btnTapHandler”>按钮</button>
数据赋值
page({
/**
* 页面的初始数据
*/
data: {
randomNum: Math.random() * 10,
randomNum1: Math.random().toFixed(2),
Num:0
},
//修改数据的值
CountChange(){
this.setData({
Num:this.data.Num + 1
})
},
})
<button type=“primary” bindtap=“CountChange”> +1</button>
事件传参
在小程序中不能在绑定时间的同时为事件处理函数传递参数
<button type=“primary” bindtap=“btnTapHandler(123)”>事件传参</button>
小程序会认为btnTapHandler(123)是名称
使用data-*自定义属性传参,*表示参数的名字,2这样传的是数字2,单纯写2是字符2
<button type=“primary” bindtap=“btnTapHandler” data-info=“{{2}}”>事件传参</button>
page({
/**
* 页面的初始数据
*/
data: {
randomNum: Math.random() * 10,
randomNum1: Math.random().toFixed(2),
Num:0
},
//定义+2按钮的事件处理函数
btnTap2(event){
this.setData({Num:this.data.Num + event.target.dataset.info })
},
})
<button type=“primary” bindtap=“btnTap2” data-info=“{{2}}”>+2</button>
bindinput的语法格式
通过input事件来响应文本框的输入事件
inputHandler(e){
console.log(e.detail.value)
},
<input bindinput=“inputHandler”></input>
数据同步(文本框和data)
定义数据
page({
/**
* 页面的初始数据
*/
data: {
Num:0
},
})渲染结构
<input value=“{{Num}}” bindinput=“inputHandler”></input>
美化样式
input {
border: 1px solid #221133;
padding:5px;
margin: 5px;
border-radius: 3px;
}绑定input事件处理函数
page({
/**
* 页面的初始数据
*/
data: {
Num:0
},
inputHandler(e){
this.setData({
Num:e.detail.value
})
},
})
条件渲染
wx:if
<view wx:if=“{{type == 1}}”>男</view>
<view wx:elif=“{{type == 2}}”>女</view>
<view wx:else>保密</view>
data: {
type:2
},
结合block使用wx:if
如果要一次性控制多个组件的展示或隐藏,可以使用block标签
<block wx:if=“{{true}}”>
<view>1</view>
<view>2</view>
</block>
hidden
控制组件的显示或隐藏,可以和wx:if有相同的效果但是原理不同
<view hidden=“{{!flag}}”>这是hidden控制的</view>
data: {
flag:true
},
使用建议,当频繁切换的时候使用hidden
列表渲染
wx:for
data: {
arr1:[‘苹果’,’华为’,’小米’]
},
<view wx:for=“{{arr1}}”>
索引是:{{index}},item项是:{{item}}
</view>
手动指定索引和当前项的变量名*
<view wx:for=“{{arr1}}” wx:for-index=“idx” wx:for-item=“itemName”>
索引是:{{idx}},item项是:{{itemName}}
</view>
wx:key
类似于Vue列表渲染中的:key,小程序也建议在列表渲染时为渲染出来的列表项指定唯一的key值,从而提高渲染效率,没有id可用index作为key值
data: {
arr1:[‘苹果’,’华为’,’小米’],
arr2:[
{id:1,name:’小红’},
{id:2,name:’小黄’},
{id:3,name:’小白’}
]
},
<view wx:for=“{{arr2}}” wx:key=“id”>
{{item.name}}
</view>
WXSS
WXSS具有大部分CSS特性
rpx
根据不同的设备,将设备的屏幕宽度等分为750份
- 在较小的设备上1rpx代表的宽度较小
- 在较大的设备上1rpx代表的宽度较大
rpx与px的单位换算
样式导入
路径/common/common.wxss
.username {
color: blue;
}
在index.wxcss中
@import “/common/common.wxss”;
input {
border: 1px solid #221133;
padding:5px;
margin: 5px;
border-radius: 3px;
}
在index.wxml中
<view wx:for=“{{arr2}}” wx:key=“id” class=“username”>
{{item.name}}
</view>
全局样式
在app.wxss中配置全局的样式
局部样式
在页面文件中.wxss中配置页面局部样式
- 当局部样式和全局样式冲突时,根据就近原则,使用当前页面样式
- 当局部的样式权重大于等于全局样式的权重,局部的才会覆盖
全局配置
window
期中导航栏和背景区域可以通过window节点配置
{
“pages”:[
“pages/list/list”,
“pages/index/index”,
“pages/logs/logs”
],
“window”:{
“backgroundTextStyle”:”light”,
“navigationBarBackgroundColor”: “#fff”,
“navigationBarTitleText”: “qxd”, //
“navigationBarTextStyle”:”black”
},
“style”: “v2”,
“sitemapLocation”: “sitemap.json”
}
tabBar
“tabBar”: {
“list”: [
{
“pagePath”: “pages/index/index”,
“text”: “首页”
},
{
“pagePath”: “pages/list/list”,
“text”: “内容”
}
]
},
在每个tab中可以包含如下的配置项
- 图片放到image文件夹中,从根目录加入路径
- 在全局app.json中添加代码
“tabBar”: {
“list”: [
{
“pagePath”: “pages/index/index”,
“text”: “首页”,
“iconPath”: “/image/1.png”,
“selectedIconPath”: “/image/1_active.png”
},
{
“pagePath”: “pages/list/list”,
“text”: “内容”,
“iconPath”: “/image/2.png”,
“selectedIconPath”: “/image/2_active.png”
},
{
“pagePath”: “pages/logs/logs”,
“text”: “个人信息”,
“iconPath”: “/image/3.png”,
“selectedIconPath”: “/image/3_active.png”
}
]
},
页面配置
在页面的json文件中配置
“enablePullDownRefresh”: true //下拉刷新不推荐在全局中使用
网路数据请求
get请求
调用wx.request()方法
<button bindtap=“getInfo”>发送请求</button>
//发起get数据请求
getInfo() {
wx.request({
url: ‘https://www.escook.cn/api/get‘,
method:’GET’,
data: {
name: ‘zs’,
age: 20
},
success:(res) =>{
console.log(res)
}
})
},
url: ‘https://www.escook.cn/api/get’,必须先配置到小程序的后台
Post请求
同样调用wx.request()方法
<button bindtap=“postInfo”>发送get请求</button>
//发起post数据请求
postInfo() {
wx.request({
url: ‘https://www.escook.cn/api/get‘,
method:’POST’,
data: {
name: ‘ls’,
age: 33
},
success:(res) =>{
console.log(res.data)
}
})
},
在页面刚加载时就请求数据
在页面刚刚加载的时候,自动请求一些初始化数据,希望进入首页就自动执行post和get请求,使用onload
/**
* 生命周期函数–监听页面加载
*/
onLoad(options) {
this.getInfo(),
this.postInfo()
},
跳过合法域名校验
跨域和Ajax
跨域问题只存在于基于浏览器的web开发中,由于小程序的宿主环境不是浏览器,而是微信客户端,所以小程序中不存在跨域的问题。
Ajax技术的和兴时依赖于浏览器中的XMLHttpRequest这个对象,由于小程序宿主环境是尾行客户端,所以小程序中不能叫做“发起Ajax请求”,而是叫做“发起网络数据请求”
案例-本地生活
链接:https://pan.baidu.com/s/1WJ_Bh6b8HBaF7tpCpg0APg?pwd=18if
提取码:18if
页面导航
导航到tabBar-声明式导航
<navigator url=“/pages/index/index” open-type=“switchTab”>导航到消息页面</navigator>
<navigator url=“/pages/index/index” open-type=“navigate”>导航到消息页面</navigator>
导航到tabBar页面-编程式导航
<button bindtap=“gotoMessage”>跳转到消息页面</button>
//通过编程式导航跳转到消息页面
gotoMessage() {
wx.switchTab({
url: ‘/pages/message/message’,
})
},
导航到非tabBar页面-编程式
<button bindtap=“gotoRead”>跳转到非tabBar页面</button>
//通过编程式导航跳转到消息页面
gotoRead() {
wx.navigateTo({
url: ‘/pages/read/read’,
})
},
后退导肮-编程式
<button bindtap=“gotoRead”>通过编程式导航后退</button>
//通过编程式导航后退
gotoBack() {
wx.navigateBack(){
delta: 1 //后退层级数
}
},
导航传参-声明式
<navigator url=“/pages/info/info?name=wx&age=20” open-type=“navigate”>跳转到info并传参</navigator>
导航传参-编程式
<button bindtap=“gotoInfo”>跳转到info并传参</button>
//通过编程式导航到info页面并传递参数
gotoInfo() {
wx.navigateTo({
url: ‘/pages/info/info?name=wx&age=20’,
})
},
onLoad获取参数
/**
* 生命周期函数–监听页面加载
*/
onLoad(options) {
console.log(options)
},
其他页面可以获取到值
/\*\*
\* 页面的初始数据
\*/
data: {
//导航传递的参数
query:{}
},
/**
* 生命周期函数–监听页面加载
*/
onLoad(options) {
console.log(options)
this.setDate({
query:options
})
},
页面事件
下拉刷新
- 全局开启下拉刷新
- 局部开启下拉刷新
{
“usingComponents”: {},
“enablePullDownRefresh”: true
}
配置下拉刷新窗口颜色
{
“usingComponents”: {},
“enablePullDownRefresh”: true,
“backgroundColor”: “#efefef”,
“backgroundTextStyle”: “dark”
}
监听下拉刷新窗口函数
/**
* 页面相关事件处理函数–监听用户下拉动作
*/
onPullDownRefresh() {
console.log(‘触发了message页面的下拉刷新’)
},
下拉刷新关闭
/**
* 页面相关事件处理函数–监听用户下拉动作
*/
onPullDownRefresh() {
this.setData({
Num: 0
})
wx.stopPullDownRefresh({
success: (res) => {},
})
},
上拉触底
- 上拉触底距离是可以自定义的,在页面或全局的json文件中,配置onReachBottomDistance来改变,默认50
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
//触底事件在触发是,应考虑用户多次触发的可能做节流处理
console.log(“触发了触底事件”)
},
案例-上拉触底
定义获取随机颜色的方法
/**
* 页面的初始数据
*/
data: {
colorList:[]
},
//得到随机颜色
getColors(){
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]
})
}
})
},页面加载时获取初始数据
/* *
*生命周期函数–监听页面加载
*/
onLoad(options) {
this.getColors()
},渲染UI,美化页面效果
<view wx:for=“{{colorList}}” wx:key=“index” class=“num-item” style=“background-color: rgb({{item}}) ;”>{{item}}</view>
.num-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;
}上拉触底获取颜色
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
this.getColors()
},添加loading提示效果
//得到随机颜色
getColors(){
//查官方API文档
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]
})
}
})
},对上拉触底进行节流处理
/**
* 页面的初始数据
*/
data: {
colorList:[],
//节流值
isloading: false
},
//得到随机颜色
getColors(){
//节流操作
this.setData({
isloading:true
})
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]
})
},
complete:()=>{
wx.hideLoading()
this.setData({
isloading:false
})
}
})
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
if(this.data.isloading){
return
}
this.getColors()
},
生命周期
应用生命周期
页面生命周期
生命周期函数,自动按次序执行
- 页面生命周期函数
- 应用生命周期函数
应用生命周期函数
App({
/**
* 当小程序初始化完成时,会触发 onLaunch(全局只触发一次)
*/
onLaunch: function () {
//完成初始化的功能
},
/**
* 当小程序启动,或从后台进入前台显示,会触发 onShow
*/
onShow: function (options) {
},
/**
* 当小程序从前台进入后台,会触发 onHide
*/
onHide: function () {
},
/**
* 当小程序发生脚本错误,或者 api 调用失败时,会触发 onError 并带上错误信息
*/
onError: function (msg) {
}
})
页面生命周期函数
// pages/info/info.js
Page({
/**
* 页面的初始数据
*/
data: {},
/**
* 生命周期函数–监听页面加载
*/
onLoad(options) {},
/**
* 生命周期函数–监听页面初次渲染完成
*/
onReady() {},
/**
* 生命周期函数–监听页面显示
*/
onShow() {},
/**
* 生命周期函数–监听页面隐藏
*/
onHide() {},
/**
* 生命周期函数–监听页面卸载
*/
onUnload() {},
/**
* 页面相关事件处理函数–监听用户下拉动作
*/
onPullDownRefresh() {},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {},
/**
* 用户点击右上角分享
*/
onShareAppMessage() {}
})
WXS
在html中无法使用.js的函数,但是可以使用wxs,从而完成过滤器等的功能
数据类型
number、string、boolean、object、function、array、date、regexp
wxs不支持类似于ES6以上的语法
wxs遵循CommonJS
内嵌wxs脚本
<view>{{m1.toUpper(username)}}</view>
<wxs module=“m1”>
module.exports.toUpper = function(str){
return str.toUpperCase()
}
</wxs>
外联wxs脚本
案例-本地生活
自定义组件
- 根目录下component文件夹,键入组件的名称之后回车
局部引用
- 放在页面的.json文件中
“usingComponents”: {
“my- test1”:”/compoment/test1/test1”
},
全局引用
- 放在全局app的.json文件中
组件和页面区别
- 组件.json的声明不同
- 组件的.js文件为Component()函数
- 组件的事件处理函数需要定义到methods节点中
组件样式隔离
组件中的样式不会影响外界页面,外界页面样式也不会影响组件
- app.wxss中的全局样式对组件无效
- 只有class选自其会有样式隔离效果,id选择器、属性选择器、标签选择器不受样式隔离的影响
- 在组件和引用组建的页面中建议使用class选择器,不使用id、属性、标签选择器
修改组件的样式隔离
stylelsolation可选值
data数据
// compoment/test1/test1.js
Component({
/**
* 组件的初始数据
*/
data: {
},
})
methods方法
// compoment/test1/test1.js
Component({
methods:{
addCount(){ //事件处理函数
}
\_myfunction(){//自定义函数
}
}
})
properties属性
/**
* 组件的属性列表
*/
properties: {
//第一种方式简化
min:Number,
//第二种方式完整定义
max:{
type:Number,
value:10
}
},
data和properties的区别
data更倾向与存储组件的私有数据
properties更倾向于存储外界传递到组建的中的数据
本质上相同
数据监听器
- 作用类似于vue中的watch侦听器
- 可以在一个监听器中监听多个字段
Component({
observers:{
‘字段A,字段B’:function(字段A的新值,字段B的新值){
//do something
}
}
})
<view style=“text-align: center;”>监听器的应用:{{num1}} + {{num2}} = {{sum}}</view>
<button bindtap=“addNum”>num +</button>
<button bindtap=“decNum”>num -</button>
监听对象属性的变化
- 数据监听器支持监听对象中单个或多个属性的变化
Component({
observers:{
‘对象.属性A,对象.属性B’:function(属性A的新值,属性B的新值){
//do something,监听分三种情况,分别可以对属性和对象进行赋值触发
}
}
})
案例-颜色变化块
<text style=“text-align: center;”>组件2:对象监听器的应用,改变颜色</text>
<view style=“height: 200rpx;width: 828rpx;background-color: rgb({{fullcolor}});text-align: center;line-height: 200rpx;font-size: 30rpx;text-shadow: 0rpx 0rpx 2rpx black;color: white;”>
颜色值:{{fullcolor}}
</view>
<view style=“display:flex;”>
<button bindtap=“addRed” style=“background-color:rgb(214, 141, 119)”>R</button>
<button bindtap=“addGreen” style=“background-color: lightgreen;”>G</button>
<button bindtap=“addBlue” style=“background-color: lightblue;”>B</button>
</view>
data: {
color:{
r:0,
g:0,
b:0
},
fullcolor:’0, 0, 0’
},
/\*\*
\* 组件的方法列表
\*/
methods: {
addRed(){
if(this.data.color.r + 1 > 255){
this.setData({
'color.r': 0
})
return 0
}
this.setData({
'color.r':this.data.color.r + 2
})
},
addGreen(){
if(this.data.color.g + 1 > 255){
this.setData({
'color.g': 0
})
return 0
}
this.setData({
'color.g':this.data.color.g+ 2
})
},
addBlue(){
if(this.data.color.b + 1 > 255){
this.setData({
'color.b': 0
})
return 0
}
this.setData({
'color.b':this.data.color.b + 2
})
}
},
observers:{
'color.r,color.g,color.b':function(r,g,b){
this.setData({
fullcolor:\`${r}, ${g}, ${b}\`
})
}
}
})
简化监听项
observers:{
‘color.**‘:function(obj){
this.setData({
fullcolor:`${obj.r}, ${obj.g}, ${obj.b}`
})
}
}
纯数据字段
概念:指不用于界面渲染的data字段,既不会展示在界面上,也不会出纳递给其他组件,仅在组件内部使用
好处:提升页面更新的性能
// compoment/test1/test1.js
Component({
options:{
//指定所有_开头的数据字段为纯数据字段
pureDtaPattern:/^_/ //正则表达式
},
data: {
a:true, //普通数据字段
_b:true // 纯数据字段
}
})
组件的生命周期函数
生命周期函数
参数
描述说明
created
无
在组件实例刚刚被创建时执行
attached
无
在组件实例静页面节点树时执行
ready
无
在钻进在试图层布局完成后执行
moved
无
在组件实例被移动到节点树另一个位置时执行
detached
无
在组件实列 被从页面节点数移除时执行
error
Object Error
每当组件方法抛出错误时执行
组件所在页面的生命周期
自定义的组件行为依赖于页面状态变化,此时就需要用到组件所在页面的生命周期
生命周期函数
参数
描述
show
无
组件所在页面被展示时执行
hide
无
组件所在页面被隐藏时执行
resize
Object Size
组件所在页面尺寸变化时执行
插槽
在组件中用于承载组件使用者提供的wxml结构,即替换为wxml标签
<slot></slot>
<component-tag-name>
<view> 这是插入到组件的内容</view>
</component-tag-name>
多个插槽的使用
//启用多个节点
options:{
multipleSlots:true
}
<my-test3>
<view slot=“before”>这里是插入到组件slot name=”before”中的内容</view>
<view slot=“after”>这里时插入到组件slot name=”after”中的内容</view>
</my-test3>
父子组件之间的通信
属性绑定
- 用于父组件向子组件的指定属性设置数据
事件绑定
- 用于子组件向父组件传递数据,可以传递任意数据
获取组件实例
父组件还可以通过this.selectComponent()获取子组件实例对象
这样就可以直接访问子组件的任意数据和方法
属性绑定
<view>父组件中的count = {{count}}</view>
<button bindtap=“addCount” size=“mini” type=“primary” style=“margin-left: 140px;”>count + 1</button>
<my-test4 count=“{{count}}”></my-test4>
//父组件js
/\*\*
\* 组件的初始数据
\*/
data: {
count: 0
},
<text>子组件4:</text>
<view style=“text-align: center;”>子组件中的count = {{count}}</view>
/**
* 组件的属性列表
*/
properties: {
count:Number
},
事件绑定
在父组件的js中,定义一个函数,这个函数即将通过自定义事件的形式,传递给子组件。
syncCount(e){
// console.log(‘syncCount’)
this.setData({
count:e.detail.value
})
}在父组件的wxml,通过自定义事件的形式,将步骤1定义的函数引用,传递给子组件
<my-test4 count=“{{count}}” bind:sync=“syncCount”></my-test4>
在组件的js中,通过调用this.triggerEvent(‘自定义事件名称’,{/参数对象/}),将数据发送到父组件
addCount(){
this.setData({
count : this.properties.count + 1
}),
this.triggerEvent(‘sync’,{value: this.properties.count})
}在父组件的js中,通过e.detail获取到子组件
获取组件实例
可在父组件里调用this.selectComponent(“id或class选择器”),获取子组件的实例对象,从而直接访问子组件的任意数据的方法。调用时需要传入一个选择器,例如this.selectComponent(“.my-component”)。
<my-test5 id=“ca” class=“containA”></my-test5>
<button bindtap=“getChild” type=“primary” >获取子组件的实例对象</button>
getChild(){
const child = this.selectComponent(‘.containA’)
child.setData({
count : this.data.count
})
}
behaviors
类似与vue中的mixins
工作方式,每个beavior可以包含一组属性、数据、生命周期函数和方法。组件引用它时,它的属性、数据和方法会被合并到组件中。每个组件可以引用多个behavior,behavior也可以应用其它behavior。
//组件.js
const myBehavior = require(‘../../behaviors/my-behavior’)
Component({
behaviors:[myBehavior]
)}
//behavior.js
module.exports = Behavior({
data:{
username:’zs’
},
properties:{
},
methods:{
}
})
<view>在behavior中的用户名为:{{username}}</view>
behavior的可用节点
behavior重名规则
- 同名数据字段重名规则
- 同名的属性或方法
- 同名的生命周期函数
npm包
- 不依赖于Node.js内置库的包
- 不支持依赖于浏览器内置对象的包
- 不支持依赖于C++的包
Vant Weapp
- 有赞前端团队开源
安装
- 环境node.js 安装教程https://cloud.tencent.com/developer/article/1572591
- 安装步骤 https://vant-ui.github.io/vant-weapp/#/quickstart
初始化包管理文件
npm init -y
安装npm包
npm i @vant/weapp@1.3.3 -S –production
构建npm包
微信开发者工具 –> 工具 –> 构建npm
本地设置,使用npm包,新版本不用勾选
删除style:“v2”
在页面或全局的json组件usingComponents中添加组件
“usingComponents”: {
“van-button”: “@vant/weapp/button/index”
}根据vant的文档来当作组件一样使用
定制全局主题样式
在app.wxss中,写入CSS变量,即对全局生效
page{
–button-danger-background-color:#C00000;
–button-danger-border-color:#D60000;
}
API Promise化
基于回调函数的异步API的缺点:在默认情况下,小程序官方提供的异步API都是基于回调函数实现的,容易造成回调地狱
API Promsie化通过额外的配置,将官方提供、基于回调函数的异步API,升级改在为基于Promise的异步API,从而提高代码的可对那个、维护性,避免回调地狱的问题。
实现API的Promise化,主要依赖于miniprogram-api-promise这个第三方包。
#在当前项目文件夹终端中安装npm包,记得先要初始化
npm i –save miniprogram-api-promise@1.0.4
#安装完成删除miniprogram_npm后进行npm构建
//在小程序的入口文件中(app.js),只需调用一次promisifyAll()方法
//即可实现异步API的Promise化
import {promisifyAll} from ‘miniprogram-api-promise’
const wxp = wx.p = {}
//promisify all wx’s api
promisifyAll(wx,wxp)
全局数据共享
状态管理,解决组件之间数据共享的问题,开发中常用的全局数据共享方案有:Vuex、Redux、MobX等。
在小程序中,可以使用mobx-miniprogram配合mobx-miniprogram-bindings实现全局数据共享。其中:
- mobx-miniprogram用来创建Store实例对象
- mobx-miniprogram-bindings用来把Store中的共享数据或方法,绑定到组件或页面中使用。
































