速通-微信小程序 5Day

这一部分需要结合视频观看,blog 不太容易去介绍😶‍🌫️😶‍🌫️😶‍🌫️

速通-微信小程序-CSDN博客

速通-微信小程序 2Day-CSDN博客

速通-微信小程序 3Day-CSDN博客

紧接前文,搭配有助于快速,巩固/学习!话不多说开始!

经过前面几篇的学习,好简单,最起码对于做过前端Vue 开发,小程序前后端 so so easy!

哦对了,顺便推荐一下之前的VUE学习blog,此篇有很多知识概念何Vue高度类似;

小程序 NPM

小程序已支持使用 npm 安装第三方包,开发者可以借助成熟的社区库快速实现功能,避免重复造轮子:

但受限于自身的运行环境,对 npm 包的使用存在明确限制:

小程序是运行在微信环境,并不是,浏览器环境;

不支持依赖 Node.js 内置库的包:

  • 例如依赖 fspathhttp 等 Node.js 内置模块的包,

  • 小程序的沙箱环境无法提供这些模块的实现,因此无法运行

不支持依赖 C++ 插件的包: 包含原生 C++ 插件包 如:部分加密、图像处理库,需要原生环境支持;

不支持依赖浏览器内置对象的包: 例如:依赖 windowdocumentnavigator 等浏览器专属对象的包;

Vant Weapp

Vant Weapp🔗 是有赞前端团队开源的小程序 UI 组件库

提供丰富的移动端组件:按钮、表单、弹窗 等...,可大幅提升小程序开发效率,采用 MIT 开源协议;

安装 Vant 组件库

尽量参考官方,随着时间和版本,问题不同环境存在差异!!!

步骤一 通过 npm 安装: 建议指定版本为@1.3.3

sh 复制代码
# 如果项目第一次使用npm 还需要进行构建 package.json
npm init -y
# 通过 npm 安装
npm i @vant/weapp@1.3.3 -S --production

yarn add @vant/weapp --production	# 通过 yarn 安装

npm i vant-weapp -S --production	# 安装 0.x 版本

步骤二:修改app.json

将 app.json 中的 "style": "v2" 去除,

小程序的 新版基础组件 强行加上了许多样式,难以覆盖,不关闭将造成部分组件样式混乱;

步骤三:构建 npm 包: 微信开发者工具 工具 -> 构建 npm 构建完成后,即可引入组件;

旧版本: 还需要在项目设置中开启:使用npm 模块新版本已经默认集成了配置;

引入|使用 Vant

安装完成后,通过 app.json全局引用usingComponents 节点引入组件,即可在页面中直接使用:

js 复制代码
{
  "usingComponents": {
    "van-button": "@vant/weapp/button/index"
  }
}

全局主题样式

Vant Weapp 全局主题定制 CSS 变量方式

Vant Weapp 通过 CSS 变量 自定义属性 实现全局主题定制,

开发者只需在 app.wxss 中重写这些变量,即可统一所有组件的样式风格;

关于使用 CSS 自定义属性变量🔗🔗 复杂的网站都会有大量的 CSS 代码,通常也会有许多重复的值;

  • 同样一个颜色值可能在成千上百个地方被使用到,如果这个值发生了变化,
  • 需要全局搜索并且一个一个替换很麻烦哎~,自定义属性在某个地方存储一个值,其他许多地方引用它;

Demo 案例:butten 如果程序需要,定制按钮的颜色可以在,全局:app.wxss 统一配置;

page 选择器下定义 CSS 变量 :所有在 page 下定义的变量会全局生效,覆盖 Vant 的默认值;

css 复制代码
/* app.wxss */
page {
  /* 定制警告按钮的背景颜色 */
  --button-danger-background-color: #c00073;
  /* 定制警告按钮的边框颜色 */
  --button-danger-border-color: #D60000;
}

Vant 组件内部大量使用 CSS 变量定义样式,开发者通过覆盖这些变量,

就能在不修改组件源码的情况下,实现全局主题风格的统一;

😶‍🌫️😶‍🌫️😶‍🌫️为什么是Page?为什么是这些配置??

在小程序中,所有页面的内容都被包裹在一个 <page> 标签内,这是小程序框架自动生成的 根容器

page 选择器下定义的 CSS 变量,会被所有子元素 Vant组件继承,从而实现 全局生效;

为什么是 --button-danger-background-color 这个属性值???

详情可以参考: vant-weapp/packages/common/style/var.less GitHub

这个变量名是 Vant Weapp 组件库 内部预定义的 CSS 变量,遵循了清晰的语义化命名规则;

API Promise

本篇涉及文档blog:前后端交互的弯弯绕绕_前后端怎么相互调用的-CSDN博客

