微信小程序有自己开发框架,并且和我们熟悉的vue或者react框架的语法,api区别还是蛮大的,学习成本不低,个人不推荐花太多时间去学习,更推荐uni-app(使用vue的语法开发web应用并多端发布)这类的框架,使用我们熟悉的框架语法开发,还能轻松实现多端发布。当然,wx小程序的知识中也有许多是通用的。

说说你对微信小程序的理解?优缺点?

是什么

2017年,微信正式推出了小程序,允许外部开发者在微信内部运行自己的代码,开展业务

截至目前,小程序已经成为国内前端的一个重要业务,跟 Web 和手机 App 有着同等的重要性

小程序是一种不需要下载安装即可使用的应用(但实际上还是存在一个轻量级的下载和安装流程,不过用户感知不到),它实现了应用“触手可及”的梦想,用户扫一扫或者搜一下即可打开应用

也体现了“用完即走”的理念,用户不用关心是否安装太多应用的问题。应用将无处不在,随时可用,但又无需安装卸载

注意的是,除了微信小程序,还有百度小程序、微信小程序、支付宝小程序、抖音小程序,都是每个平台自己开发的,都是有针对性平台的应用程序

背景

小程序并非凭空冒出来的⼀个概念,当微信中的 WebView 逐渐成为移动 Web的⼀个重要⼊⼝时,微信就有相关的 JS-SDK

JS-SDK 解决了移动网页能⼒不⾜的问题,通过暴露微信的接⼝使得 Web 开发者能够拥有更多的能⼒,然而在更多的能⼒之外,JS-SDK的模式并没有解决使⽤移动网页遇到的体验不良的问题

因此需要设计⼀个比较好的系统,使得所有开发者在微信中都能获得⽐较好的体验:

  • 快速的加载
  • 更强⼤的能⼒
  • 原⽣的体验
  • 易⽤且安全的微信数据开放
  • 高效和简单的开发

这些是JS-SDK做不到的,需要设计一个全新的小程序系统

其中相比H5,小程序与其的区别有如下:

  • 运⾏环境:⼩程序基于浏览器内核重构的内置解析器
  • 系统权限:⼩程序能获得更多的系统权限,如⽹络通信状态、数据缓存能⼒等
  • 渲染机制:⼩程序的逻辑层渲染层是分开的

微信小程序可以视为只能用微信打开和浏览的H5,小程序和网页的技术模型是一样的,用到的 JavaScript 语言和 CSS 样式也是一样的,只是网页的 HTML 标签被稍微修改成了 WXML 标签

因此可以说,小程序页面本质上就是网页

其中关于微信小程序的实现原理,我们在后面的文章讲到

优缺点

优点:

  • 随搜随用,用完即走:使得小程序可以代替许多APP,或是做APP的整体嫁接,或是作为阉割版功能的承载体
  • 流量大,易接受:小程序借助自身平台更加容易引入更多的流量
  • 安全
  • 开发门槛低
  • 降低兼容性限制

缺点:

  • 用户留存:及相关数据显示,小程序的平均次日留存在13%左右,但是双周留存骤降到仅有1%
  • 体积限制:微信小程序只有2M的大小,这样导致无法开发大型一些的小程序
  • 受控微信:比起APP,尤其是安卓版的高自由度,小程序要面对很多来自微信的限制,从功能接口,甚至到类别内容,都要接受微信的管控

说说微信小程序的实现原理?

背景

网页开发,渲染线程和脚本是互斥的,这也是为什么长时间的脚本运行可能会导致页面失去响应的原因,本质就是我们常说的 JS 是单线程的

