2021版小程序开发4——基础加强

news2025/1/31 7:19:55

2021版小程序开发4——基础加强

学习笔记 2025

  • 自定义组件
  • 组件中behaviors的作用
  • 安装和使用vant-weapp组件库
  • 使用MobX实现全局数据共享
  • 对小程序的API进行Promise化

具体的内容还包括:使用npm包、全局数据共享、分包和自定义tabBar的案例;

1 自定义组件

创建自定义组件

创建/components目录,继续创建子目录(目录名为组件名),右击子目录新建Component填入组件名即可;每个组件也会自动创建四个组成文件;

引入自定义组件:

  • 局部引用:在页面的json配置文件中配置
  • 全局引用:在全局的json配置文件中配置
{
  "usingComponents" : {
    'ms-test': "/components/test/test" // 组件路径 不要带后缀
  }
}

组件和页面的区别:组件的js和json文件 明显区别于页面的

  • 组件的json中,需要声明属性 "component":true
  • 组件的js中调用的是Component()函数,而页面的js中调用的是Page()函数;
  • 组件的事件处理函数需要定义到methods节点中,而页面的函数只需要定义在和data节点平级的节点中即可);

内部方法建议以下划线开头;

在组件和引用组件的页面中 尽量使用class选择器,不要使用id、属性、标签选择器;因为只有class选择器受样式隔离的影响;
全局/页面样式不会影响组件内样式;

修改组件样式的隔离选项

修改组件样式的隔离选项:

  • 自定义组件的样式隔离特性能够防止组件内外样式相互干扰;
  • 如果希望在外部能够影响组件内部的样式,可以修改组件的样式隔离选项:styleIsolation
    • isolated 默认值
    • apply-shared 页面可以影响组件
    • shared 页面和组件样式可相互影响,而且组件中样式还会影响其他设置了apply-shared或shared的组定义组件;
// 在组件js中配置
Component({
  options: {
    styleIsolation: 'isolated'
  }
})

// 或在组件.json中配置
{
  'styleIsolation': 'isolated'
}

自定义组件的数据、方法和属性

用于组件模版渲染的私有数据,需要定义到data节点中(也页面一样);

组件中,事件处理函数和自定义方法都需要定义到methods节点中;

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

  • 使用组件时,通过属性传值;
{
  properties: {
    max:{
      type: Number, // 数据类型
      value: 10 // 默认值
    },
    min: Number // 无需指定默认值时的简化用法

  }
}

// <my-test max="11"></my-test>

和Vue比,比较特别的一点是,小程序组件中的properties和data数据都是可读可写的;

组件中的数据监听器

监听属性变化,执行特定操作;(类似Vue中watch)

小程序中监听的基本语法格式:

Component({
  // 需要声明一个 observers 配置对象
  observers: {
    // 可以在一个监听器中 同时监听多个字段的变化
    "字段1, 字段2": function("字段1的新值,字段2的新值"){
      // 触发方式:
      // 为字段1 赋值
      // 为字段2 赋值
      // setData为对象赋值
    }
  }
})

关于setData/observers:使用嵌套对象的子属性赋值/监听的方法;

data: {
  rgb: {
    r: 0,
    g: 0
  },
  fullColor: ''
}

...
this.setData({
  // 为嵌套对象的子属性赋值的方式
  'rgb.r': 255
})

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

通配符监听:

  • 使用通配符**来监听对象中所有属性的变化;
observers: {
  'rgb.**': function(obj){
    this.setData({
      fullColor: `${obj.r}, ${obj.g}`
    })
  }
}

纯数据字段

指不用于界面 渲染的data字段(具体的:既不会展示在界面上,也不会传递给其他组件,仅在当前页面的内部使用);

这样的数据适合被定义为纯数据字段,有助于提升页面的更新性能;

使用:

  • 在Component的options节点中,指定pureDataPattern为一个正则表达式,符合这个正则的字段都将成为纯数据字段(可以是一个对象);
Component({
  options:{
    pureDataPattern: /^_/ // 以下划线开头的字段
  },
  data: {
    a: true,
    _b: true, // pureData
    _rgb: { // pureData
      r: 0,
      g: 0,
    }
  }

})