小程序原生的异步 API(如 wx.request 网络请求)默认采用 回调函数 的方式实现,例如:

js 复制代码
wx.request({
  method: '',
  url: '',
  data: {},
  success: () => { /* 请求成功回调 */ },
  fail: () => { /* 请求失败回调 */ },
  complete: () => { /* 请求完成回调 */ }
})

多层嵌套会导致 回调地狱 Callback Hell ,代码层级深、可读性差;

错误处理和流程控制繁琐,代码维护成本高;

什么是 API Promise 化:

API Promise 化是指:通过工具或配置,将小程序官方提供的、

基于回调函数的异步 API,升级改造为基于 Promise 的异步 API

我们可以使用 async/await 语法来编写异步代码,告别回调地狱,大幅提升代码可读性可维护性;

NPM 实现 API Promise 化:

安装依赖: 在项目根目录执行 npm 命令,安装指定版本的包:别忘记,小程序工具-构建npm

sh 复制代码
npm install --save miniprogram-api-promise@1.0.4

在小程序入口文件 app.js中配置:

只需在 app.js 中调用一次 promisifyAll() 方法,即可完成所有异步 API 的 Promise 化:

js 复制代码
// 1. 导入 promisifyAll 方法
import { promisifyAll } from 'miniprogram-api-promise'
// 2. 定义挂载对象,将 Promise 化后的 API 挂载到 wx.p 上
const wxp = wx.p = {}
// 3. 执行 Promise 化,将 wx 上的所有异步 API 转换为 Promise 版本
promisifyAll(wx, wxp)

// app.js
App({ /** 小程序配置 */ })

配置完成后,所有小程序原生异步 API 都会在 wx.p 对象上提供对应的 Promise 版本

调用 Promise 化后的异步 API

xml 复制代码
<van-button type="danger" bindtap="getInfo">vant按钮</van-button>
js 复制代码
// 定义 async 函数,处理按钮点击事件
async getInfo() {
  // 使用 await 等待 Promise 化的 API 完成
  const { data: res } = await wx.p.request({
    method: 'GET',
    url: 'https://www.escook.cn/api/get',
    data: { name: 'zs', age: 20 }
  })

  // 打印请求结果
  console.log(res)
}

全局数据共享:

全局数据共享(状态管理)是为了解决 组件间数据共享 的问题,避免多层嵌套传递数据的繁琐;

核心目标解决 多个组件 / 页面共享同一份数据 ,并且,数据变化时,所有用到该数据地方能自动更新🆙

小程序Mobx 全局数据共享: 类似于 Vuex、Redux

  • 把 MobX 看作一个 全局数据仓库(Store),里面存着所有组件都需要用的公共数据;

  • 任何组件都可以 订阅 这个仓库里数据,当仓库里的数据变了,所有订阅了的组件会 自动更新

  • 同时,MobX 要求必须通过 指定方式 Action 修改仓库里的数据,保证数据变化可追踪、可调试;

MobX 全局数据共享

小程序中使用 MobX 实现全局数据共享,依赖两个 npm 包:

包名 作用
mobx-miniprogram 用于创建 Store 实例对象,封装全局共享的数据和方法
mobx-miniprogram-bindings 用于将 Store 中的数据和方法,绑定到页面或组件 中使用
sh 复制代码
npm install --save mobx-miniprogram@4.13.2 mobx-miniprogram-bindings@1.2.1

⚠️ 注意: 在小程序开发者工具中,点击「工具」→「构建 npm」,重新生成构建后的 npm 包;

集中管理:所有共享数据和修改逻辑都集中在 Store 中,便于维护

简化通信:彻底告别了组件间层层传递数据的繁琐,让代码更清晰

响应式更新:当 Store 中的数据发生变化时,所有绑定了该数据的页面和组件会自动更新视图。

创建 MobX Store 实例

在项目中新建 store/store.js 文件,编写如下代码:

Store 是全局数据的容器,我们需要创建一个 Store 实例来管理共享状态:

js 复制代码
// 从 mobx-miniprogram 中导入 observable 和 action
import { observable, action } from 'mobx-miniprogram'

// 使用 observable 创建 Store 实例
export const store = observable({
  // 1. 数据字段(需要共享的数据)
  numA: 1,
  numB: 2,
  // 2. 计算属性(getter,基于现有数据计算新值)
  get sum() { return this.numA + this.numB },
  // 3. actions 方法(修改 Store 中数据的唯一方式,必须用 action 包装)
  updateNum1: action(function (step) {
    this.numA += step
  }),
  updateNum2: action(function (step) {
    this.numB += step
  })
})

将 Store 绑定到页面

在页面中,我们需要将 Store 的数据和方法绑定到当前页面实例,以便在页面中直接使用:

