微信小程序学习笔记

也是黑马教程中学习的视频

入门

创建小程序

打开网站 https://mp.weixin.qq.com/进行注册。

获取AppID;

打开开发者工具:

  1. 代理方式推荐改为不适用任何代理,勾选后直连网络

  2. 选择新建项目,填写项目名称、目录和AppID,后端服务选择不适用云服务。

  3. 点击编译后,可以在左侧查看运行效果;也可以点击预览,然后用手机微信扫码查看

开发者文档可以点击帮助中开发者文档;设置中进行通用设置;

结构

pages:存放所有小程序的页面

utils: 存放工具性质的模块

app.js: 小程序项目的入口文件

app.json: 小程序项目的全局配置文件

app.wxss: 小程序项目的全局样式

project.config.json: 项目的配置文件

sitemap.json:用来配置小程序及其页面是否允许被微信索引

建议每个页面单独放在一个文件夹中

js文件:页面的脚本文件,存放页面的数据、事件处理函数等

json文件:当前页面的配置文件,配置窗口的外观、表现等

wxml文件:页面的模板结构文件

wxss文件:当前页面的样式表文件

JSON配置文件

项目根目录中的app.json

​ 小程序的所有页面路径、窗口外观、界面表现、底部tab等。

​ pages:所有页面的路径。

​ window:全局定义所有页面的背景色、文字等。

​ style:所使用的样式,v2是其中的一个较新版本

​ sitemapLocation:指明sitemap.json的位置。

**项目根目录中的project.config.json **

​ 小程序的开发工具 个性化设置

​ setting:和编译相关的配置(和详情中的本地设置一致)

​ projectname:项目名称(不等于小程序名称,小程序的名称在详情中查看)

​ appid:小程序的账号ID

**项目根目录中的sitemap.json **

​ 配置小程序页面是否允许微信索引

​ action:allow,允许索引;disallow,不允许索引(警告修改setting中checkSitMap为false可不再弹出)

每个页面文件夹中的json

​ 本页面中的窗口外观设置,覆盖全局配置(项目根目录中的app.json)。

​ 配置内容同项目根目录中的app.json的window中的字段。

新建小程序页面

​ app.json中 pages 中新增页面的存放路径 即可,工具自动创建对应页面。

修改小程序项目首页

​ 调整 app.json 中 pages 数组中页面路径的先后顺序即可,默认把排在第一位的页面当做首页进行渲染。

wxml

​ 类似于html,区别

  1. 标签名称不同
    1. html(div,span,img,a)
    2. wxml(view, text, image, navigator)
  2. 属性节点不同
    1. 连接
  3. 类似于vue中的模板语法
    1. 数据绑定
    2. 列表渲染
    3. 条件渲染

wxss

​ 类似于css,区别

  1. 新增rpx尺寸单位
    1. css需要手动进行像素单位换算
    2. wxss在低层支持rpx,在不同大小屏幕上会自动进行换算
  2. 提供了全局的样式和局部样式
    1. 如app.wxss和 页面中的 wxss
  3. wxss仅支持部分css选择器
    1. .class 和 #id
    2. element
    3. 并集选择器、后代选择器
    4. ::after 和 ::before 等伪类选择器

js逻辑交互

  1. app.js
    1. 小程序入口,调用app()函数启动整个小程序
  2. 页面的js
    1. 页面的入口文件,通过调用Page()函数来创建并运行界面
  3. 普通的js
    1. 普通的功能模块文件,用来封装公共函数和属性

宿主环境

概念

宿主环境是指程序运行所必须的依赖环境。例如:android和iOS是两个不同的宿主环境。

手机微信是小程序的宿主环境,基于微信完成功能。

小程序宿主环境包含的内容包括:

  1. 通信模型
  2. 运行机制
  3. 组件
  4. API

通信模型

通信主体

  1. 渲染层:wxml模板和wxss样式工作在渲染层
  2. 逻辑层:js脚本工作在逻辑层

通信模型分为两部分:

  1. 渲染层和逻辑层之间的通信:由微信客户端进行转发
  2. 逻辑层和第三方服务器之间的通信: 由微信客户端进行转发

运行机制

小程序启动过程

  1. 将小程序的代码包下载到本地
  2. 解析app.json全局配置文件
  3. 执行app.js小程序入口文件,调用App()创建小程序实例
  4. 渲染小程序首页
  5. 启动完成

页面渲染过程

  1. 加载解析页面的json配置文件
  2. 加载页面的wxml模板和wxss样式
  3. 执行页面的js文件,调用page()创建页面实例
  4. 渲染完成

组件

组件由宿主环境提供,共分为九类

  1. 视图容器

    1. view:视图区域组件,类似于div,实现页面布局效果
    2. scroll-view: 可滚动的视图区域;实现滚动列表的效果
    3. swiper和swiper-item:轮播图容器组件,和轮播图item组件
  2. 基础内容

    1. text:文本组件,类似于span
    2. rich-text:富文本
  3. 表单组件

  4. 导航组件

  5. 媒体组件

  6. map地图组件

  7. canvas画布组件

  8. 开放能力

  9. 无障碍访问

view

横向布局,类名使用container貌似有问题

<view class="container1">
	<view>Aview>
    <view>bview>
    <view>cview>
view>

.container1 view{
    width:50px;
    height:50px;
    text-align:center;
    line-height:50px;
}
.container1 view:nth-child(1){
    background-color:lightgreen;
}
.container1 view:nth-child(2){
    background-color:lightskyblue;
}
.container1 view:nth-child(3){
    background-color:lightcoral;
}
.container1{
    display: flex;
    justify-content: space-around;
}

scroll-view

实现纵向滚动效果,横向滚动使用scroll-x

<scroll-view class="container1" scroll-y>
	<view>Aview>
    <view>bview>
    <view>cview>
scroll-view>
.container1 view{
    width:100px;
    height:100px;
    text-align:center;
    line-height:100px;
}
.container1 view:nth-child(1){
    background-color:lightgreen;
}
.container1 view:nth-child(2){
    background-color:lightskyblue;
}
.container1 view:nth-child(3){
    background-color:lightcoral;
}
.container1{
	border: 1px solid red;
    height:120px;
    width:100px;
}

swiper和swiper-item

<swiper class="swiper-container" indicator-dots>
    <swiper-item>
        <view class="item">Aview>
    swiper-item>
    <swiper-item>
        <view class="item">bview>
    swiper-item>
    <swiper-item>
        <view class="item">cview>
    swiper-item>
swiper>
.swiper-container{
    height: 150px;
}
.item{
    height: 100%;
    line-height: 150px;
    text-align: center;
}

swiper-item:nth-child(1) .item{
    background-color: lightgreen;
}
swiper-item:nth-child(2) .item{
    background-color: lightskyblue;
}
swiper-item:nth-child(3) .item{
    background-color: lightcoral;
} 