而在小程序中,选择了 Hybrid 的渲染方式,将视图层逻辑层分开的,双线程同时运行,视图层的界面使用 WebView 进行渲染,逻辑层运行在 JSCore

  • 渲染层

    使用 WXML 和 WXSS 编写,类似于 HTML 和 CSS。

    负责界面展示,包括布局、样式等。

    实际上是通过 WebView解析渲染的,但在微信小程序中进行了优化,以提供接近原生应用的性能。

    界面渲染相关的任务全都在WebView线程里执行。一个小程序存在多个界面,所以渲染层存在多个 WebView 线程

  • 逻辑层

    主要使用 JavaScript 编写。

    负责处理业务逻辑、数据获取、API 请求等,其中网络请求由微信客户端进行转发

    运行在一个基于 V8 或者 JSCore 的 JavaScript 引擎之上(视操作系统而定)

  • Native

    Native 层指的是微信客户端本身的原生代码,它负责:

    • 提供基础库,包含所有可用的 API
    • 处理逻辑层和渲染层之间的高效通信。
    • 实现性能优化,确保小程序能够流畅运行。
    • 提供安全机制,保护用户数据和隐私。

WebView 是什么

WebView 是一个允许在应用程序内部展示网页内容的组件,它依赖于特定平台上的浏览器内核来工作

在不同的平台上有不同实现:

  • Android:使用 android.webkit.WebView
  • iOS:使用 WKWebView(较新的推荐使用方式)或 UIWebView(已废弃)。

相当于 Web 开发中的 浏览器渲染引擎,也就是浏览器的内核,关于浏览器的介绍可以参考:前端面试—网络 | 三叶的博客

通信

逻辑层和渲染层之间的通信,是通过微信客户端(Native,或者说是宿主环境)提供的 API 实现的,比如逻辑层可以通过 setData 方法将数据传递给渲染层,触发页面更新:

1
2
3
this.setData({
message: 'Hello, World!'
});

在逻辑层发生数据变更的时候,通过宿主环境(native)提供的setData方法把数据从逻辑层传递到渲染层,再经过对比前后差异,把差异应用在原来的Dom树上(小程序在渲染层,宿主环境会把wxml转化成对应的JS对象,类似web开发中的dom对象),渲染出正确的视图

当视图存在交互的时候,例如用户点击你界面上某个按钮,这类反馈应该通知给开发者的逻辑层,需要将对应的处理状态呈现给用户

对于事件的分发处理,微信进行了特殊的处理,将所有的事件拦截后,丢到逻辑层交给JavaScript进行处理

由于小程序是基于双线程的,也就是任何在视图层逻辑层之间的数据传递都是线程间的通信,会有一定的延时,因此在小程序中,页面更新成了异步操作

异步会使得各部分的运行时序变得复杂一些,比如在渲染首屏的时候,逻辑层渲染层会同时开始初始化工作,但是渲染层需要有逻辑层的数据才能把界面渲染出来

如果渲染层初始化工作较快完成,就要等逻辑层的指令才能进行下一步工作

因此逻辑层与渲染层需要有一定的机制保证时序正确(异步同步化),在每个小程序页面的生命周期中,存在着若干次页面数据通信。

运行机制

小程序启动运行两种情况

  • 冷启动(重新开始):用户首次打开或者小程序被微信主动销毁后再次打开的情况,此时小程序需要重新加载启动,即为冷启动。
  • 热启动:用户已经打开过小程序,然后在一定时间内再次打开该小程序,此时无需重新启动,只需要将后台态的小程序切换到前台,这个过程就是热启动。

初次启动过程

1.把小程序的代码包下载到本地

2.解析app.json全局配置文件

3.执行app.js 小程序入口文件,调用App()创建小程序实例

4.渲染小程序首页(app.json 文件中的 pages 数组的第一个页面路径)

5.加载解析页面的.json配置文件

6.加载页面的.wxml模板和.wxss样式

7.执行页面的.js 文件,调用Page()创建页面实例,页面渲染完成

8.小程序启动完成

注意:

1.小程序没有重启的概念
2.当小程序进入后台,客户端会维持一段时间的运行状态,超过一定时间后会被微信主动销毁
3.短时间内收到系统两次以上内存警告,也会对小程序进行销毁,这也就为什么一旦页面内存溢出,页面会奔溃的本质原因了

每次冷启动时,都会检查是否有更新版本,如果发现有新版本,将会异步下载新版本的代码包,并同时使用客户端本地的包(缓存中的包)进行启动,即新版本的小程序需要等下一次冷启动才会应用上。

快速开始

注册账号

前往微信公众平台:https://mp.weixin.qq.com/