页面 .wxml 使用: 在页面的 WXML 中,可以直接使用绑定的数据:

xml 复制代码
<view>{{numA}} + {{numB}} = {{sum}}</view>
<van-button type="primary" bindtap="btnHandler1" data-step="{{1}}">
  numA + 1
</van-button>

<van-button type="danger" bindtap="btnHandler1" data-step="{{-1}}">
  numA - 1
</van-button>

页面 .js 文件配置

js 复制代码
// 从 mobx-miniprogram-bindings 中导入 createStoreBindings
import { createStoreBindings } from 'mobx-miniprogram-bindings'
// 导入我们创建的 Store 实例
import { store } from '../../store/store'

Page({
  /*** 页面的初始数据 */
  data: {  },
  /* 生命周期函数--监听页面加载 */
  onLoad: function () {
    // 创建 Store 绑定
    this.storeBindings = createStoreBindings(this, {
      // 指定要绑定的 Store
      store,
      // 指定要绑定的数据字段(会自动映射到页面的 data 中)
      fields: ['numA', 'numB', 'sum'],
      // 指定要绑定的 actions 方法(会自动映射到页面的 this 上)
      actions: ['updateNum1']
    })
  },
  /* 生命周期函数--监听页面卸载 */
  onUnload: function () {
    // 页面卸载时,销毁 Store 绑定,避免内存泄漏
    this.storeBindings.destroyStoreBindings()
  },
  // 页面方法,调用绑定的 action
  btnHandler1(e) {
    this.updateNum1(e.target.dataset.step)
  }
})

将 Store 绑定到组件

在自定义组件中,我们通过 storeBindingsBehavior 来实现 Store 的自动绑定

组件 .wxml 使用: 在组件的 WXML 中,使用方式与页面完全一致:

xml 复制代码
<view>{{numA}} + {{numB}} = {{sum}}</view>

<van-button type="primary" bindtap="btnHandler2" data-step="{{1}}">
  numB + 1
</van-button>

<van-button type="danger" bindtap="btnHandler2" data-step="{{-1}}">
  numB - 1
</van-button>

组件 .js 文件配置

js 复制代码
// 从 mobx-miniprogram-bindings 中导入 storeBindingsBehavior
import { storeBindingsBehavior } from 'mobx-miniprogram-bindings'
// 导入我们创建的 Store 实例
import { store } from '../../store/store'

Component({
  // 在 behaviors 中引入 storeBindingsBehavior
  behaviors: [storeBindingsBehavior],

  // 配置 Store 绑定
  storeBindings: {
    // 指定要绑定的 Store
    store,
    // 指定要绑定的数据字段(三种绑定方式)
    fields: {
      // 方式1:箭头函数
      numA: () => store.numA,
      // 方式2:函数参数(参数为 Store 实例)
      numB: (store) => store.numB,
      // 方式3:字符串(直接指定 Store 中的字段名)
      sum: 'sum'
    },
    // 指定要绑定的 actions 方法
    actions: {
      updateNum2: 'updateNum2'
    }
  },

  /* 组件的方法列表 */
  methods: {
    btnHandler2(e) {
      // 调用绑定的 action 方法
      this.updateNum2(e.target.dataset.step)
    }
  }
})

小程序分包:

分包基础概念

分包是将一个 完整的小程序项目

按照业务需求划分为不同的子包,在构建时打包成独立的分包,

用户在使用时 按需进行加载 ,而非一次性下载全部代码,分包好处:👇

  • 优化首次启动速度 :小程序启动时只下载主包,大幅减少首次加载时间,提升用户体验

  • 团队协作解耦:在多团队共同开发时,不同业务模块可独立分包,降低代码耦合度,便于协作维护;

项目构成对比:

  • 分包前 所有页面和资源

    TabBar页、普通页、图片、脚本、样式等

    被打包在一起,导致项目体积过大,严重影响首次启动速度;

  • 分包后 :项目由 1 个主包 + 多个分包 组成:

    分包:只包含和当前分包业务相关的页面与私有资源,按需下载;

    主包 :仅包含项目的启动页面、TabBar 页面,以及所有分包都需要用到的 公共资源;

    加载规则:

  • 小程序启动时,默认只下载 主包 并启动主包内的页面,因此 TabBar 页面必须放在主包中

  • 当用户进入分包内的某个页面时,客户端才会下载对应的分包,下载完成后再展示页面;

  • 非 TabBar 页面可按功能划分到不同分包,实现按需加载;

体积限制: 整个小程序 主包 + 所有分包 的总大小不得超过 16M;

单个分包或主包的大小不得超过 2M;

小程序使用分包