组件常用属性:

  1. indicator-dots : 默认false,是否显示面板指示点
  2. indicator-color: 默认rgba(0,0,0,.3),指示点颜色
  3. indicator-active-color : 默认#000000,当前选中指示点颜色
  4. autoplay : 默认false,是否自动切换
  5. interval : 默认5000,自动切换间隔,单位ms
  6. circular: 默认false,是否采用衔接滑动

text

通过text的selectable属性,实现长按选中文本内容,只有text支持长按选中。

<view>
    手机号可以长按选中
	<text selectable>13131311313text>
view>

rich-text

通过组件的nodes属性节点,可以把html字符串渲染为对应的UI结构:

<rich-text nodes=" style='color:red;'>标题</h1>">rich-text>

button

按钮组件,通过open-type属性可以调用微信提供的各种功能(客服、转发、获取用户授权、获取用户信息等)

<button>黑色按钮button>
<button type="primary">绿色按钮button>
<button type="warn">红色按钮button>

<button size="mini">小尺寸按钮button>
<button type="primary" size="mini">绿色按钮button>
<button type="warn" size="mini">红色按钮button>

<button size="mini" plain>小尺寸镂空按钮button>
<button type="primary" size="mini" plain>绿色按钮button>
<button type="warn" size="mini" plain>红色按钮button>

image

图片组件,默认宽度300px,高240px

<image>image>
<image src="/images/1.png">image>
<image src="/images/1.png" mode="aspectFit">image>
image{
    border:1px solid red;
}

image组件的mode属性用来指定图片的裁剪和缩放模式,常见属性如下:

  1. scaleToFill:缩放模式(默认值),不保持纵横比缩放图片,是图片的宽高完全拉伸到填满image元素
  2. aspectFit:缩放模式,保持纵横比缩放图片,使图片的长边完全能够显示出来,可以完整的显示图片
  3. aspectFill:缩放模式,保持纵横比缩放图片,只保证图片的短边完全显示,也就是图片只在一个方向完整。
  4. widthFix:缩放模式,image宽度不变,高度自动变化(image的高度),保持原图宽高比不变
  5. heightFix:缩放模式,image高度不变,宽度自动变化(image的宽度),保持原图宽高比不变

API

小程序的API是宿主环境提供的,包括获取用户信息、本地存储、支付功能等。

事件监听

特点:以on开头,用来监听某些事件的触发

举例:wx.onWindowResize(function callback)监听窗口尺寸的变化

wx可以理解为js中的window全局对象。

同步API

特点:以sync结尾

​ 同步API的执行结果,可以通过函数返回值直接获取,失败则抛出异常

举例:wx.setStorageSync(‘key’,‘value’)向本地存储写入内容。

异步API

特点:类似于ajax(option),需要通过success、fail、complete等接受调用结果

举例:wx.request()发起网络请求,通过success回调函数接收数据。

发布

上传代码:点击开发工具栏中的上传,写版本号和项目备注。

查看版本:小程序管理后台,管理,版本管理,开发版本中查看

提交审核

发布

二维码获取:小程序管理后台,设置,基本设置,小程序码和线下物料下载

基础

数据绑定

在data中定义数据

在页面对应的js中

Page({
    data:{
        info:'hello',
        imgsrc:'http://www.itheima.com/images/logo.png',
        randomNum:Math.random() * 10,
        randomNum2:Math.random().toFixed(2),
    }
})

在wxml中使用数据

mustache语法,插值表达式

动态绑定内容

<view>{{info}}view>

动态绑定属性

<image src="{{imgsrc}}">image>

三元运算,算数运行

<view>{{randomNum >= 5 ? '大于5' : '小于5'}}view>
<view>{{randomNum * 100}}view>

可以在调试工具的AppData中查看data中的数据。

data赋值

通过this.setData设置,通过this.data访问

Page({
    data:{
        count:0
    },
    changeCount(){
        this.setData({
            count:this.data.count + 1
        })
    }
})

事件绑定

事件是渲染层到逻辑层的通讯方式,可以通过事件将用户在渲染层发生的行为,反馈到逻辑层处理。

常用事件:

类型 绑定方式 事件描述
tap bindtap,bind:tap 类似于点击事件,手指点完离开
input bindinput 文本框输入
change bindchange 状态改变,如checkbox

当事件回调触发时,会收到一个事件对象event,他的属性如下

属性 类型 说明
type string 事件类型
timeStamp integer 页面打开到触发事件所经过的毫秒数
target object 触发事件的组件的一些属性值集合
currentTarget object 当前组件的一些属性值集合
detail object 额外的信息
touches array 触摸事件,当前停留在屏幕中的触摸点信息的数组
changedTouches array 触摸事件,当前变化的触摸点信息的数组

target是触发事件的源头组件,currentTarget是当前事件所绑定的组件。

<view bindtap="handle">
	<button>
        按钮
    button>
view>

此时如果按钮上有点击事件,view上进行事件监听,那么target指向的是按钮,currentTarget指向的是view。

以上点击事件处理函数如下:

Page({
    handle(e){
        console.log(e)
    }
})

传参

不能在绑定事件的同时为事件处理函数传递参数,即以下写完不合规

需要通过’data-'传参,如下进行:

<button type="primary" bindtap="handle" data-info="{{2}}">
    事件传参
button>

最终,info会被解析为参数的名字,数字2被解析为参数值。2需要放在{{}}中,否则会被解析为字符串2.

Page({
    handle(event){
        console.log(event.target.dataset)
        console.log(event.target.dataset.info)
    }
})

获取参数时通过event.target.dataset获取,dataset是一个对象,包含了所有通过data-*传递过来的参数项;通过dataset可以访问具体参数的值。

bindinput

绑定事件

<input bindinput="handle">input>

事件处理

handle(e){
    console.log(e.detail.value)
}

e.detail.value是变化后,文本框最新的值。

文本框和data之间的数据同步

<input value="{{msg}}" bindinput="handle">input>
Page({
    data:{
        msg:'hello'
    },
    handle(e){
        this.setData({
            msg:e.detail.value
        })
    }
})

条件渲染

通过wx:if="{{condition}}"来判断是否需要渲染代码块。

也可以使用wx:elifwx:else进行判断

<view wx:if="{{condition}}">ok1view>
<view wx:elif="{{condition2}}">ok2view>
<view wx:else>okelseview>

结合block

如果一次性控制多个组件的显示和隐藏,可以使用block标签上加wx:if控制。block并不是一个组件,只是一个包裹性容器,不会在页面中做任何渲染。(为啥不用view呢?只是少渲染一个view)

<block wx:if="{{condition}}">
	<view>view1view>
    <view>view2view>
block>

hidden

可以直接使用hidden="{{condition}}"进行控制显示隐藏。

<block hidden="{{condition}}">
	<view>view1view>
    <view>view2view>
block>

不同:

  1. 运行方式
    1. wx:if 以动态创建和移除元素的方式控制 显示 隐藏
    2. hidden 以切换样式的方式(display:none/block),控制 显示 隐藏
  2. 建议
    1. 切换频繁,建议使用hidden
    2. 控制条件复杂,可以使用wx:if搭配wx:elif、wx:else

