• 小程序笔记3


    1.自定义组件

    1.创建组件

    1. 在项目的根目录中,鼠标右键,创建 components -> test 文件夹
    2. 在新建的 components -> test 文件夹上,鼠标右键,点击“新建 Component”
    3. 键入组件的名称之后回车,会自动生成组件对应的 4 个文件,后缀名分别为 .js,.json,.wxml 和 .wxss

    2.引用组件

    1. 局部引用:组件只能在当前被引用的页面内使用

      在页面的 .json 配置文件中引用组件的方式,叫做“局部引用”

      “usingComponents”: {
      “my-test1”: “/components/test/test”,
      }

    2. 全局引用:组件可以在每个小程序页面中使用

      app.json引用

      “usingComponents”: {
      “my-test1”: “/components/test/test”,
      }

    3.组件和页面的区别

    从表面来看,组件和页面都是由 .js、.json、.wxml 和 .wxss 这四个文件组成的。但是,组件和页面的 .js 与 .json 文件有明显的不同:

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

    4.自定义组件样式

    1. 组件样式隔离(组件之间或者组件和页面之间样式互不影响,只针对样式选择器)

    2. 组件样式隔离的注意点

      • app.wxss 中的全局样式对组件无效
      • 只有 class 选择器会有样式隔离效果,id 选择器、属性选择器、标签选择器不受样式隔离的影响
    3. 修改组件的样式隔离选项

    Component({
         options: {
           styleIsolation: 'shared'
         }
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    页面给组件传值

    
    //组件
    properties: {
    // 第一种方式:简化的方式
    // max: Number
    // 第二种方式:完整的定义方式
        max: {
          type: Number,
          value: 10
        }  
    },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    5.数据监听器

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

    observers: {
    ‘n1, n2’: function (newN1, newN2) {
    this.setData({
    sum: newN1 + newN2
    })
    }
    }

    1. 监听对象中指定属性的变化

      ‘’rgb.r,rgb.b"…

    2. 监听对象中所有属性的变化

      使用通配符 ** 来监听对象中所有属性的变化

      “rgb.**”:…

    6.纯数据字段

    • 概念:纯数据字段指的是那些不用于界面渲染的 data 字段,

    • 应用场景:例如有些情况下,某些 data 中的字段既不会展示在界面上,也不会传递给其他组件,仅仅在当前组件内部使用。带有这种特性的 data 字段适合被设置为纯数据字段。

    • 好处:纯数据字段有助于提升页面更新的性能。

    • 使用规则:在 Component 构造器的 options 节点中,指定 pureDataPattern 为一个正则表达式,字段名符合这个正则表达式的字段将成为纯数据字段(data、methods…中符合规则的)

    • 例子

      options: {
      pureDataPattern: /^_/
      },

      data: {
      _rgb: {
      r: 0,
      g: 0,
      b: 0
      },

      7.生命周期

      在小程序组件中,最重要的生命周期函数有 3 个,分别是 created、attached、detached。它们各自的特点如下:

      • 组件实例刚被创建好的时候,created 生命周期函数会被触发
        此时还不能调用 setData
        通常在这个生命周期函数中,只应该用于给组件的 this 添加一些自定义的属性字段
      • 在组件完全初始化完毕、进入页面节点树后, attached 生命周期函数会被触发
        此时, this.data 已被初始化完毕
        这个生命周期很有用,绝大多数初始化的工作可以在这个时机进行(例如发请求获取初始数据)
      • 在组件离开页面节点树后, detached 生命周期函数会被触发
        退出一个页面时,会触发页面内每个自定义组件的 detached 生命周期函数
        此时适合做一些清理性质的工作
        - [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yoaVNabr-1659496958698)(C:\Users\syhgly\AppData\Roaming\Typora\typora-user-images\1659444077111.png)]

    8.lifetimes 节点

    在小程序组件中,生命周期函数可以直接定义在 Component 构造器的第一级参数中,可以在 lifetimes 字段内进行声明(这是推荐的方式,其优先级最高)

    9.组件所在页面的生命周期

    自定义组件的行为依赖于页面状态的变化,此时就需要用到组件所在页面的生命周期。

    10.pageLifetimes 节点

    组件所在页面的生命周期函数,需要定义在 pageLifetimes 节点中

    11.插槽

    在自定义组件的 wxml 结构中,可以提供一个 节点(插槽),用于承载组件使用者提供的 wxml 结构。

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

    • 启用多个插槽–组件的 .js 文件中开启

      Component({
        options: {
          multipleSlots: true
        },
      })
      //例子  -通过具名使用
      <slot name="A"></slot> 
      <view slot="before">***</view>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    配合 -----***

    12.父子组件之间通信

    1. 属性绑定(父->子)

      父组件

      count=“{{count}}”

      子组件

      properties: {
      count: Number
      },

    2. 事件绑定

      bind:sync=“syncCount”||bindsync=“syncCount”

      父组件(通过 e.detail 获取到子组件传递过来的数据)

      sysncCount(e)

      子组件(通过调用 this.triggerEvent(‘自定义事件名称’, { /* 参数对象 */ }) ,将数据发送到父组件)

      this.triggerEvent(‘sync’, { value: this.properties.count })

    3. 获组件实例

      可在父组件里调用 this.selectComponent(“id或class选择器”) ,获取子组件的实例对象,从而直接访问子组件的任意数据和方法。调用时需要传入一个选择器,例如 this.selectComponent(“.my-component”)。

    wxml:   class="customA" id="cA"
    
       父组件
    
       getChild() {
           const child = this.selectComponent('#cA')
           console.log(child)
           // child.setData({
           //   count: child.properties.count + 1
           // })
           child.addCount()
         },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    13.behaviors

    1. 简介

      用于实现组件间代码共享的特性,类似于 Vue.js 中的 “mixins”

    2. behaviors 的工作方式

      每个 behavior 可以包含一组属性、数据、behavior 、生命周期函数和方法。组件引用它时,它的属性、数据和方法会被合并到组件中。
      每个组件可以引用多个 behaviorbehavior 也可以引用其它 behavior

    3. 创建behavior

      调用 Behavior(Object object) 方法即可创建一个共享的 behavior 实例对象,供所有的组件使用

     my-behavior.js
      module.exports = Behavior({
        data: {
          username: 'zs'
        },
        properties: {},
        methods: {}
      })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    //组件
      const myBehavior = require('../../behaviors/my-behavior')
      Component({
        behaviors: [myBehavior],
      }
    • 1
    • 2
    • 3
    • 4
    • 5
    1. 同名字段的覆盖和组合规则

      当组件触发生命周期时,上例生命周期函数执行顺序为:

      1. [my-behavior] created
      2. [my-component] created
      3. [my-behavior] attached
      4. [my-component] attached
      5. [my-behavior] ready
      6. [my-component] ready

      组件和它引用的 behavior 中可以包含同名的字段

      1. 同名的数据字段 (data)
        • 同名的数据字段都是对象类型,会进行对象合并
        • 其余情况会进行数据覆盖,覆盖规则为: **引用者 behavior > 被引用的 behavior靠后的 behavior > 靠前的 behavior**。(优先级高的覆盖优先级低的,最大的为优先级最高)
      2. 同名的属性 (properties) 或方法 (methods)
        1. 组件本身有这个属性或方法,则组件的属性或方法会覆盖 behavior 中的同名属性或方法;
        2. 若组件本身无这个属性或方法,则在组件的 behaviors 字段中定义靠后的 behavior 的属性或方法会覆盖靠前的同名属性或方法;
      3. 同名的生命周期函数
        1. 对于不同的生命周期函数之间,遵循组件生命周期函数的执行顺序
        2. 对于同种生命周期函数,遵循如下规则
          • behavior 优先于组件执行;
          • 被引用的 behavior 优先于 引用者 behavior 执行;
          • 靠前的 behavior 优先于 靠后的 behavior 执行;
        3. 如果同一个 behavior 被一个组件多次引用,它定义的生命周期函数只会被执行一次

    2.使用那npm包

    1. 小程序对 npm 的支持与限制

      总结:虽然 npm 上的包有千千万,但是能供小程序使用的包却“为数不多”。

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

      • 介绍:Vant Weapp 是有赞前端团队开源的一套小程序 UI 组件库,助力开发者快速搭建小程序应用。它所使用的是 MIT 开源许可协议,对商业使用比较友好。
        官方文档地址

      • 安装

        • 通过 npm 安装(建议指定版本为@1.3.3(不要是最新的))

        • 构建 npm 包

        • 修改 app.json(使用组件)

          “usingComponents”: {
          “van-button”: “@vant/weapp/button/index”,

          }

        • 详细的操作步骤,大家可以参考 Vant 官方提供的快速上手教程

    3. 定制全局主题样式

      Vant Weapp 使用 CSS 变量来实现定制主题。 关于 CSS 变量的基本用法,请参考 MDN 文档

    4. 使用 npm 包进行API Promise优化

      • 基于回调函数的异步 API 的缺点
        在这里插入图片描述

      缺点:容易造成回调地狱的问题,代码的可读性、维护性差!

      • API Promise 优化-升级改造为基于 Promise 的异步 API

        在小程序中,实现 API Promise 优化主要依赖于 miniprogram-api-promise 这个第三方的 npm 包。它的安装和使用步骤如下:
        在这里插入图片描述

    3.全局数据共享

    1. 简介

      全局数据共享(又叫做:状态管理)是为了解决组件之间数据共享的问题。
      开发中常用的全局数据共享方案有:Vuex、Redux、MobX 等

    2. 小程序中的全局数据共享方案(Mobx)

      在小程序中,可使用 mobx-miniprogram 配合 mobx-miniprogram-bindings 实现全局数据共享。其中:

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

      • 安装包

        npm install --save mobx-miniprogram@4.13.2 mobx-miniprogram-bindings@1.2.1

        注意:MobX 相关的包安装完毕之后,记得删除 miniprogram_npm 目录后,重新构建 npm。

      • 创建Mobx的store实例

        // 在这个 JS 文件中,专门来创建 Store 的实例对象

    import { observable, action } from 'mobx-miniprogram'
     export const store = observable({
       // 数据字段
       numA: 1,
       numB: 2,
       activeTabBarIndex: 0,
       // 计算属性
       get sum() {
         return this.numA + this.numB
       },
       // actions 函数,专门来修改 store 中数据的值
       updateNum1: action(function (step) {
         this.numA += step
       }),
       updateNum2: action(function (step) {
         this.numB += step
       }),
       updateActiveTabBarIndex: action(function(index) {
         this.activeTabBarIndex = index
       })
     })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 将 Store 中的成员绑定到页面中
      // pages/message/message.js
         import { createStoreBindings } from 'mobx-miniprogram-bindings'
         import { store } from '../../store/store'
    
         Page({
           onLoad: function (options) {
    	     this.storeBindings = createStoreBindings(this, {
    	       store,
    	       fields: ['numA', 'numB', 'sum'],
    	       actions: ['updateNum1']
    	     })
           },
    
           btnHandler1(e) {
             // console.log(e)
             this.updateNum1(e.target.dataset.step)
           }
         }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 在页面上使用 Store 中的成员
     <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>
    
    • 1
    • 2
    • 3
    • 将 Store 中的成员绑定到组件中
      	 import { storeBindingsBehavior } from 'mobx-miniprogram-bindings'
         import { store } from '../../store/store'
         Component({
           behaviors: [storeBindingsBehavior],
           storeBindings: {
             store,
             fields: {
               numA: 'numA',
               numB: 'numB',
               sum: 'sum'
             },
             actions: {
               updateNum2: 'updateNum2'
             }
           },
         methods: {
             btnHandler2(e) {
               this.updateNum2(e.target.dataset.step)
             }
           }
         })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 在组件中使用 Store 中的成员
     <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>
    
    • 1
    • 2
    • 3

    4.分包

    1. 简介

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

    2. 分包的好处

      • 可以优化小程序首次启动的下载时间
      • 在多团队共同开发时可以更好的解耦协作
    3. 分包前项目的构成

      分包前,小程序项目中所有的页面和资源都被打包到了一起,导致整个项目体积过大,影响小程序首次启动的下载时间

    4. 分包后项目的构成

      分包后,小程序项目由 1 个主包 + 多个分包组成
      主包:一般只包含项目的启动页面或 TabBar 页面、以及所有分包都需要用到的一些公共资源
      分包:只包含和当前分包有关的页面和私有资源

    5. 分包的加载规则

      • 在小程序启动时,默认会下载主包并启动主包内页面

        tabBar 页面需要放到主包中

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

        非 tabBar 页面可以按照功能的不同,划分为不同的分包之后,进行按需下载

      • 分包的体积限制

        • 整个小程序所有分包大小不超过 16M(主包 + 所有分包)
        • 单个分包/主包大小不能超过 2M
    6. 配置方法(使用分包)

    7. 打包原则(使用分包)

      • 小程序会按 subpackages 的配置进行分包,subpackages 之外的目录将被打包到主包中
      • 主包也可以有自己的 pages(即最外层的 pages 字段)
      • tabBar 页面必须在主包内
      • 分包之间不能互相嵌套
    8. 引用原则(使用分包)

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

    9. 独立分包

      • 简介

        独立分包本质上也是分包,只不过它比较特殊,可以独立于主包和其他分包而单独运行

      • 独立分包和普通分包的区别

        最主要的区别:是否依赖于主包才能运行
        普通分包必须依赖于主包才能运行
        独立分包可以在不下载主包的情况下,独立运行

    10. 独立分包的应用场景

      开发者可以按需,将某些具有一定功能独立性的页面配置到独立分包中。原因如下:
      当小程序从普通的分包页面启动时,需要首先下载主包
      独立分包不依赖主包即可运行,可以很大程度上提升分包页面的启动速度
      注意:一个小程序中可以有多个独立分包。

    11. 独立分包的配置方法

    在这里插入图片描述

    1. 独立分包引用原则

      独立分包和普通分包以及主包之间,是相互隔绝的,不能相互引用彼此的资源!例如:
      主包无法引用独立分包内的私有资源
      独立分包之间,不能相互引用私有资源
      独立分包和普通分包之间,不能相互引用私有资源
      特别注意:独立分包中不能引用主包内的公共资源

    2. 分包预下载

      简介

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

    3. 配置分包的预下载

      预下载分包的行为,会在进入指定的页面时触发。在 app.json 中,使用 preloadRule 节点定义分包的预下载规则,示例代码如下:
      在这里插入图片描述

    4. 分包预下载的限制

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

  • 相关阅读:
    堆相关例子-排序最多移动k距离
    王学岗-编译出运行的文件
    2022年C++面试题万余字汇总【面试官常问】
    【Java】split 分割方法
    Linux初始化(下):从_start到第一个进程
    简析CloudCompare文件夹之间的关系
    【C++】命名空间 namespace 与 标准流 iostream ( 命名空间概念简介 | 命名空间定义 | 命名空间使用 | iostream 中的命名空间分析 )
    EasyCVR云端录像模块无法进行下载是什么原因?该如何解决该问题?
    C++20:换了“心“的auto关键字
    自学Python第二十六天- Tornado 框架
  • 原文地址:https://blog.csdn.net/qq_38799387/article/details/126137024