app.json 中通过 subpackages 节点声明分包结构,示例如下:

  • root:分包的根目录,如 moduleA

  • pages:当前分包下所有页面的相对路径,

  • name:分包的别名可选,用于分包预下载等场景


小程序严格按照 subpackages 配置分包,subpackages 之外所有目录/文件,被打包到主包中:

TabBar 页面必须放在主包内,否则无法正常显示

主包可以有自己的页面,配置在最外层的 pages 字段中

分包之间不能互相嵌套,即一个分包的根目录不能是另一个分包的子目录;

引用原则:

  • 分包之间 不能相互引用 对方的私有资源。

  • 主包 无法引用 分包内的私有资源 如: 分包内的图片、脚本等

  • 分包 可以引用 主包内的公共资源 如: 主包的公共脚本、样式、图片等


和普通页面一样,在app.json 中配置对应目录,系统会自动创建出对应的文件目录;

小程序独立分包

独立分包本质上也是分包,但它是一种特殊的分包,

可以 独立于主包和其他分包而单独运行, 用户无需下载主包即可直接打开独立分包内的页面;

类型 运行依赖
普通分包 必须依赖主包才能运行,用户进入分包页面前需先下载主包
独立分包 可在不下载主包的情况下独立运行,大幅提升页面启动速度

应用场景: 适用于 功能独立性较强 页面,如:活动页、推广页、工具页 配置独立分包,原因:

  • 普通分包启动时需先下载主包,而独立分包可直接运行,显著提升启动速度。

  • 一个小程序中可以配置多个独立分包

配置方法:app.jsonsubpackages 节点中,通过添加 "independent": true 来声明独立分包:

js 复制代码
{
  "pages": [
    "pages/home/home",
    "pages/message/message",
    "pages/contact/contact"
  ],
  "subpackages":[
    {
      "root": "pkgA",
      "pages": [
        "pages/cat/cat",
        "pages/dog/dog"
      ]
    },
    {
      "root": "pkgB",
      "name": "pack2",
      "pages": [
        "pages/apple/apple",
        "pages/banana/banana"
      ],
      "independent": true 			// 声明为独立分包
    }
  ],
  "tabBar": { /*...*/ },
  "window": { /*...*/  },
}

⭐⭐引用原则 重要 独立分包与主包、普通分包之间是 相互隔绝 的,资源引用有严格限制:

  • 主包无法引用独立分包内的私有资源

  • 独立分包之间不能相互引用私有资源

  • 独立分包和普通分包之间不能相互引用私有资源

特别注意 :独立分包中 不能引用主包内的公共资源,需将依赖的资源打包到独立分包自身;

分包预下载:

分包预下载是指: 在进入小程序的某个页面时,由框架自动预下载可能需要的分包;

当用户后续进入这些分包页面时,无需再次下载,从而提升启动速度;

配置分包预下载:

app.json 中,通过 preloadRule 节点定义预下载规则:

js 复制代码
{
  "preloadRule": {
    "pages/contact/contact": { 	// 触发预下载的页面路径
      "network": "all",         // 网络模式:all(不限网络)或 wifi(仅WiFi,默认值)
      "packages": ["pkgA"]      // 预下载的分包,通过 root 或 name 指定
    }
  }
}
  • network:控制预下载网络环境,可选值为 all 不限网络wifi 仅在 WiFi 下预下载,默认值

  • packages:指定进入触发页面后,需要预下载分包,可通过分包 root \ name 字段来指定;

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

  • 预下载的分包总体积不得超过 2M,否则预下载会被框架拦截🧱🧱;

  • 例如:若从主包的 contact 页面预下载分包 A、B、C,则 A+B+C 的体积必须小于 2M;

相关文档

黑马---小程序简介_哔哩哔哩_bilibili 对应:Day5 天内容!

这一部分需要结合视频观看,blog 不太容易去介绍😶‍🌫️😶‍🌫️😶‍🌫️

相关推荐
hamish-wu1 小时前
告别idea,拥抱AI开发环境TRAE
java·ide·编辑器·intellij-idea·intellij idea·visual studio
她说..2 小时前
万字详解WebSocket的用法
java·网络·websocket·网络协议·springboot
一只酸奶牛^_^2 小时前
java实现pdf添加水印
java·pdf
不绝1912 小时前
延迟函数/协同程序
java·开发语言
摇滚侠2 小时前
登录认证,验证码实现逻辑
java·intellij-idea
老毛肚2 小时前
java juc 01 进程与线程
java·开发语言
1candobetter2 小时前
JAVA后端开发——反射机制在Spring业务开发中的实际应用
java·开发语言·spring
说私域2 小时前
数字围城下的防御与突围:基于私域流量与智能名片商城小程序的用户关系重构研究
小程序·重构·流量运营·私域运营