列表渲染

wx:for

​ 通过wx:for可以根据指定的数组,循环渲染重复的组件结构,如下:

<view wx:for="{{array1}}">
	索引:{{index}} 当前项是:{{item}}
view>
Page({
  data:{
      array1 :["apple","banana"]
  }  
})

手动指定索引和当前项的变量名

修改index和item的变量名,可以使用其他名称指代

<view wx:for="{{array1}}" wx:for-index="idx" wx:for-item="itm">
	索引:{{idx}} 当前项是:{{itm}}
view>

key

建议指定唯一key值,提高渲染效率

Page({
  data:{
      array1 :[
      	{id:1,name:'h'},
        {id:2,name:'e'},
        {id:3,name:'l'},
      ]
  }  
})
<view wx:for="{{array1}}" wx:key="id">
	索引:{{index}} 当前项是:{{item}}
view>

没有key时 可以使用index作为key值

进阶

wxss

相较于css,扩展了 rpx 尺寸 和 @import ;也有一些选择器和样式不可使用。
rpx,解决小程序尺寸适配问题,rpx将屏幕横向上分为750份,rpx自动进行单位换算。一般建议iphone6作为视觉参考,1rpx=0.5px。
@import,后接需要导入的外联样式表的相对路径,用分号表示语句结束,如@import "common.wxss";,common.wxss在当前路径下,在wxss中使用。
全局样式,定义在app.wxss页面样式,作用于所有页面。
局部样式,定义在 页面.wxss 的样式,只作用于当前页面。局部样式会覆盖全局样式,只有局部页面样式权重大于等于全局样式才会覆盖。

全局配置

根目录中的app.json文件。

  1. pages, 记录当前小程序页面的存放路径
  2. window,全局设置窗口的外观
  3. tabBar,底部tabBar的效果
  4. style,是否启用新版的组件样式,值如‘v2’

window节点常用配置:

  1. navigationBarTitleText:导航栏标题文本
  2. navigationBarBackgroundColor:导航栏背景颜色,只支持"#121212"格式
  3. navigationBarTextStyle:导航栏标题文本颜色,只支持“white”和“black”
  4. enablePullDownRefresh:全局开启下拉刷新,true;会作用于每个页面,效果可能在开发工具中表现的有差异。
  5. backgroundColor:下拉刷新时的背景颜色,只能是"#121212"格式
  6. backgroundTextStyle:下拉刷新时的loading样式,小圆点样式,只能时light和dark。
  7. onReachBottomDistance:上拉触底的距离,默认距离50px,一般不更改。

tabBar

用于实现多页面切换,分为顶部tabBar和底部tabBar。
只能配置做少2个,最多5个;当渲染顶部tabBar,只显示文本。
微信小程序学习笔记_第1张图片

  1. backgroundColor:背景色
  2. selectedIconPath:选中时的图片路径
  3. borderStyle:边框的颜色
  4. iconPath:未选中时的图片路径
  5. selectedColor:文字选中时的颜色
  6. color:文字未选中的颜色

app.json中tabBar节点配置项

  • position:bottom或者top
  • borderColor:边框的颜色
  • color:文字未选中的颜色
  • selectedColor:文字选中时的颜色
  • backgroundColor:背景色
  • list:必选,tab页列表,大于等于2个,小于等于五个

其中list项对象包括的配置选项如下:

  • pagePath: 必填,页面路径,同Pages中的内容
  • text: tab显示的文本呢
  • iconPath: 未选中时的图片路径
  • selectedIconPath:选中时的图片路径

注意:tabBar涉及到的页面必须放在pages数组中的前面。

页面配置

页面下的 .json文件,对单独页面窗口外观进行配置。
如,增加节点 navigationBarBackgroundColor:"#ff0000",则对当前页面导航栏进行了修改。
节点内容同app.json中window下各个键:navigationBarTitleTextnavigationBarBackgroundColornavigationBarTextStyleenablePullDownRefreshbackgroundColorbackgroundTextStyleonReachBottomDistance

网络数据请求

限制:

  1. 只能请求https类型的接口
  2. 必须将接口的域名添加到信任列表,(可以在开发工具中的详情➡项目配置➡域名信息 中查看 request合法域名)
  3. 所以地址必须时域名,不可以时ip的格式

配置合法域名:
登录微信小程序管理后台➡开发➡开发配置➡服务器域名➡需改request合法域名。

get请求

使用wx.request()方法

wx.request({
	url:'https://www.escook.cn/api/get',
	method:'GET',
	data:{
		name:'zs',
		age:'30'
	},
	success:(res)=>{
		console.log(res);
	}
})

post请求

使用wx.request()方法

wx.request({
	url:'https://www.escook.cn/api/post',
	method:'POST',
	data:{
		name:'zs',
		age:'30'
	},
	success:(res)=>{
		console.log(res);
	}
})

在页面加载时请求数据

可以在页面的 onLoad 中进行请求。

onLoad:function(options){
	this.getData();//页面中的方法
}

跳过request合法请求

可以在开发者工具中临时开启(详情➡本地设置) 开发环境不校验请求域名、TLS版本及https证书跳过域名校验。
只能在开发调试中使用。

跨域和ajax

  1. 小程序中不存在跨域的问题。
  2. ajax依赖于浏览器的XMLHttpRequest,但是小程序不是浏览器,所以只能叫做发起网络数据请求。

页面导航

即页面跳转

  1. 声明式导航:通过点击 实现条状。
  2. 编程时导航:调用api,

导航到tabBar页面(声明式)

需要指定url 和 open-type 属性,其中

  • url 表示要跳转到的页面地址,必须是 / 开头
  • open-type 表示跳转的方式,必须为 switchTab
    如:
<navigator url="pages/message/message" open-type="switchTab">导航到消息页面navigator>

导航到非tabBar页面(声明式)

  • url 表示要跳转到的页面地址,必须是 / 开头
  • open-type 表示跳转的方式,必须为 navigate(此属性可以省略,效果相同)
    如:
<navigator url="pages/message/message" open-type="navigate">导航到非tab面navigator>

后退导航(声明式)

  • delta值必须是数字,表示要后退的层级,默认为1,表示后退一步。
  • open-type 为 navigateBack,表示后退导航

导航到tabBar页面(编程式)

调用 wx.switchTab(Object object) 方法,可以跳转到tabBar,其中object属性:

  1. url 字符串,需要跳转的tabBar路径,路径不能带参数
  2. success 函数,成功的回调
  3. fail 函数,失败的回调
  4. complete 函数,完成的回调
wx.switchTab({
	url:'/pages/message/message'
})

导航到非tabBar页面(编程式)

调用 wx.navigateTo(Object object) 方法,可以跳转到非tabBar,其中object属性:

  1. url 字符串,需要跳转的非tabBar路径,路径不能带参数
  2. success 函数,成功的回调
  3. fail 函数,失败的回调
  4. complete 函数,完成的回调