快捷选中: cmd+d

2 组件生命周期

  • created:刚创建
    • 不能调用setData,因为data还没初始化
    • 可以给this添加一些自定义的属性字段
  • attached: 刚被放入页面节点树,还没渲染
    • 可以发送网络请求;
  • ready:在视图层布局完成之后执行
  • moved:组件实例被移动到节点树的另一个位置时执行
  • detached:从页面节点树移除
    • 清理事件监听;
  • error:组件方法异常的时候执行

排列顺序也是执行顺序;

小程序组件的生命周期函数可以在lifetimes字段内进行声明;

Components({
  lifetimes:{
    attached(){},
    detached(){},
  }
})

组件所在页面的生命周期

在自定义组件的行为需要依赖页面状态的变化的时候,可能需要在组件中监听组件所在页面的生命周期;

组件能使用的页面生命周期函数:

  • 这些函数需要定义在pageLieftimes节点中;
  • show:组件所在页面被显示的时候
  • hide:组件所在页面被隐藏的时候
  • resize::组件所在页面的尺寸变化的时候
Components({
  pageLieftimes:{
    show(){
      Math.floor(Math.random() * 256) // 0~255
    },
    hide(){},
    resize(){},
  }
})

3 自定义组件插槽

  • 提供<slot></slot>节点,相当于占位符,用于承载组件使用者提供的wxml结构;
<!-- test组件内 -->
<view>
<!-- 单插槽 -->
  <slot></slot>
</view>

<!-- 使用组件时 -->
<test>
  <view>替换组件内占位符</view>
</test>

如果需要让组件支持多个插槽,只需要在options节点配置multipleSlots属性为true;每个slot占位以不同的name区分;

<!-- test组件内 -->
<view>
  <slot name="header"></slot>
  <view>Content</view>
  <slot name="footer"></slot>
</view>

<!-- 使用组件时 -->
<test>
  <view slot="header">替换组件内占位符header</view>
  <view slot="footer">替换组件内占位符footer</view>
</test>

4 父子组件间通信

父子组件间传值的三种方式:

  • 通过属性绑定传值,父向子传值,需要指定属性,仅能传递json兼容的数据(无法传递方法);
  • 事件绑定,子向父传值
    • 在父组件中定义一个回调函数,然后传递给子组件;
    • 在子组件中 调用this.triggerEvent('自定义事件名称', {参数对象}),将数据发送到父组件
    • 父组件js中,通过e.detail获取子组件所传递的数据,可以是任意数据类型(如方法);
  • 父组件中可通过 this.selectComponent()方法获取子组件实例,以直接访问子组件的任何数据和方法;

属性绑定:

  • 父组件中使用子组件并绑定数据(注意这里与vue不同,小程序的wxml中使用的是Mustache语法,如 <test title="{{use_title}}"></test>);
  • 子组件中properties节点声明相应的属性名;
  • 这个绑定是单向的,因此如果在子组件中title属性发生了变化,还需要使用子向父传值;

事件绑定:

<!-- 事件绑定 -->
<test bind:sync="syncCountChange"></test>
// 父组件
syncCountChange(e){
  e.detail.value
}

// 子组件
methods: {
  addCount(){
    this.setData({
      count: this.properties.count + 1
    })
    this.triggerEvent('sync', {value: this.properties.count})
  }
}