下载微信开发者工具

https://developers.weixin.qq.com/miniprogram/dev/devtools/stable.html

创建第一个项目

使用js基础模板

使用技巧

  • 查看效果
    • 编译->模拟
    • 打开模拟器后底部可以看到页面路径
    • 手机预览
  • 帮助->开发者文档
  • 详情
    • 查看小程序信息
    • 本地设置

项目结构概述

  • pages

    用来存放所有小程序的页面,每个页面以单独的文件夹存在
    其中,每个页面由4个基本文件组成

    • .js文件(页面的脚本文件,存放页面的数据、事件处理函数等)
    • .json 文件(当前页面的配置文件,配置窗口的外观、表现等)
    • .wxml文件(页面的模板结构文件)
    • .wxss文件(当前页面的样式表文件)
  • utils

    用来存放工具性质的模块(例如:格式化时间的自定义模块)

  • app.js

    小程序项目的入口文件

  • app.json

    小程序项目的全局配置文件

  • app.wxss

    小程序项目的全局样式文件

  • project.config.json

    项目的配置文件

  • sitemap.json

    站点地图,用来配置小程序及其页面是否允许被微信索引

JSON文件总结

app.json

是当前小程序的全局配置,包括了小程序的所有页面路径窗口外观界面表现底部 tab等。

1
2
3
4
5
6
7
8
9
10
11
12
13
{
//放页面路径
"pages": [
],
"window": {
},
"tabBar": {
},
//全局注册的组件
"usingComponents": {},
//指定分包
"subPackages":[]
}

只需要在 app.json-> pages中新增页面的存放路径,小程序开发者工具即可帮我们自动创建对应的页面文件

只需要调整app.json-> pages字符串数组中页面路径的前后顺序,即可修改项目的首页。小程序会把排在第一位的页面,当作项目首页进行渲染。

window

1
2
3
4
5
6
7
8
9
10
//app.json
{
....
"window": {
"navigationBarTextStyle": "black",
"navigationBarBackgroundColor": "#fff",
"backgroundColor": "#F8F8F8"
}
....
}
  • navigationBar系列(导航栏)

    • navigationBarTitleText:修改导航栏的标题
    • navigationBarBackgroundColor:修改导航栏的背景色,只支持16进制颜色,不能设置为red,blue等
    • navigationBarTextStyle:设置标题颜色,可选值只能是black和white(为什么这里又能直接写颜色了?)
  • background系列(下拉页面才会显示的部分的背景配置)

    • backgroundColor:指定16进制的颜色值比如#efefef。
    • backgroundTextStyle:只支持dark和light
  • onReachBottomDistance

    默认为50px,当滚动条距离底部50px的时候触发触底刷新

  • enablePullDownRefresh

    设置为true,表示允许下拉刷新

tabBar

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//app.json
{
....
"tabBar": {
"selectedColor": "#28b389",
"list": [
{
"pagePath": "pages/home/home",
"iconPath": "static/home.png",
"selectedIconPath": "static/home-h.png",
"text": "推荐"
},
{
"pagePath": "pages/classify/classify",
"iconPath": "static/classify.png",
"selectedIconPath": "static/classify-h.png",
"text": "分类"
},
{
"pagePath": "pages/user/user",
"iconPath": "static/user.png",
"selectedIconPath": "static/user-h.png",
"text": "我的"
}
]
}
....
}
  • selectedlconPath:选中时显示的图标路径
  • iconPath:未选中时显示的图标路径
  • color:tab上文字的默认(未选中)颜色
  • selectedColor: tab 上的文字选中时的颜色
  • pagePath:tab对应的页面路径,点击tab会跳转到指定页面。

注意

tabBar中只能配置最少2个、最多5个tab页签(list数组里的元素数目等于tab数目)

当渲染顶部 tabBar时,不显示 icon,只显示文本

页面的json文件

1
2
3
4
5
6
7
8
9
10
11
{
"navigationBarTitleText": "分类",
"navigationStyle": "custom",
"enablePullDownRefresh": true,
//局部组件注册
"usingComponents": {
"nav-bar": "../../components/nav-bar/nav-bar",
"theme-item": "../../components/theme-item/theme-item",
"uni-load-more": "../../uni_modules/uni-load-more/components/uni-load-more/uni-load-more"
}
}