wx.navigateTo({
	url:'/pages/message/message'
})

后退导航(编程式)

调用navigateBack,返回上一页面或多级页面,可选参数如下:

  1. delta字符串,表示要后退的层级,大于现有页面则返回首页
  2. success 函数,成功的回调
  3. fail 函数,失败的回调
  4. complete 函数,调用结束完成返回的回调

wx.navigateBack()默认返回上一页吗。

导航传参(声明式)

url路径后面可以携带参数:

  • 参数与路径之间使用?分割
  • 参数键与参数值用=相连
  • 不用参数用&分割
<navigator url="/pages/info/info?name=tom&age=30">跳转navigator>

可以再模拟器左下角的页面参数查看。

导航传参(编程式)

调用wx.navigateTo(Object object)跳转时,可以携带参数,如下

wx.navigateTo({
	url:"pages/info/info?name=ls&age=32"
})

接受导航传参

在onLoad中直接获取(在options),假设存储到data中的query:

onLoad:function(options){
	console.log(options)
	this.setData({
		query:options
	})
}

在这里插入图片描述

下拉刷新和上拉触底

启用下拉刷新

  1. 全局开启,app.json ➡ window ➡ enablePullDownRefresh 设置true
  2. 局部开启,页面json ➡ enablePullDownRefresh 设置true(推荐)

下拉窗口样式

全局或者页面json中

  1. backgroundColor:背景颜色 16进制格式
  2. backgroundTextStyle:loading的样式,dark 或者light

监听下拉刷新事件

在页面.js 中 onPullDownRefresh() 函数中监听。

onPullDownRefresh:function(){
	//todo
	console.log("下拉刷新")
}

停止下拉刷新效果

通过wx.stopPullDownRefresh 实现:

onPullDownRefresh:function(){
	//todo
	console.log("下拉刷新")
	wx.stopPullDownRefresh()
}

监听上拉触底

在页面的js文件中,通过 onReachBottom 函数监听:

onReachBottom:function(){
	//todo
	console.log("上拉触底")
}

例子:

<view wx:for="{{colorList}}" wx:key="index" class="num-item" sytle="background-color:rgba({{item}})">{{item}}view>
data:{
	colorList:[],//随机颜色
	isloading:false //是否正在请求
},
getColors(){
	this.setData({
		isloading:true
	})
	wx.showLoading({title:'数据加载中...'})//展示提示窗
	wx.request({
		url:"https://www.essss.cn/api/getcolor",
		method:'GET',
		success:({data:res})=>{
			this.setData({
				colorList:[...this.data.colorList,...res.data]
			})
		}complete:()=>{
			wx.hideLoading()//隐藏提示窗
			this.setData({
				isloading:false
			})
		}
	})
},
onLoad:function(options){
	this.getColors()
},
onReachBottom:function(){
//需要节流处理,防止上次没处理完再此请求
	if(this.data.isloading) return
	this.getColors()
}
.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 7rpx #aaa;
}

...展开运算符,用于对数组或者对象的操作,也可以将几个数组进行连接,参考,

let arr=[1,2,3]
 // 展开一个数组
 console.log(...arr)

 console.log("-----------");
 // 复制一个数组,也称为拷贝数组
 let arr2=[...arr]
 arr2.push(4);
 // 并且不会对arr造成影响
 console.log("arr",arr);
 console.log("arr2",arr2);
 
 console.log("-----------");
 
 // 连接数组
 let arr3=[...arr,...arr2] 
 console.log(arr3);
 
//对象操作-------------------------------------------------
var obj1 = { foo: 'yuan', x: 42 };
var obj2 = { foo: 'li', y: 13 };

// 克隆对象一定要加上{}
var clonedObj = { ...obj1 };
console.log("克隆后的对象",clonedObj);
console.log("-----------");
// 同样的修改复制后的并不会影响原来的对象
clonedObj.foo="ss"
console.log("clonedObj",clonedObj);
console.log("obj1",clonedObj);
console.log("-----------");

// 合并后的对象:
var mergedObj = { ...obj1, ...obj2}
console.log("合并后的对象",mergedObj);

console.log("-----------");
// 当然也可以在合并时添加新的属性
var mergedObj = { ...obj1, ...obj2,address:"上海"}
console.log("合并后的对象",mergedObj)
   
原文链接:https://blog.csdn.net/qq_44259670/article/details/116397831

自定义编译模式

每次重新编译后,模拟器自动跳转到首页
普通编译 下拉➡添加编译模式➡启动页面 的值进行修改,启动参数也可以自动添加,如name=zs。
删除时,可以点击 添加编译模式 中的 自定义编译模式 边的修改按钮,删除。

生命周期

  1. 应用生命周期:小程序从启动➡运行➡销毁的过程
  2. 页面生命周期:页面的加载➡渲染➡销毁的过程

应用的生命周期函数

需要再app.js中进行声明。

App({
	//小程序初始化完成时,执行此函数,全局只触发一次,可以进行初始化
	onLaunch:function(options){ },
	//小程序启动,或从后台进入前台显示时触发。
	onShow:function(options){ },
	//小程序从前台进入后台时出发。
	onHide:function(){ }
})

页面的生命周期函数

需要再页面.js中进行声明。

Page({
	onLoad:function(options){ }, //监听页面加载,一个页面只能调用一次
	onReady:function(){ },//监听页面初次渲染完成,一个页面只能调用一次
	onShow:function(){ },//监听页面显示
	onHide:function(){ },//监听页面隐藏
	onUnload:function(){ },//监听页面卸载,一个页面只能调用一次
})

wxs脚本

wxs是微信小程序独有的脚本语言,结合wxml可以构建出页面的结构。
可以应用为过滤器。

  1. wxs有自己的数据类型,同js
  2. wxs不支持类似es6以上的语法,如let 箭头函数 展开运算符
  3. wxs遵循commonjs规范,如module对象,require()函数,module.exports

使用wxs脚本

wxs代码可以编写在wxml文件中的标签内。
wxml文件中的每个标签,必须提供module属性,用来指定当前wxs的模块名称,方便wxml中访问模块的成员。

<view>{{m1.toUpper(username)}}view>
<wxs module="m1">
module.exports.toUpper = function(str){
	return str.toUpperCase()
}
wxs>

外联wxs脚本
wxs代码还可以编写在 .wxs后缀的文件内,如:
//tools.wxs

function toLower(str){
	return str.toLowerCase()
}
module.exports = {
	toLower:toLower
}

应用外联wxs脚本时需要添加module和src属性(相对路径)

<wxs module="m2" src="../../utils/tools.wxs">wxs>
<view>{{m2.toLower(username)}}view>

注意:

  1. wxs的应用一般时作为过滤器,配合mustache语法使用,如上两个例子。
    不能进行作为组件的事件回调函数,例如不能以下写法:
<button bindtap="m2.toLower">按钮button>
  1. wxs不能调用js中的函数和小程序中的API。

组件和样式