直接获取子组件实例:

  • this.selectComponent(#id或.class选择器)
<test class="customA"></test>
const childA = this.selectComponent(".customA")
// childA.setData(...)

5 自定义组件的behaviors

自定义组件的behaviors

  • 用于实现组件间代码共享的特性,类似vue中mixins
  • 每个组件可以引入多个behaviors,behaviors间也可以相互引用;

每个behavior中都可以包含一组:属性、数据、生命周期函数和方法,组件应用它时,它的属性、数据和方法会被合并到组件中;

创建 behavior

// 调用 Behavior() 可以创建一个共享的behavior对象
module.exports = Behavior({
  // 属性
  properties:{},
  // 数据
  data:{},
  // 方法
  methods:{}
  // 其他behavior
  behaviors:[],
  // 生命周期函数
  created(){},
  attached(){},
  ready(){},
  moved(){},
  detached(){},
})

导入并使用behavior

使用require()方法导入,挂载后即可访问其中数据或方法;

const myB = require("../../behaviors/my-behavior")

Component({
  // 挂载到 behaviors 数组节点中
  behaviors:[myB],
})

behaviors中同名字段的覆盖和组合规则:

  • 同名数据字段(data)
    • 对象重复 合并
    • 组件 > 父behavior > 子behavior
  • 同名属性(properties)或方法(methods)
  • 同名的生命周期函数

具体的可参考小程序官方文档;

6 使用npm包管理三方工具包

3个限制:

  • 不支持依赖于Node.js内置库的包;
  • 不支持依赖于浏览器内置对象的包;
  • 不支持依赖于C++插件的包;

服务于小程序的包没有那么多;虽然有三方包的加持,但是不要忘记小程序本身提供的丰富API;

Vant Weapp

一套开源的小程序UI组件库

  • https://youzan.github.io/vant-weapp

安装Vant组件库:

  • 通过npm安装 建议指定版本,如@1.3.3(具体可参考文档)
    • 在小程序文件目录空白区域,右击打开外部终端
    • 初始化npm(会创建一个package.json的配置文件): npm init -y
    • copy命令进行vant安装
  • 构建npm包:IDE 工具 构建npm 勾选使用,再本地设置 勾选使用npm模块(以使用三方包);
  • 修改app.json配置文件(不使用新版样式,以防止样式冲突)

使用Vant组件库:

// 全局配置使用组件
"usingComponents":{
  'van-button': "@vant/weapp/button/index"
}

定义Vant全局的主题样式:

  • 使用CSS变量(CSS_custom_properties)来实现,具体可参考MDN文档;
  • 在 app.wxss中,写入CSS变量,即可对全局生效;
  • 参考Vant定制主题,可以获取到可用的样式变量;
/* 为了全局 变量都定义在页面的根节点标签page中 */
page {
  --变量名: CSS变量值;
  @变量名: less变量值;
}

/* 使用时 */
CSS属性 : var(--变量名, 指定变量不存在时的默认值)

API Promise化处理

将基于回调函数的异步api,改造为基于Promise的异步API;

实现方式:

  • 依赖miniprogram-api-promise三方包,使用npm install --save miniprogram-api-promise@1.0.4(建议指定版本号)安装;
  • 每次构建前建议都删除依赖目录:miniprogram_npm目录
  • 重新构建:点击工具->构建,重新构建
    • 在node_modules目录下的包不可以直接使用,构建后,在miniprogram_npm目录下的包才可以使用;

使用:

// 在app.js中 按需导入
import {promisifyAll} form 'miniprogram-api-promise'

// 定义了一个空对象 之后就可以通过wx.p去调用promise化的api(wxp和wx.p是同一个对象)
const wxp = wx.p = {}
// 将wx的异步请求全部promise化 之后挂载到wxp上
promisifyAll(wx, wxp)
async getInfo(){
  // 解构data赋值给res
  const {data: res} = await wx.p.request({
    method: "GET",
    url: '',
    data: {}
  })
  console.log(res)
}

全局数据共享

即状态管理,是为了解决组件间数据共享的问题,类似Vue中如vuex

小程序中可使用两个包:mobx-miniprogream配合mobx-miniprogream-bindings实现全局数据共享

  • mobx-miniprogream 用于创建 store实例
  • mobx-miniprogream-bindings 用于把store中的数据共享方法 绑定到组件或页面中使用

npm安装,之后:

  • 创建一个store目录
  • 其中再创建一个 store.js,专门创建Store的实例对象
// store.js
import {observable,  action} form 'mobx-miniprogream'

// 按需导出
export const store = observable({
  // 挂载需要共享的数据
  // 数据
  num1: 1,
  num2: 1,
  // 计算属性
  get sum(){
    return this.num1 + this.num2
  },
  // actions
  // 专门用来定义 修改数据的方法
  dosomething: action(function (step){
    this.num1 += step
  })
})
  • 将Store中的成员绑定到页面中
import { createStoreBindings } from 'mobx-miniprogream-bindings'
import {store} from "../../store/store"

Page({
  onLoad: function(){
    // 
    this.storeBindings = createStoreBindings(this, {
      store,
      fields: ['num1', 'num2', 'sum'], // 绑定的字段
      actions: ['dosomething'] // 绑定的方法
    })
  },
  onUnload: function() {
    this.storeBindings.destroyStoreBindings()
  }
})

组件中的绑定略有不同:

import { storeBindingsBehavior } from 'mobx-miniprogram-bindings'
import { store } from '../../store/store'

Component({
  behaviors: [storeBindingsBehavior],
  // 配置对象 storeBindings
  storeBindings: {
    store,
    fields: {
      numA: (store) => store.num1,
      numB: 'num2'
    },
    actions: {
      dosome: 'dosomething'
    }
  }
})

7 分包

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

默认是不分包的;

一个主包+多个分包:

  • 主包:一般包含启动页面或多个TabBar页面,以及所有分包都要用到的一些公共资源;
  • 分包:只当前分包相关的页面和私有资源;

分包可以引用主包内的公共资源;

分包加载:

  • 小程序启动时,默认下载主包并启动主包内页面;
    • tabBar只能放到主包中;
  • 当进入分包某页面时,才会下载对应分包;

分包体积限制:

  • 所有分包不超过16M
  • 单个包不超过2M

配置分包:

  • 项目目录解构的变化;
    • 主包: pages
    • 分包A: packageA/pages
    • 分包B: packageB/pages
  • app.json配置节点(修改后保存会自动创建文件目录);
    • pages
    • subpackages
"pages": [ "pages/index/index", "pages/logs/logs"],
"subpackages":[{
  "root": "packageA", // 分包A的根目录
  "pages": ["pages/indexA/indexA", "pages/logsA/logsA"] // 相对当前root的页面存放路径
},{
  "root": "packageB",
  "name": "pkg2", // 分包别名
  "pages": ["pages/indexB/indexB", "pages/logsB/logsB"]
}]

在项目基本信息面板,可以看到各个分包的体积;

打包原则:

  • 按subpackages配置进行分包,之外的目录会被打包到主包中;
  • 主包有自己的pages(即最外层的pages);
  • tabBar必须在主包内;
  • 分包之间不能相互嵌套;

独立分包:

  • 一种特殊的分包,只不过可以独立于主包二单独运行;
    • 正常分包,只能通过主包跳转(需要先下载主包);
    • 而独立分包,可以在小程序启动后直接载入(无需依赖主包);
  • 一个小程序中可以有多个独立分包;
  • 独立分包与主包(包括主包内的公共资源)和其他分包(包括独立分包)间是隔绝的,不能相互引用彼此资源;

配置独立分包:

  • 在分包配置中增加"independent": true即可;

分包预下载:

  • 在进入指定页面时可以配置触发该行为,将可能使用的后续分包页面提前下载;
  • 使用preloadRule节点进行定义;
"preloadRule": {
  "pages/myself/myself": {
    // 在进入 myself页面的时候 触发加载以下分包
    "network": "all", // 网络模式 默认为wifi
    "packages": ["pkg2"] // 分包别名
  }
}

同一个主/分包中的页面享用共同的预下载大小限额2M,如主包的tabBar三个页面分别预下载了体积为1M的分包,此时主包就会下载3M的分包,这是不允许的(会失败);

8 自定义tabBar实现更丰富的功能

  • 自定义组件:参考小程序官方文档,自定义tabBar(注意这是一个组件)
  • Vant组件库:提供了一个可用的Tabbar
    • 切换tab,拿到change的tab索引,调用wx.switchTab方法;
    • 把tab索引也放到store中(包括相应的修改值的方法),以解决索引无法切换的问题;
  • MobX数据共享:参考小程序官方文档,扩展能力,框架扩展;
  • 组件样式隔离:要覆盖tabBar的默认样式,需要修改自定义Tabbar组件样式隔离选项的值,
  • 组件数据监听器:监听Store中的字段,为组件内变量赋值
  • 组件的behaviors
  • Vant样式覆盖:参考Vant文档,样式覆盖
observers: {
  'sum': function(val){
    this.setData({
      // 为datalist数组下标为1的对象的info属性赋值
      'datalist[1].info': val
    })
  }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2286810.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Zookeeper入门部署(单点与集群)

本篇文章基于docker方式部署zookeeper集群&#xff0c;请先安装docker 目录 1. docker初期准备 2.启动zookeeper 2.1 单点部署 2.2 集群部署 3. Linux脚本实现快速切换启动关闭 1. docker初期准备 拉取zookeeper镜像 docker pull zookeeper:3.5.6 如果拉取时间过长&#xf…

【AI非常道】二零二五年一月(二),AI非常道

经常在社区看到一些非常有启发或者有收获的话语&#xff0c;但是&#xff0c;往往看过就成为过眼云烟&#xff0c;有时再想去找又找不到。索性&#xff0c;今年开始&#xff0c;看到好的言语&#xff0c;就记录下来&#xff0c;一月一发布&#xff0c;亦供大家参考。 有关AI非…

jQuery小游戏(二)

jQuery小游戏&#xff08;二&#xff09; 今天是新年的第二天&#xff0c;本人在这里祝大家&#xff0c;新年快乐&#xff0c;万事胜意&#x1f495; 紧接jQuery小游戏&#xff08;一&#xff09;的内容&#xff0c;我们开始继续往下咯&#x1f61c; 游戏中使用到的方法 key…

【硬件测试】基于FPGA的QPSK+帧同步系统开发与硬件片内测试,包含高斯信道,误码统计,可设置SNR

目录 1.算法仿真效果 2.算法涉及理论知识概要 2.1QPSK 2.2 帧同步 3.Verilog核心程序 4.开发板使用说明和如何移植不同的开发板 5.完整算法代码文件获得 1.算法仿真效果 本文是之前写的文章 《基于FPGA的QPSK帧同步系统verilog开发,包含testbench,高斯信道,误码统计,可…

NVIDIA GPU介绍:概念、序列、核心、A100、H100

概述 入职一家大模型领域创业公司&#xff0c;恶补相关知识。 概念 一些概念&#xff1a; HPC&#xff1a;High Performance Computing&#xff0c;高性能计算SoC&#xff1a;System on Chip&#xff0c;单片系统FLOPS&#xff1a;Floating Point Operations Per Second&am…

C++ list 容器用法

C list 容器用法 C 标准库提供了丰富的功能&#xff0c;其中 <list> 是一个非常重要的容器类&#xff0c;用于存储元素集合&#xff0c;支持双向迭代器。<list> 是 C 标准模板库&#xff08;STL&#xff09;中的一个序列容器&#xff0c;它允许在容器的任意位置快速…

解密全同态加密中的自举(Bootstrapping)

摘要 自举&#xff08;Bootstrapping&#xff09;是全同态加密&#xff08;Fully Homomorphic Encryption, FHE&#xff09;中经常使用的术语。熟悉 FHE 的人都知道&#xff0c;自举是 FHE 方案中最复杂且计算密集的部分。然而&#xff0c;只有极少数非 FHE 专家真正理解自举操…

显示当前绑定变量

来自v$sql中的信息 测试两个变量的情况&#xff08;实际可以看6个&#xff0c;可根据需要修改&#xff09; DROP TABLE T1 PURGE; CREATE TABLE T1 AS SELECT A.*,SYSDATE RIQI FROM DBA_USERS A ORDER BY 1;var mc char(3); var id number; exec :mc:SYS; exec :id:50;set li…

arm-linux-gnueabihf安装

Linaro Releases windows下打开wsl2中的ubuntu&#xff0c;资源管理器中输入&#xff1a; \\wsl$gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf.tar.xz 复制到/home/ark01/tool 在 Ubuntu 中创建目录&#xff1a; /usr/local/arm&#xff0c;命令如下&#xff1a; …

宝塔面板SSL加密访问设置教程

参考:https://www.bt.cn/bbs/thread-117246-1-1.html 如何快速使用证书加密访问面板 因早期默认未开启https访问所以没有相关的风险提醒&#xff0c;现面板默认已开启https加密访问、提升安全性 由于采用的是服务器内部本身签发证书&#xff0c;不被公网浏览器信任请参考以下步…

Baklib在知识管理创新中的价值体现与其他产品的优势比较分析

内容概要 在当前的数字化时代&#xff0c;知识管理成为企业成功的重要组成部分。有效的知识管理不仅有助于提升内部沟通效率&#xff0c;还能促进创新与决策的科学化。尤其是Baklib作为一种知识中台&#xff0c;具有独特的价值&#xff0c;它能够融合企业内外的知识资源&#…

机器学习周报-文献阅读

文章目录 摘要Abstract 1 相关知识1.1 WDN建模1.2 掩码操作&#xff08;Masking Operation&#xff09; 2 论文内容2.1 WDN信息的数据处理2.2 使用所收集的数据构造模型2.2.1 Gated graph neural network2.2.2 Masking operation2.2.3 Training loss2.2.4 Evaluation metrics 2…

C语言连接Mysql

目录 C语言连接Mysql下载 mysql 开发库 方法介绍mysql_init()mysql_real_connect()mysql_query()mysql_store_result()mysql_num_fields()mysql_fetch_fields()mysql_fetch_row()mysql_free_result()mysql_close() 完整代码 C语言连接Mysql 下载 mysql 开发库 方法一&#xf…

Synology 群辉NAS安装(6)安装mssql

Synology 群辉NAS安装&#xff08;6&#xff09;安装mssql 写在前面mssql 2019:成功安装说明&#xff0c;这个最终成功了 mssql 2022没有成功1. pull image2.启动mssql docker container 远程连接 写在前面 mssq是一个重要节点。 这是因为我对mysql没有一丝好感。虽然接触了许…

WEB集群1-5天

文章目录 第一天、1、初始化配置1. 编写的初始化的脚本 init_env.sh2. 远程拷贝初始化脚本到mysql服务器里3.在mysql这台服务器上执行脚本 2、总结 第二天1、yumyum介绍yum操作将冯老师提供的网站的源码包上传到web服务器 2、部署网站1、解压文件2、epel源&#xff1a;可以提供…

“AI视频智能分析系统:让每一帧视频都充满智慧

嘿&#xff0c;大家好&#xff01;今天咱们来聊聊一个特别厉害的东西——AI视频智能分析系统。想象一下&#xff0c;如果你有一个超级聪明的“视频助手”&#xff0c;它不仅能自动识别视频中的各种元素&#xff0c;还能根据内容生成详细的分析报告&#xff0c;是不是感觉特别酷…

kaggle视频追踪NFL Health Safety - Helmet Assignment

3年前的比赛了&#xff0c;检测视频中的头盔&#xff0c;通过对比赛录像的分析&#xff0c;正确指派球员。每个进攻都有两个相关的视频&#xff0c;一个是边线视角&#xff0c;另一个是端区视角&#xff0c;而且这两个视频是同步的&#xff0c;即视频中的每一帧都是对应的。我用…

idea对jar包内容进行反编译

1.先安装一下这个插件java Bytecode Decompiler 2.找到这个插件的路径&#xff0c;在idea的plugins下面的lib文件夹内&#xff1a;java-decompiler.jar。下面是我自己本地的插件路径&#xff0c;以作参考&#xff1a; D:\dev\utils\idea\IntelliJ IDEA 2020.1.3\plugins\java-d…

deepseek R1 14b硬件要求

RTX2080ti 11G显卡&#xff0c;模型7b速度挺快&#xff0c;试试14B也不错。 7B显存使用5.6G&#xff0c;11B显存刚好够&#xff0c;出文字速度差不多。 打算自己写个移动宽带的IPTV播放器&#xff0c;不知道怎么下手&#xff0c;就先问他了。

DeepSeek-R1环境搭建推理测试

引子 这两天国货之光DeepSeek-R1火爆出圈&#xff0c;凑个热闹。过来看看 aha moment&#xff08;顿悟时刻&#xff09;的神奇&#xff0c;OK&#xff0c;我们开始吧。 一、模型介绍 1月20日&#xff0c;中国AI公司深度求索&#xff08;DeepSeek&#xff09;发布的DeepSeek-…