页面的json文件中的属性,就是全局配置(app.json)中window的配置属性。

小程序中的每一个页面,可以使用json文件来对本页面的窗口外观进行配置,页面中的配置项会覆盖app.json的 window属性中相同的配置项。

project.config.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
{
"description": "项目配置文件。",
"packOptions": {
"ignore": [],
"include": []
},
"setting": {
"urlCheck": false,
"es6": true,
"postcss": false,
"minified": true,
"newFeature": true,
"bigPackageSizeSupport": true,
"babelSetting": {
"ignore": [],
"disablePlugins": [],
"outputPath": ""
}
},
"compileType": "miniprogram",
"libVersion": "3.5.5",
"appid": "xyz",
"projectname": "4meinv"
}

是项目配置文件,用来记录我们对小程序开发工具所做的个性化配置,

setting中保存了编译相关的配置

projectname中保存的是项目名称,项目名称不等于小程序名称

appid中保存的是小程序的账号ID

sitemap.json

站点地图,微信现已开放小程序内搜索,效果类似于PC网页的SEO(搜索引擎优化)。该文件用来配置小程序页面是否允许微信索引。

js文件总结

app.js

是整个小程序项目的入口文件,通过调用App()函数来启动整个小程序

1
createApp().app.mount("#app");

页面的.js 文件

是页面的入口文件,页面的脚本文件,存放页面的数据、事件处理函数等

通过调用Page()函数来创建并运行页面

1
wx.createPage(MiniProgramPage);

api

wx对象在浏览器中就相当于window

事件监听

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

1
wx.onWindowResize(function callback)//监听窗口尺寸变化的事件

同步api

Sync结尾的API都是同步API

同步API的执行结果,可以通过函数返回值直接获取,如果执行出错会抛出异常

1
wx.setStorageSync('key','value')//向本地存储中写入内容

异步api

类似于jQuery 中的$.ajax(options)函数,需要通过success、fail、complete回调函数接收调用的结果

1
wx.request()//发起网络数据请求,通过success回调函数接收数据

基础语法

事件

  • tap

    手指触摸后马上离开,类似于HTML中的click 事件

    绑定方式:bindtap 或 bind:tap

    1
    2
    3
    <view class="container">
    <button bindtap="handleTap">点击我</button>
    </view>
    1
    2
    3
    4
    5
    6
    Page({
    handleTap(e) {
    console.log('按钮被点击了');
    // 可以在这里执行其他逻辑,如发起网络请求或更新页面状态
    }
    });
  • input

    文本框输入事件

    绑定方式:bindinput或 bind:input

    通过e.detail.value获得最新输入的值,不同于js的e.target.value

    1
    2
    3
    <view class="container">
    <input type="text" placeholder="输入内容" bindinput="handleInput" />
    </view>
    1
    2
    3
    4
    5
    6
    7
    Page({
    handleInput(e) {
    const inputValue = e.detail.value;
    console.log('当前输入值:', inputValue);
    // 更新页面状态或其他操作
    }
    });
  • change

    状态改变时触发,绑定方式同上

    1
    2
    3
    <view class="container">
    <switch bindchange="handleChange" />
    </view>
    1
    2
    3
    4
    5
    6
    7
    Page({
    handleChange(e) {
    const isChecked = e.detail.value;
    console.log('开关状态改变为:', isChecked ? '开启' : '关闭');
    // 根据开关状态执行相应逻辑
    }
    });

事件对象

js中的事件对象相同,e.target表示目标对象,即触发该事件的对象;e.currentTarget表示事件流经过的当前对象;e.type表示事件类型。

数据绑定

页面数据写在js文件中

1
2
3
4
5
Page({
data: {
info: 'init data'
}
})

wxml文件中使用:

1
2
<image src="{{imgSrc}} "></image>
<view>{{info}}</view>

在wxml文件中使用js中的数据一定要加{{}}

条件渲染

wx:if/wx:elif/wx:else

block组件