创建

  1. 项目根目录 右键 新建文件夹 创建 components 文件夹,下面创建 test 文件夹
  2. test 文件夹上 右键 新建Component
  3. 输入组件名称后回车,自动生成四个文件,js json wxml wxss

建议每个组件单独创建一个文件夹存放。

引用

  1. 局部引用:组件只能被当前页面引用
  2. 全局引用:组件可以在每个小程序页面中引用

局部应用:
页面.json 文件中引用

{
	"usingComponents":{
		"my-test1":"/component/test1/test1"
	}
}

页面给中使用组件

<my-test1>my-test1>

全局引用:
在app.json文件中,引入组件

{
	"pages":[],
	"usingComponents":{
		"my-test1":"/component/test1/test1"
	}
}

页面给中使用组件

<my-test1>my-test1>

组件文件

  1. 组件中的json文件中需要声明"component":true属性
  2. 组件的js文件中调用的是Component() 函数
  3. 组件的事件处理函数需要定义到methods节点中

组件样式隔离

组件间的样式不会影响到小程序和其他组件的样式,同样小程序和其他组件的样式也不影响到组件里的样式。
即组件内不可以使用app.wxss里面定义的样式类。
只用类选择器会被影响,id、标签、属性选择器不受影响,所以建议在组件中使用类选择器

修改组件样式隔离

通过styleIsolation修改,其可选值:

  1. isolated,默认值,启用样式隔离
  2. apply-shared 页面wxss样式将影响到组件,但组件wxss中的样式不会影响到页面。
  3. shared 页面wxss会影响到组件,组件wxss中的样式也会影响到页面和其他设置了shared和apply-shared的组件。

组件的js文件中增加配置:

Component({
	options:{
		styleIsolation:'isolated'
	}
})

或者在组件的json文件中增加配置:

{
	"styleIsolation":"isolated"
}

数据

需要定义到data节点中

Component({
	data:{
		count:0
	}
})

方法

组件中方法需要定义到methods节点中

Component({
	methods:{
		addCount(){ //事件处理函数
			//todo
		},
		_showCount(){// 自定义方法建议下划线_开头
			//todo
		}
	}
})

属性

properties 是组件对外的属性,用来接受外界传递到组件中的数据,示例如下:

Component({
	properties:{
		max:{	//完整定义属性的方式,需要指定属性默认值时,建议使用此方法
			type:Number,	//属性值的数据类型
			value:10		// 默认值
		},
		max:Number	//简化定义属性的方式,不需指定属性默认值时,可以使用简化方式
	},
	methods:{
		getMax(){
			return this.properties.max
		}
	}
})

使用:

<my-test max="10">my-test>

data和properties区别

  1. 都是可读可写的
  2. data倾向于存储私有数据
  3. properties倾向于存储传递过来的数据
Component({
	properties:{
		max:{	//完整定义属性的方式,需要指定属性默认值时,建议使用此方法
			type:Number,	//属性值的数据类型
			value:9		// 默认值
		},
		max:Number	//简化定义属性的方式,不需指定属性默认值时,可以使用简化方式
	},
	methods:{
		printf(){
			console.log(this.data)
			console.log(this.properties)
			console.log(this.data === this.properties)
		}
	},
	data:{
		count:0
	}
})

微信小程序学习笔记_第2张图片
调用printf,结果为true;证明data数据和properties在本质上是一样的,都是可读可写的。因此properties属性的值也可以用于页面渲染,或使用setData为properties中是属性重新赋值。

修改properties的值

Component({
	properties:{max:Number},
	methods:{
		addCount(){
			this.setData({max:this.properties.max + 1})
		}
	}
})
<view>properties{{max}}view>

数据监听器

数据监听器用于监听和响应任何属性和数据字段的变化,执行特定的操作。类似与vue中的watch。

Component({
	data:{d1:0,d2:0},
	methods:{
		chg(){
			this.setData({
				d1:1
			})
		}
	},
	observers:{//数据监听器
		'd1,d2':function(newd1,newd2){//监听d1和d2的变化
			//todo
		}
	}
})

也可以监听对象的单个或多个属性,多个属性中如果其中一个变化则会触发监听器。

Component({
	data:{
		o:{a:o,b:1}
	},
	methods:{
		chg(){
			this.setData({
				o:{a:11,b:22}
			})
		}
	},
	observers:{//数据监听器
		'o.a,o.b':function(newd1,newd2){//监听o的a和b属性的变化
			//todo
		}
	}
})

案例:

Component({
	data:{
		rgb:{
			r:0,
			g:0,
			b:0
		},
		fullColor:'0,0,0'
	},
	properties:{
	
	},
	methods:{
		changeR(){
			this.setData({
				'rgb.r':this.data.rgb.r + 5 > 255 ? 255 :this.data.rgb.r + 5
			})
		},
		changeG(){
			this.setData({
				'rgb.g':this.data.rgb.g + 5 > 255 ? 255 :this.data.rgb.g + 5
			})
		},
		changeB(){
			this.setData({
				'rgb.b':this.data.rgb.b + 5 > 255 ? 255 :this.data.rgb.b + 5
			})
		},
	},
	observers:{
		'rgb.r, rgb.g, rgb.b':function(r,g,b){
			this.setData({
				fullColor: `${r},${g},${b}`
			})
		}
	}
})
<view style="background-color:rgb({{fullColor}});" class="colorBox">颜色值:{{fullColor}}view>
<button size="mini" bindtap="changeR" type="default">Rbutton>
<button size="mini" bindtap="changeG" type="primary">Gbutton>
<button size="mini" bindtap="changeB" type="warn">Bbutton>
.colorBox{
	line-height:200rpx;
	font-size:24rpx;
	color:white;
	text-shadow:0rpx 0rpx 2rpx black;
	text-align:center;
}

如果要监听的属性过多,可以使用通配符**来监听所有属性的变化,如

observers:{
	'rgb.**':function(obj){
		this.setData({
			fullColor:`${obj.r},${obj.g},${obj.b}`
		})
	}
}

纯数据字段

指不用于渲染的data数据,如上例中的rgb,如果data中的字段既不展示到界面上,也不会传递给其他组件,仅仅在当前组件内部使用,这种特性的字段适合设置为纯数据字段。
有助于提升页面更新的性能。

使用规则:
在Component的options节点中,指定pureDataPattern为一个正则表达式,字段名称符合此正则表达式的字段将成为纯数据字段。如

Component({
	options:{
		//指定下划线开头的数据为纯数据字段
		pureDataPattern:/^_/
	},
	data:{
		a:true,//普通数据字段
		_b:true//纯数据字段,只应用于数据逻辑,不渲染到页面上
	}
})

监听纯数据字段:

Component({
	options:{
		//指定下划线开头的数据为纯数据字段
		pureDataPattern:/^_/
	},
	data:{
		_rgb:{
			r:0,
			g:0,
			b:0
		}
	},
	observers:{
	'_rgb.**':function(obj){
		this.setData({
			fullColor:`${obj.r},${obj.g},${obj.b}`
		})
	}
}
})

组件的生命周期

生命周期函数如下:

生命周期函数 参数 描述说明
created 在组件实例刚刚被创建时调用
attached 在组件实例进入页面节点树时执行
ready 在组件在视图层布局完成后执行
moved 在组件实例被移动到页面节点树另一个位置时执行
detached 在组件实例被从页面节点树移除时执行
error Object Error 每当组件方法抛出错误时执行

顺序如表中的顺序。
重点使用以下几个:
created:
在组件被创建好的时候,该函数被触发;此时还不能使用setData,此阶段只能给组件的this添加一些自定义的属性字段。
attached:
该阶段,this.data已经被初始化完毕;绝大多数初始化工作可以在此阶段进行。
detached:
退出页面时,页面中的组件会触发detached;该阶段一般进行清理工作,如取消监听。

生命周期函数的使用

Component({
	//推荐使用
	lifetimes:{
		attached(){},
		detached(){}
	},
	//旧式的定义方式
	attached(){},
	detached(){}
})

新旧方式同时存在时,lifetimes中的生命周期函数会覆盖旧式的。

组件内部也可以监听 组件 所在 页面的生命周期,

生命周期函数 参数 描述
show 组件所在页面被展示时执行
hide 组件所在页面被隐藏时执行
resize Object Size 组件所在页面尺寸发生变化时执行

使用:

Component({
	pageLifetimes:{//监听所在页面的生命周期
		show(){},
		hide(){},
		resize(){}
	}
})

插槽

在wxml结构中,提供了一个** **节点(插槽),用于承载组件使用者提供的wxml结构。
可以理解为组件中预留的占位符,组件使用者提供具体的内容。

单个插槽
小程序中,默认每个自定义组件中只允许使用一个 slot 进行占位,这种个数上的限制,叫做单个插槽。


<view class="wrapper">
	<view>这里是组件的内部节点view>
	<slot>slot>
view>


<component-tag-name>
	<view>这里是插入组件slot中的内容view>
component-tag-name>

多个插槽
启用多个插槽,在组件的js文件中进行配置:

Component({
	options:{
		multipleSlot:true//启用多个插槽
	}
})

多个slot标签,使用name来区分


<view class="wrapper">
	<slot name="before">slot>
	<view>这里是组件的内部节点view>
	<slot name="after">slot>
view>


<component-tag-name>
	<view slot="before">这里是插入组件slot中的内容1view>
	<view slot="after">这里是插入组件slot中的内容2view>
component-tag-name>

父子组件通信

  1. 属性绑定
    • 用于父组件向子组件的指定属性设置数据,仅能设置json兼容的数据(不能传递方法)
  2. 事件绑定
    • 用于子组件向父组件传递数据,可以传递任意数据
  3. 获取组件实例
    • 父组件可以通过 this.selectComponent()获取子组件实例的对象
    • 然后就可以直接访问子组件的任意数据和方法

属性绑定
父组件

<view> count值{{count}}view>
<my-com count="{{count}}">my-com>
data:{
	count:0
}

子组件

properties:{
	count:Number
}
<view> 子组件 count值{{count}}view>