类似vue中的template

hidden

类似vue中的v-show,不一样的是这里值为true的话是隐藏,v-show是显示

列表渲染

  • wx:for:传入一个数组

  • wx:for-item:可以指定当前项的变量名

  • wx:for-index:可以指定当前循环项的索引的变量名

  • wx:key

    类似vue中的key,如果数组item中有id属性,直接令wx:key=’id’即可,不需要写成{{item.id}},否则会报错(真是奇怪)

示例

1
2
3
<view wx:for="{{arr}}">
索引是: {{index}}, item项是:{{item}}
</view>
1
2
3
<view wx:for="{{arr1}}" wx:for-index="idx" wx:for-item="itemName" wx:key="idx">
索引是: {{idx}}, item项是: {{itemName}}
</view>

wxml与html的区别

标签名称不同

1
2
HTML ( div, span, img, a)
wxml (view, text, image, navigator)

属性节点不同

1
2
<a href="#">超链接</a>
<navigator url="/pages/home/home"></navigator>

wxss与css的区别

  • 新增了rpx尺寸单位

    CSS中需要手动进行像素单位换算,例如rem,wxss在底层支持新的尺寸单位rpx,在不同大小的屏幕上小程序会自动进行换算。

    鉴于不同设备屏幕的大小不同,为了实现屏幕的自动适配,rpx把所有设备的屏幕,在宽度上等分为750份(即:当前屏幕的总宽度为750rpx)。小程序在不同设备上运行的时候,会自动把 rpx的样式单位换算成对应的像素单位(px)来渲染,从而实现屏幕适配。

  • wxss仅支持部分CSS选择器

  • 提供了全局的样式和局部样式

    项目根目录中的app.wxss会作用于所有小程序页面,而页面的wxss样式仅对当前页面生效。

wxs与js的区别

  • 只支持js的部分语法,不支持es6语法
  • 声明变量只能用var,没有const,let
  • 不能写箭头表达式
  • 对象键值名称相同不能省略
  • wxs不能调用js 中定义的函数
  • wxs不能调用小程序提供的API

说白了wx小程序上运行的js代码是阉割版的…

特点

  • wxs 代码可以编写在wxml文件中的<wxs>标签内,就像Javascript 代码可以编写在 html文件中的<script>标签内一样。
  • wxml文件中的每个<wxs></wxs>标签,必须提供 module属性,用来指定当前wxs 的模块名称,方便在wxml中访问模块中的成员
  • wxs代码还可以编写在以.wxs为后缀名的文件内,就像javascript代码可以编写在以.js为后缀名的文件中一样。
  • 在wxml中引入外联的 wxs脚本时,必须为<wxs>标签添加module和src属性,module用来指定模块的名称src,用来指定要引入的脚本的路径,且必须是相对路径

组件

视图组件

  • view

    普通视图区域,类似于HTML中的div,是一个块级元素常用来实现页面的布局效果

  • scroll-view

    可滚动的视图区域,常用来实现滚动列表效果;添加scroll-y属性,允许y轴滚动。

  • swiper和swiper-item

    轮播图组件,常用属性:

    • indicator-dots:添加导航条,默认值false
    • indicator-color:指示点颜色
    • indicator-active-color:当前选中的指示点颜色
    • autoplay:是否自动切换,默认为false
    • interval:自动切换时间间隔(单位ms)
    • circular:是否采用衔接滑动,默认为false
  • text

    添加了selectable属性才能实现长按选择复制等操作

  • rich-text

    通过rich-text组件的nodes属性节点,把HTML字符串渲染为对应的结构,就像vue里的v-html

    这段代码会将 <h1> 元素的内容渲染到 <rich-text> 组件内部,而不是替换整个 <rich-text> 标签

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

其他组件

  • button

    功能比HTML中的button 按钮丰富

    属性:

    • type:指定按钮的类型,颜色,有点像前端框架里的语法了
    • size:指定按钮的大小
    • plain:添加了就具有镂空样式
    • open-type:通过这个属性可以调用微信提供的各种功能(客服、转发、获取用户授权、获取用户信息等)
  • image

    组片组件,有默认宽高

    mode属性(前3个修改图片大小,后2个修改image容器大小)

    • scaleToFill:(默认值)缩放模式,不保持纵横比缩放图片,使图片的宽高完全拉伸至填满image元素。没有空隙,没有裁剪,但是会失真)
    • aspectFit:缩放模式,保持纵横比缩放图片,使图片的长边能完全显示出来。也就是说,可以完整地将图片显示出来。(就是contain)。没有裁剪,没有失真,但是可能有空隙。
    • aspectFill:缩放模式,保持纵横比缩放图片,只保证图片的短边能完全显示出来。也就是说图片通常只在水平或垂直方向是完整的,另一个方向将会发生截取。(就是cover)。有裁剪,但是没有失真,没有空隙。
    • widthFix:缩放模式,容器的宽度不变,高度自动变化,保持原图宽高比不变
    • heightFix:缩放模式,容器的高度不变,宽度自动变化,保持原图宽高比不变

    与img区别

    微信中的image更像一个容器,src指定的图片是背景图片,前3个属性值在修改背景图片大小,后2个属性在修改容器的大小。

    img的大小就是src指定的图片的大小。

数据请求

安全限制

只能请求HTTPS类型的接口

必须将接口的域名添加到信任列表中

配置request合法域名

登录微信小程序管理后台→开发→开发设置→服务器域名→修改request合法域名。

跳过域名检查

只能在开发阶段使用,步骤:详情->本地设置->不校验…

发请求

1
2
3
4
5
6
7
8
9
10
11
 wx.request({
url: ' https://applet-base-api-t.itheima.net/api/get',
method:'GET',
data:{
name:'tom',
age:20
},
success(res){
console.log(res.data)
}//请求成功后的回调函数
})

注意事项

  • 跨域问题
    跨域问题只存在于基于浏览器的Web开发中。由于小程序的宿主环境不是浏览器而是微信客户端,所以小程序中不存在跨域的问题

  • ajax
    Ajax技术的核心是依赖于浏览器中的XMLHttpRequest这个对象,由于小程序的宿主环境是微信客户端,所以小程序中不能叫做发起Ajax请求,而是叫做发起网络数据请求

导航

声明式导航

  • 跳转到tabBar页面,需要指定open-type属性为switchTab

    1
    <navigator url=" /pages/message/message" open-type="switchTab">导航到消息页面</navigator>
  • 跳转到非tabBar页面:open-type必须为navigate,也可以省略不写

  • 后退导航:如果要后退到上一页面或多级页面,则需要指定open-type属性为navigateBack({delta:1}),delta表示后退层级

编程式导航

  • 跳转到tabBar页面
    使用wx.switchTab()方法,传入一个对象,必须包含url属性

  • 跳转到非tabBar页面

    使用wx.navigateTo()方法,传入一个对象,必须包含url属性

  • 后退导航

    wx.navigateBack(),传入{delta:1}指定后退层级

导航传参

声明式导航传参

1
<navigator url="/pages/infolinfo?name=zs&age=20">跳转到info页面</navigator>

接收参数

通过声明式导航传参或编程式导航传参所携带的参数,可以直接在onLoad事件中直接获取到

1
2
3
onUpload(options){
console.log(options)
}

下拉刷新 触底加载

下拉刷新

1
2
onPullDownRefresh//下拉事件触发后执行该函数
wx.stopPullDownRefresh()可以停止当前页面的下拉刷新

触底加载

通过onReachBottom()函数即可监听当前页面的触底事件

onReachBottomDistance的值默认为50px,当滚动条距离底部50px的时候认为已触底。

自定义编译模式

编译->添加编译模式,现在用热重载就好了,修改代码保存后不会切换到首页。

自定义组件

创建components文件夹,右键选择创建组件

引用

  • 局部
    页面的json文件的usingComponents属性中声明

  • 全局
    在app.json文件的usingComponents属性中声明,如果没有就自己添加

    1
    2
    3
    "usingComponents": {
    "count":"/components/test/test"
    }//count为组件在页面中的名称

    总结:引入组件在json文件中声明,区别于vue