事件绑定

  1. 父组件的js中,定义一个函数,这个函数即将通过自定义事件的形式,传递给子组件。
  2. 父组件的wxml中,通过自定义事件的形式,将步骤1中定义的函数引用,传递给子组件。
  3. 子组件的js中,通过调用this.triggerEvent('自定义事件名称‘,{参数对象}),将数据发送到父组件。
  4. 父组件的js中,通过e.detail获取到子组件传递过来的数据

父组件

//父组件中定义syncCount 方法
syncCount(e){
	console.log("syncCount")
	console.log(e.detail.value)
}

<my-com count="{{count}}" bind:sonf="syncCount">my-com>

<my-com count="{{count}}" bindsonf="syncCount">my-com>

子组件

methods:{
	addcount(){
		this.triggerEvent('sonf',{value:this.properties.count})
	}
}

获取组件实例
在父组件中调用this.selectComponent("id或者css选择器"),获取子组件的实例对象,从而直接访问子组件的任意数据和方法。调用时需要传入一个选择器。

<my-com class="comA" id="ca">my-com>
<button bindtap="getchd">getbutton>
getchd(){
//不支持标签选择器
	const child = this.selectComponent('.comA')
	child.setData({//调用子组件的setData方法
		count:child.properties.count + 1
	})
	child.addCount()//调用子组件的方法
}

behaviors

用于实现组件间代码共享的特性,类似于vue中的mixins。
自定义组件A ←引用←代码共享(behavior)→引用→自定义组件B。
工作方式:
每个behavior 可以包含一组 属性、数据、生命周期函数 和方法。组件引用他时,他的属性、数据和方法会被合并到组件中。
每个组件可以引用多个behavior,behavior也可以引用其他的behavior。
创建behavior
调用Behavior(Object object)方法即可创建一个共享的behavior实例对象,供所有组件使用:
my-b.js

//调用 Behavior()方法,创建实例
//使用 module.exports 将 behavior 实例对象共享出去
module.exports = Behavior({
	//属性节点
	properties:{},
	//私有数据节点
	data:{username:'zs'},
	//事件处理函数 和 自定义方法节点
	methods:{},
	//其他节点
})

导入并使用behavior
在组件中,使用 require() 方法导入需要的behavior, 挂载后即可访问behavior中的数据或方法,如:

//1. 使用 require() 导入需要的自定义 behavior 模块
const myBehavior = require("../../behaviors/my-b")

Component({
	//2. 将导入的 behavior 实例对象,挂载到 behaviors 数组节点中,即可生效
	behaviors:[myBehavior],
	//组件的其他节点
})
<view>behavior:{{username}}view>

behavior中可用的节点
propertie、data、methods、behaviors使用较多。

可用的节点 类型 是否必填 描述
properties Object Map 同组件的属性
data Object 同组件的数据
methods Object 同自定义组件的方法
behavior String Array 引入其他的behavior
created Function 生命周期函数
attached Function 生命周期函数
ready Function 生命周期函数
moved Function 生命周期函数
detached Function 生命周期函数

behavior中同名字段的覆盖和组合规则
组价和它引用的 behavior 中 可以包含同名的 字段,处理规则如下:

  1. 数据(data)重名
    • 对象类型数据,会进行对象合并
    • 其余情况进行数据覆盖,组件 > 父behavior > 子behavior
  2. 属性(properties)和方法
  3. 生命周期函数

使用npm包

小程序支持npm包,但是有3个限制:

  1. 不支持依赖于 Node.js 内置库的包,如fs、path
  2. 不支持依赖于浏览器内置对象的包,如jquery
  3. 不支持依赖于c++插件的包,如一些加密包
    所以支持的包很少。

vant Weapp

前端开源 小程序UI组件库,使用MIT开源许可协议。
网址:https://youzan.github.io/vant-weapp/#/home

安装

  1. 通过npm安装,可以使@1.3.3版本
  • npm init -y,生成package.json
  • npm i @vant/weapp -S --production,安装vant Weapp,也可以指定版本号npm i @vant/[email protected] -S --production
  1. 构建npm包
  • 工具→构建npm,勾选使用npm模块
  • 右上角 详情,勾选使用npm模块
  1. 修改app.json
  • 将 “style”:“v2” 删除,防止样式冲突

小程序中打开终端的方法:目录树空白处右键,在外部终端窗口打开。

使用

在 app.json 的 usingComponents 节点引入需要的组件。

"usingComponents":{
	"van-button":"@vant/weapp/button/index"
}
<van-button type="primary">按钮van-button>

定制全局主题样式

使用css变量来实现定制主题。
声明自定义属性,属性名前需要加两个减号--,属性值可以使任意的css值。

/*在根伪类下定义变量,就可以在html文档的任何地方引用了,或者html{}中定义*/
:root{
	--my-define-color:brown;
	--my-define-width:10px;
}
p{
	background-color:var(--my-define-color);
	width:var(--my-define-width,5px);
	/*,5px表示不确定--my-define-width是否存在,如果不存在,则按照5px来设置width*/
}

在小程序中,app.wxss文件里,写入css变量,即可对全局生效:

page{
	--button-danger-background-color:#efef00;
	--button-danger-border-color:#efef00;
}

小程序的根节点为page,所以定义到page下。
可在官网的定制主题里查找对应的css变量名称。

API Promise化

基于回调函数的异步API,容易造成回调地狱。
API Promise化,就是通过额外的配置,将官方的API改造成promise的异步api。

实现

依赖第三方npm包,miniprogram-api-promise。
安装:npm install --save [email protected]
小程序安装新的npm包后,需要进行构建,防止出错,可以将miniprogram_npm文件夹删除。

在小程序入口文件app.js中,调用一次 promiseifyAll() 方法,即可实现 Promise 化。

import { promisifyAll } from 'miniprogram-api-promise'

const wxp = wx.p = {}
promisifyAll(wx, wxp)

使用Promise化的API

页面js

async getInfo(){
	const { data:res } = await wx.p.request({
		method:'GET',
		url:'https://www.escook.cn/api/get',
		data:{name:'zs',age:30}
	})
	console.log(res)
}

全局数据共享

全局数据共享(又叫状态管理),是为了解决组件之间数据共享的问题。
常用的数据共享方案有:vuex,redux,MobX等。

小程序中的全局共享

使用mobx-miniprogram配合mobx-miniprogram-bindings实现全局数据共享。

  1. mobx-miniprogram用来创建Store实例对象
  2. mobx-miniprogram-bindings用来把Store中的共享数据或方法,绑定到组件或页面中使用

安装MobX

npm install --save [email protected] [email protected]
安装完毕后, 需要删除 miniprogram_npm 后,重新工具→构建 npm

创建 MobX

根目录下创建store文件夹,下创建store.js,用来存储数据

import { observable, action } from 'mobx-miniprogram'

export const store = observable({
	//存放共享数据
	//数据字段
	numA:1,
	numB:2,
	//计算属性,方法名 前 增加 get
	get sum(){
		return this.numA + this.numB
	}
	//actions 方法,用来修改 store 中的数据,只能通过actions修改,不可直接改
	updateNum1:action(function(step){
		this.numA += step
	}),
	updateNum2:action(function(step){
		this.numB += step
	})
})

页面使用

页面js文件

import { createStoreBindings } from 'mobx-miniprogram-bindings'
//导入实例对象,store文件夹中的store.js
import { store } from '../../store/store'

Page({
	onload:function(){
		//将当前页面与数据绑定
		this.storeBindings = createStoreBindings(this, {
			store,//绑定的数据源
			fields:['numA','numB','sum'],//数据、属性字段
			actions:['updateNum1']//导入的方法
		})
	},
	onUnload:function(){
		this.storeBindings.destroyStoreBindings()
	},
	handle1(e){//按钮处理函数
		this.updateNum1(e.target.dataset.step)
	}
})

页面wxml

<view>{{numA}} + {{numB}} = {{sum}}view>
<van-button type="primary" bindtap="handle" data-step="{{1}}">
	numA + 1
van-button>
<van-button type="danger" bindtap="handle" data-step="{{-1}}">
	numA - 1
van-button>

组件中使用

将store中的成员绑定到组件中
组件js文件

import { storeBindingsBehavior } from 'mobx-miniprogram-bindings'
//导入实例对象,store文件夹中的store.js
import { store } from '../../store/store'

Component({
	behaviors:[ storeBindingsBehavior ],//通过 storeBindingsBehavior  实现自动绑定
	storeBindings:{
		store,//指定要绑定的 store
		fields:{//指定要绑定的字段数据
			numA:()=>store.numA,//绑定字段的方式1
			numB:(store)=>store.numB,//绑定字段的方式2
			sum:'sum'//绑定字段的方式3
		},
		actions:{//绑定方法
			updateNum2:'updateNum2'
		}
	},
	methods:{
		handle(e){
			this.updateNum2(e.target.dataset.step)
		}
	}
})
<view>{{numA}} + {{numB}} = {{sum}}view>
<van-button type="primary" bindtap="handle" data-step="{{1}}">
	numB + 1
van-button>
<van-button type="danger" bindtap="handle" data-step="{{-1}}">
	numB - 1
van-button>

分包

分包指的是把一个完整的小程序项目,按照需求划分为不同的子包,在构建时打包成不同的分包,用户在使用时按需进行加载。

  1. 首次启动时缩短下载时间
  2. 协同开发

分包后,小程序项目有1个主包 + 多个分包组成

  • 主包:一般只包含项目的启动页面或tabBar页面、以及所有分包需要的一些公共资源
  • 分包:只包含和当前分包相关的页面和私有资源

分包的加载规则:

  1. 小程序启动时,默认会下载主包并启动主包内页面:
    tabBar 页面需要放在主包中
  2. 当用户进入分包内某个页面时,客户端会把对应分包下载下来,下载完成后再进行展示
    非tabBar页面可以按照功能的不同,划分为不同的分包之后,进行按需下载。

体积限制:

  1. 整个小程序的所有分包大小不超过16M
  2. 单个分包、主包大小不能超过2M

分包的使用需要在app.json 的 subpackages 节点中声明分包的结构:
微信小程序学习笔记_第3张图片

{
"pages":[//主包的所有页面
	"pages/index",
	"pages/logs"
]
"subpackages":[//通过subpackages 节点,声明分包结构
	{
		"root":"packageA",//第一个分包根目录
		"pages":[//当前分包下,所有的页面的相对存放路径
			"pages/cat",
			"pages/dog"
		]
	},
	{
		"root":"packageB",//第二个分包的根目录
		"name":"pack",//分包的别名
		"pages":[//当前分包下,所有的页面的相对存放路径
			"pages/apple",
			"pages/banana"
		]
	}
]
}

创建分包:
可以在app.json中,直接完善subpackages节点,保存后,开发者工具会自动生成对应的文件。

查看分包大小:
开发工具右上角,详情,基本信息下方展开 本地代码 查看
微信小程序学习笔记_第4张图片
打包规则:

  1. 小程序会按 subpackages 的配置进行分包, subpackages 之外的目录将会被打包到主包中
  2. 主包也可以有自己的pages,即最外层的pages字段
  3. tabBar 页面必须在主包内
  4. 分包之间不能互相嵌套

引用原则:

  • 主包无法引用分包内的私有资源
  • 分包之间不能相互引用私有资源
  • 分包可以引用主包内的公共资源

独立分包

独立分包本质也是分包,但是可以独立于主包和其他分包单独运行。
普通分包必须依赖主包运行。
独立分包可以在不下载主包的情况下,独立运行。独立分包可以不下载主包,提高启动速度。一个小程序中可以有多个独立分包。
微信小程序学习笔记_第5张图片
通过 independent 节点 声明当前分包为独立分包。

{
"pages":[//主包的所有页面
	"pages/index",
	"pages/logs"
]
"subpackages":[//通过subpackages 节点,声明分包结构
	{
		"root":"moduleA",//普通分包根目录
		"pages":[//当前分包下,所有的页面的相对存放路径
			"pages/cat",
			"pages/dog"
		]
	},
	{
		"root":"moduleB",//第二个分包的根目录
		"pages":[//当前分包下,所有的页面的相对存放路径
			"pages/apple",
			"pages/banana"
		],
		"independent":true//声明当前分包为独立分包
	}
]
}

独立分包的引用原则:
独立分包和普通分包、主包之间,相互隔绝,不能互相引用彼此的资源。

  1. 主包无法引用独立分包内的私有资源
  2. 独立分包之间,不能相互引用私有资源
  3. 独立分包和普通分包之间,不能相互引用私有资源
  4. 独立分包中不能引用主包内的公共资源

分包预下载
进入小程序的某个页面时,由框架自动预下载可能需要的分包,从而提升进入后续分包页面的速度。
配置分包预下载配置(preloadRule):

//app.json
{
	"preloadRule":{//分包预下载的规则
		"pages/contact/contact":{//触发分包预下载的页面路径
			// network 表示在指定网络模式下进行预下载
			//可选值:all(不限网络)和wifi(进wifi模式下进行预下载)
			// 默认值: wifi
			"network":"all",
			// packages 表示进入页面后,预下载哪些分包
			// 可以通过root 或者 name 指定预下载哪些分包
			"packages":["pkgA"]
		}
	}
}

同一个分包中的页面享有共同的预下载大小限额2M。

案例

自定义tabBar

  1. app.json tabBar节点增加 custom:true;表示使用自定义tabBar。
  2. 新建名为custom-tab-bar的文件夹,必须为此名称;下面增加名为index的组件,必须叫index:右键,新建component,index。
  3. 基于vant组件,完善index.wxml。app.json引入组件。
  4. 使用自定义的tabbar图标和文本,从data中的list使用数据
  5. 循环渲染tabbar的item项
  6. 通过css变量修改tabbar图标的margin-bottom值
  7. 使用list中info的值渲染徽标数字
  8. 将全局数据中的num监听,同步到data的info中
  9. 使用全局数据中的active控制页面切换记录
    10.修改tabbar文字的颜色

app.json

{
    "pages": [
        "pages/list/list",
        "pages/message/message",
        "pages/info/info"
    ],
    "window": {
        "backgroundTextStyle": "light",
        "navigationBarBackgroundColor": "#D8322E",
        "navigationBarTitleText": "小微祝福",
        "navigationBarTextStyle": "white"
    },
    "tabBar": {
        "custom": true,
        "list": [{
            "pagePath": "pages/list/list",
            "text": "列表",
            "iconPath": "image/ln.png",
            "selectedIconPath": "image/la.png"
        },{
            "pagePath": "pages/message/message",
            "text": "消息",
            "iconPath": "image/mn.png",
            "selectedIconPath": "image/ma.png"
        },{
            "pagePath": "pages/info/info",
            "text": "我的",
            "iconPath": "image/in.png",
            "selectedIconPath": "image/ia.png"
        }]
    },
    "style": "v2",
    "sitemapLocation": "sitemap.json",
    "usingComponents":{
        "van-button":"@vant/weapp/button/index",
        "van-tabbar":"@vant/weapp/tabbar/index",
        "van-tabbar-item":"@vant/weapp/tabbar-item/index"
    }
}

store.js

import { observable, action } from 'mobx-miniprogram'

export const store = observable({
    num:7,
    active:0,
    setActive:action(function(newValue){
        this.active = newValue
    })
})

index.html

index.wxml
<van-tabbar active="{{ active }}" bind:change="onChange" active-color="#990101">
  <van-tabbar-item wx:for="{{list}}" wx:key="index" info="{{item.info ? item.info : ''}}" >
    <image slot="icon" src="{{item.iconPath}}" mode="aspectFit" style="width: 30px;height:18px;" />
    <image slot="icon-active" src="{{item.selectedIconPath}}" mode="aspectFit" style="width: 30px;height:18px;" />
    {{item.text}}
  van-tabbar-item>
van-tabbar>

index.js

// custom-tab-bar/index.js
import {storeBindingsBehavior} from 'mobx-miniprogram-bindings'
import {store} from '../store/store'
Component({
    options:{//进行样式覆盖需要设置
        styleIsolation:'shared'
    },
    observers:{
        'num':function(val){
            this.setData({
                'list[1].info':val
            })
        }
    },
    behaviors:[storeBindingsBehavior],
    storeBindings:{
        store,
        fields:{
            num:'num',
            active:'active'
        },
        actions:{
            setActive:'setActive'
        }
    },
    /**
     * 组件的初始数据
     */
    data: {
        "list": [{
            "pagePath": "/pages/list/list",
            "text": "列表",
            "iconPath": "/image/ln.png",
            "selectedIconPath": "/image/la.png"
        },{
            "pagePath": "/pages/message/message",
            "text": "消息",
            "iconPath": "/image/mn.png",
            "selectedIconPath": "/image/ma.png",
            info:2
        },{
            "pagePath": "/pages/info/info",
            "text": "我的",
            "iconPath": "/image/in.png",
            "selectedIconPath": "/image/ia.png"
        }]
    },

    /**
     * 组件的方法列表
     */
    methods: {
        onChange(event){
            this.setActive(event.detail)
            console.log(this.data.list[event.detail].pagePath)
            wx.switchTab({
              url: this.data.list[event.detail].pagePath,
            })
        }
    }
})

index.css

/* custom-tab-bar/index.wxss */
.van-tabbar-item{
    --tabbar-item-margin-bottom:0;
}

常见错误

渲染层错误ReferenceError: __g is not defined

删除app.json中的 “lazyCodeLoading”: “requiredComponents”

你可能感兴趣的:(微信小程序,微信小程序,小程序,前端)