组件和页面的区别

  • 组件的 .json文件中需要声明"component": true
  • 组件的.js文件中调用的是Component()函数,而页面调用的是Page()函数

样式单向隔离

默认情况下,自定义组件的样式只对当前组件生效,不会影响到组件之外的UI结构,但是可以被组件外的样式影响。
app.wxss中的部分全局样式对组件无效,只有class选择器会有样式隔离效果,id选择器、属性选择器、标签选择器不受样式隔离的影响。

自定义tabbar

app.jsontabBar字段中新增custom:true属性

在根目录新建custom-tab-bar文件,然后右键新建组件,开发工具就会把这个组件当作tabbar

注意

  • vant组件的样式是很容易被pages页面样式(主包资源)覆盖的,因为vant组件样式本身就不是隔绝的,主包的资源是可以共享的,包括样式

  • 每个 tab 页下的自定义 tabBar 组件实例是不同的,切换到哪个页面,tabbar组件相当于属于哪个页面的组件,会受到这个页面样式的影响

  • 也因为这点,在前一个组件页面修改active,通过导航切换到下一个页面后无效了,所以不能把active交给tabbar组件维护,最好交给仓库维护

分包

定义

分包指的是把一个完整的小程序项目按照需求划分为不同的子包,在构建时打包成不同的分包,用户在使用时按需进行加载,类似webpack中的代码分割。可以优化小程序首次启动的下载时间,在多团队共同开发时可以更好的解耦协作。

结构

  • 一个主包

    一般只包含项目的启动页面或TabBar页面、以及所有分包都需要用到的一些公共资源

  • 多个分包

    只包含和当前分包有关的页面私有资源

分包的加载规则

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

体积限制

整个小程序所有分包大小不超过16M(主包+所有分包),单个分包/主包大小不能超过2M

配置规则

  • 根目录下的pages一般放的是所有主包页面

  • 在根目录下新建subpkg文件(自定义名称),创建一个分包,内部可以有多个页面,就如同pages文件夹。

  • 还要在app.json文件里声明分包结构(类似vue中的路由)

    可以看到subPackages的值是一个数组,说明可以设置多个分包,一个分包对应一个单独的文件夹,内部可以有多个页面。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    {
    "subPackages": [
    {
    "root": "subpkg",
    "name":'pkgA',//分包别名
    //当前分包下所有页面的相对路径
    "pages": [
    "detail/detail",
    "goods_list/goods_list",
    "search/search"
    ]
    }
    ]
    }

打包原则

  • subpackages之外的目录将被打包到主包中
  • tabBar 页面必须在主包内
  • 分包之间不能互相嵌套

引用原则

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

独立分包

普通分包打开依赖于主包,独立分包可以不依赖主包打开,独立分包在配置的时候需要额外添加independent:true属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
"subPackages": [
{
"root": "subpkg",//指明是项目根目录下的subpkg文件
"name":'pkgA',//分包别名
//设置独立分包
"independent": true ,
//当前分包下所有页面的相对路径
"pages": [
"detail/detail",
"goods_list/goods_list",
"search/search"
]
}
]
}

开发者可以按需,将某些具有一定功能独立性的页面配置到独立分包中,而独立分包不依赖主包即可运行,可以很大程度上提升分包页面的启动速度

独立分包和普通分包以及主包之间,是相互隔绝的,不能相互引用彼此的资源,独立分包中不能引用主包内的公共资源

分包预下载

在进入小程序的某个页面时,由框架自动预下载可能需要的分包,从而提高进入后续分包的启动速度

在app.json中配置:

1
2
3
4
5
6
"preloadRule":{//分包预下载规则
"pages/contact/contact":{//触发分包预下载的页面路径
"network":"all",//表示在指定的网络模式下下载,默认为wifi
"packages":["pkgA"]//通过root或name指定预下载哪些分包
}
}

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

协同开发

小程序版本

上传代码,上传的代码为开发版本

提交审核,为审核版本

审核通过可以发布,为线上版本

小程序推广

登录小程序管理后台→设置->基本设置→基本信息小程序码→及线下物料下载

查看运营数据

在后台统计查看,或者使用小程序数据助手。