前端与移动开发----微信小程序----小程序(四)

微信小程序第四天


1. 目标

  1. 能够知道如何自定义小程序组件
  2. 能够知道小程序组件中 behaviors 的作用

2. 组件的创建和引用

2.1 创建自定义组件
  1. 创建组件

    • 在项目的根目录中,鼠标右键,创建 components -> test 文件夹
    • 在新建的 components -> test 文件夹上,鼠标右键,点击 新建 Component
    • 键入组件的名称之后回车,会自动生成组件对应的 4 个文件,后缀名分别为 .js.json.wxml.wxss
    • 注意:为了保证目录结构的清晰,建议把不同的组件,存放到单独目录中

    前端与移动开发----微信小程序----小程序(四)_第1张图片

2.2 局部引用组件
  1. 组件的引用方式

    • 组件的引用方式分为 局部引用全局引用
      • 局部引用:组件只能在当前被引用的页面内使用
      • 全局引用:组件可以在每个小程序页面中使用
  2. 局部引用组件

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

前端与移动开发----微信小程序----小程序(四)_第2张图片

2.3 全局引入组件

app.json 全局配置文件中引用组件的方式,叫做 全局引用

前端与移动开发----微信小程序----小程序(四)_第3张图片

2.5 全局引用和局部引用的区别
  1. 根据组件的使用频率范围,来选择合适的引用方式:
    • 如果某组件在多个页面中经常被用到,建议进行 全局引用
    • 如果某组件只在特定的页面中被用到,建议进行 局部引用
2.6 组件和页面的区别
  1. 从表面来看,组件和页面都是由 .js.json.wxml.wxss 这四个文件组成的。但是,组件和 页面的 .js.json 文件有明显的不同:
    • 组件的 .json 文件中需要声明 "component": true 属性
    • 组件的 .js 文件中调用的是 Component() 函数
      • 整个程序启动调用的是 App()
      • 某个页面的渲染调用的是 Page()
      • 某个组件的渲染调用的是 Component()
    • 组件的事件处理函数需要定义到 methods 节点中

3. 组件的数据、方法和属性

3.1 定义 data 私有数据
  1. 在小程序组件中,用于组件模板渲染的私有数据,需要定义到 data 节点中

    前端与移动开发----微信小程序----小程序(四)_第4张图片

3.2 methods 方法
  1. 在小程序组件中,事件处理函数和自定义方法需要定义到 methods 节点中

    前端与移动开发----微信小程序----小程序(四)_第5张图片

3.3 定义 properties 属性
  1. 在小程序组件中, properties 是组件的对外属性,用来接收外界(父组件)传递到组件中的数据

    前端与移动开发----微信小程序----小程序(四)_第6张图片

3.4 data 和 properties 的区别
  1. 在小程序的组件中, properties 属性和 data 数据的用法相同,它们都是可读可写的,只不过:
    • data 更倾向于存储组件的私有数据
    • properties 更倾向于存储外界传递到组件中的数据
    • 所以, 也不太建议修改 properties 数据,如果要修改 properties 的数据, 最好通过子组件通信给父组件的方式实现

前端与移动开发----微信小程序----小程序(四)_第7张图片

3.5 使用 setData 修改 properties 的值
  1. 由于 data 数据和 properties 属性在本质上没有任何区别,因此 properties 属性的值也可以用于页面渲染,或使用 setDataproperties 中的属性重新赋值

前端与移动开发----微信小程序----小程序(四)_第8张图片

4. 数据监听器

4.1 什么是数据监听器以及其基础语法
  1. 什么是数据监听器

    数据监听器用于监听和响应任何属性和数据字段的变化,从而执行特定的操作。它的作用类似于 vue 中的 watch 侦听器。在小程序组件中,数据监听器的基本语法格式如下

    前端与移动开发----微信小程序----小程序(四)_第9张图片

4.2 数据监听器的基本用法
  1. 组件结构

    前端与移动开发----微信小程序----小程序(四)_第10张图片

  2. 组件的 js 代码

    前端与移动开发----微信小程序----小程序(四)_第11张图片

  3. 完整代码

    <view>
      {
          { num1 }} + {
          { num2 }} = {
          { sum }}
    view>
    
    <button type="warn" bindtap="addNum1">Num + 1button>
    <button type="warn" bindtap="addNum2">Num + 2button>
    
    
    // components/test/test.js
    Component({
           
    
      /**
       * 组件的初始数据
       */
      data: {
           
        num1: 0,
        num2: 0,
        sum: 0
      },
    
      // 数据侦听器
      observers: {
           
        'num1, num2': function (newNum1, newNum2) {
           
          this.setData({
           
            sum: newNum1 + newNum2
          })
        }
      },
    
      /**
       * 组件的方法列表
       */
      methods: {
           
        addNum1 () {
           
          this.setData({
           
            num1: this.data.num1 + 1
          })
        },
    
        addNum2 () {
           
          this.setData({
           
            num2: this.data.num2 + 1
          })
        }
      }
    })
    
    
4.3 监听对象属性的变化
  1. 数据监听器支持监听对象中单个或多个属性的变化

    前端与移动开发----微信小程序----小程序(四)_第12张图片

<button type="warn" bindtap="changeObj">监听对象的属性button>

<view>{
    { obj.name }}view>
// components/test/test.js
Component({
     
  // 组件的初始数据
  data: {
     
    obj: {
     
      name: 'tom'
    }
  },

  // 数据侦听器
  observers: {
     
    'obj.name': function (newName) {
     
      console.log(newName)
    }
  },

  // 方法列表
  methods: {
     
    changeObj() {
     
      this.setData({
     
        'obj.name': 'jerry'
      })
    }
  }
})

5. 组件的生命周期

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

组件的生命周期,指的是组件自身的一些函数,这些函数在特殊的时间点或遇到一些特殊的框架事件时被自动触发。

  1. 最重要的生命周期是 created, attached, detached ,包含一个组件实例生命流程的最主要时间点。

    • 组件实例刚刚被创建好时, created 生命周期被触发

      • 此时还不能调用 setData
      • 通常情况下,这个生命周期只应该用于给组件 this 添加一些自定义属性字段
    • 在组件完全初始化完毕、进入页面节点树后, attached 生命周期被触发

      • this.data 已被初始化完毕
      • 这个生命周期很有用,绝大多数初始化工作可以在这个时机进行
    • 在组件离开页面节点树后, detached 生命周期被触发

      • 退出一个页面时,会触发页面内每个自定义组件的detached 生命周期被触发
      • 如果组件还在页面节点树中,则 detached 会被触发。
      • 此时适合做一些清理性质的工作
5.3 lifetime 节点
  1. 生命周期方法可以直接定义在 Component 构造器的第一级参数中,组件的的生命周期也可以在 lifetimes 字段内进行声明(这是推荐的方式,其优先级最高)

前端与移动开发----微信小程序----小程序(四)_第13张图片

lifetimes: {
     
  attached () {
     
    console.log('在组件实例进入页面节点树')
  },
  detached () {
     
    console.log('在组件实例被从页面节点树移除')
  }
},

attached () {
     
  console.log('~~~~~在组件实例进入页面节点树')
},
detached () {
     
  console.log('~~~~~在组件实例被从页面节点树移除')
},

/**
 * 组件的初始数据
 */
data: {
     
  // rgb 的颜色值对象
  _rgb: {
     
    r: 0,
    g: 0,
    b: 0
  },
  // 根据 rgb 对象的三个属性,动态计算 fullColor 的值
  fullColor: '0, 0, 0'
}

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

6.1 什么是组件所在页面的生命周期
  1. 有时,自定义组件的行为依赖于页面状态的变化,此时就需要用到组件所在页面的生命周期

    • 例如:每当触发页面的 show 生命周期函数的时候,我们希望能够重新生成一个随机的 RGB 颜色值。在自定义组件中,组件所在页面的生命周期函数有如下 3 个,分别是
生命周期 参数 描述
show 组件所在的页面被展示时执行
hide 组件所在的页面被隐藏时执行
resize Object Size 组件所在的页面尺寸变化时执行
6.2 pageLifetimes 节点
  1. 组件所在页面的生命周期函数,需要定义在 pageLifetimes 节点中

    前端与移动开发----微信小程序----小程序(四)_第14张图片

6.3 生成随机的 RGB 颜色值

前端与移动开发----微信小程序----小程序(四)_第15张图片

前端与移动开发----微信小程序----小程序(四)_第16张图片

Component({
     
  // 在组件的methods节点中,定义一个随机颜色的方法
  methods: {
     
    _randomColor() {
     
      // 设置data中的数据
      this.setData({
     
        _rgb: {
     
          r: Math.floor(Math.random() * 256),
          g: Math.floor(Math.random() * 256),
          b: Math.floor(Math.random() * 256)
        }
      })
    }
  },
  // 在组件内部的pageLifetimes节点中,监听组件在页面的生命周期函数
  pageLifetimes: {
     
    // 在页面被展示的时候,调用该方法
    show() {
     
      this._randomColor()
    },
    hide() {
      }, // 页面被隐藏
    resize() {
      } // 页面尺寸变化
  }
})

7. 插槽

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

前端与移动开发----微信小程序----小程序(四)_第17张图片

  1. 其实插槽, 说的通俗一些, 就是 子组件挖坑,父组件填坑 的过程。由父组件在使用子组件的时候, 决定子组件内部的某一些布局展示
    • 子组件通过挖坑
    • 父组件通过组件标签中间的内容来填坑
7.2 单个插槽
  1. 在小程序中,默认每个自定义组件中只允许使用一个 slot 占位,这种个数上的限制叫做单个插槽
    • 默认情况下,一个组件的 wxml 中只能有一个 slot
    • 需要使用多 slot 时,可以在组件 js 中声明启用
    • 注意:小程序中目前只有默认插槽和多个插槽,暂不支持作用域插槽

前端与移动开发----微信小程序----小程序(四)_第18张图片

7.3 启动多个插槽

在小程序的自定义组件中,需要使用多 插槽时,可以在组件的 .js 文件中

前端与移动开发----微信小程序----小程序(四)_第19张图片

7.4 定义多个插槽

可以在组件的 .wxml 中使用多个 标签,以不同的 name 来区分不同的插槽

前端与移动开发----微信小程序----小程序(四)_第20张图片

8. 父子组件通讯

8.1 了解父子组件之间通信的 3 个方式
  1. 属性绑定

    • 用于父组件向子组件的指定属性设置数据,仅能设置 JSON 兼容的数据(只能传递数据,不能传递方法)
  2. 事件绑定

    • 用于子组件向父组件传递数据,可以传递任意数据(包括数组和方法)
  3. 获取组件实例

    • 父组件还可以通过 this.selectComponent() 获取子组件实例对象这样就可以直接访问子组件的任意数据和方法
8.2 属性绑定
  1. 传递数据
    • 属性绑定用于实现父向子传值,而且只能传递普通类型的数据,无法将方法传递给子组件

前端与移动开发----微信小程序----小程序(四)_第21张图片

  1. 接收数据
    • 子组件在 properties 节点中声明对应的属性并使用

前端与移动开发----微信小程序----小程序(四)_第22张图片

8.3 实现子组件的 count 属性自增 + 1
data: {
     
  count: 0
}
addCount() {
     
  this.setData({
     
    count: this.data.count + 1
  })
}
8.4 了解事件绑定的 4 个核心实现步骤
  1. 事件绑定用于实现子向父传值,可以传递任何类型的数据。使用步骤如下:
    • 父组件js 中,定义一个函数,这个函数即将通过自定义事件的形式,传递给子组件
    • 父组件wxml 中,通过自定义事件的形式,将步骤 1 中定义的函数引用,传递给子组件
    • 子组件js 中,通过调用 this.triggerEvent('自定义事件名称', {/* 参数对象 */}),将数据发送到父组件
    • 在父组件的 js 中,通过 e.detail 获取到子组件传递过来的数据
8.5 了解事件绑定的核心实现代码
  1. 步骤 1: 在父组件的 js 中,定义一个函数,这个函数即将通过自定义事件的形式,传递给子组件

    前端与移动开发----微信小程序----小程序(四)_第23张图片

  2. 步骤 2:在父组件的 wxml 中,通过自定义事件的形式,将 步骤 1 中定义的函数引用,传递给子组件

    前端与移动开发----微信小程序----小程序(四)_第24张图片

  3. 步骤 3:在 子组件js 中,通过调用 this.triggerEvent('自定义事件名称', {/* 参数对象 */}),将数据发送到父组件

    前端与移动开发----微信小程序----小程序(四)_第25张图片

  4. 步骤 4:在父组件的 js 中,通过 e.detail 获取到子组件传递过来的数据

前端与移动开发----微信小程序----小程序(四)_第26张图片

8.6 使用 selectComponent 获取组件实例

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

前端与移动开发----微信小程序----小程序(四)_第27张图片

9. 使用 npm

9.1 小程序对 npm 的支持和限制

目前,小程序中已经支持使用 npm 安装第三方包,从而来提高小程序的开发效率。但是,在小程序中使用 npm 包有如下 3 个限制:

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

    • 不支持依赖于 Node 核心模块的包
    • fs Node 文件系统模块 – 不支持
    • path Node 路径模块 – 不支持
  2. 不支持依赖于浏览器内置对象的包

    • 小程序的宿主环境是微信,不存在 DOM 和 DOM
    • 所以依赖于内置对象的包,也不能够使用
  3. 不支持依赖于 C++ 插件的包

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

9.2 了解什么是 vant Weapp
  1. Vant有赞前端团队开源的移动端组件库,于 2016 年开源,已持续维护 4 年时间。Vant 对内承载了有赞所有核心业务,对外服务十多万开发者,是业界主流的移动端组件库之一
  2. 采用 MIT 开源许可协议,对商业使用比较友好
  3. 扫描下方小程序二维码,体验组件库示例

前端与移动开发----微信小程序----小程序(四)_第28张图片

9.3 安装 Vant 组件库

在小程序项目中,安装 Vant 组件库主要分为如下几步

  1. 通过 npm 安装

    • 注意:项目目录不能存在中文!不能存在中文!不能存在中文!否则会报错 !
    npm init -y
    
    npm i @vant/[email protected] -S --production
    
  2. 构建 npm 包功能

    如果提示构建失败,可以将微信开发者工具重启,重启以后,运行小程序项目,查看是否还报错

    • 建议先点击 微信开发者工具 --> 详情 --> 本地设置 --> 使用 npm 模块
    • 然后点击 微信开发者工具 --> 菜单栏 --> 工具 --> 构建npm
    • 提示 构建成功,耗时 xxx 秒 且控制台没有任何的错误,说明包构建成功,可以进行使用
      • 否则就需要把 node_modulesminiprogram_npm 删除
      • 删除以后,重新安装包,并点击 工具 --> 构建npm,进行重新构建
  3. 修改 app.json

    • styles: v2 进行移除,防止 小程序本身的 UI 样式和 Vant 的组件样式库 冲突

详细的操作地址:安装 vant Weapp

9.4 使用 Vant 组件

安装完 Vant 组件库之后,可以在 app.jsonusingComponents 节点中引入需要的组件,即可在 wxml 中直接使用组件

前端与移动开发----微信小程序----小程序(四)_第29张图片

"usingComponents": {
     
  "van-button": "@vant/weapp/button/index"
}
<van-button type="default">默认按钮van-button>
<van-button type="primary">主要按钮van-button>
<van-button type="info">信息按钮van-button>
<van-button type="warning">警告按钮van-button>
<van-button type="danger">危险按钮van-button>
9.5 定义和使用 CSS 变量 (了解)

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

  1. 自定义属性(有时候也被称作 CSS变量 或者 级联变量)是由 CSS 作者定义的,它包含的值可以在整个文档中重复使用

  2. 由自定义属性标记设定值

    • 声明一个自定义属性,属性名需要以两个减号(--)开始,属性值则可以是任何有效的 CSS

    • 比如: --main-color: black;

  3. 由var() 函数来获取值

    • color: var(--main-color);

<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>CSS 变量title>
  <style>
    /* 变量可以声明在某个父级元素中 */
    /* 如果是声明在父级元素中, 定义的变量只能够父级元素内部使用 */
    .box {
      
      /* css 变量要求,需要以 -- 开头,后面跟上变量名称 */
      /* 属性值是合法的 css 属性值即可 */
      --main-bg-color: blue;
    }

    .box {
      
      width: 200px;
      height: 200px;
      border: 1px solid lightcoral;
      /* 如果需要使用 css 变量 */
      /* 使用 var() 去调用变量 */
      background-color: var(--main-bg-color);
    }

    .box1 {
      
      width: 200px;
      height: 200px;
      border: 1px solid lightcoral;
      background-color: var(--main-bg-color);
    }
  style>
head>

<body>
  <div class="box">div>

  <div class="box1">div>
body>

html>
9.6 使用 CSS 变量定制 Vant 的主题样式 (了解)

app.wxss 中,写入 CSS 变量,即可对全局生效

前端与移动开发----微信小程序----小程序(四)_第30张图片

所有可用的颜色变量,请参考 Vant 官方提供的配置文件

Vant 官方配置文件链接

9.7 什么是小程序 API 的 Promise 化
  1. 基于回调函数的异步 API 的缺点

    • 默认情况下,小程序官方提供的异步 API 都是基于回调函数实现的,例如,网络请求的 API 需要按照如下的方式调用

    • 这种代码的缺点是显而易见的, 容易造成回调地狱的问题,代码的可读性、维护性差!而我们就想将这种类型的代码使用 API Promise 化进行改造

      前端与移动开发----微信小程序----小程序(四)_第31张图片

  2. 什么是 API Promise

    • API Promise 化,指的是通过额外的配置,将官方提供的、基于回调函数的异步 API ,升级改造为基于 Promise 的异步 API ,从而提高代码的可读性、维护性,避免回调地狱的问题
9.8 安装并构建 miniprogram-api-promise
  1. 在小程序中,实现 API Promise 化主要依赖于 miniprogram-api-promise 这个第三方的 npm

    npm i --save [email protected]
    
  2. 下载完成,我们不能直接使用这个包,而是需要再次重新构建npm包

    • 建议在构建前先删除原有的 miniprogram_npm
    • 然后再点击工具,构建 npm
  3. 如果删除了 miniprogram_npm 目录,构建还是失败

    • 需要把 node_modulesminiprogram_npm 删除
    • 删除以后,重新安装包,重新安装以后,再次进行构建
9.9 三个步骤实现 API 的 Promise 化

前端与移动开发----微信小程序----小程序(四)_第32张图片

  1. 在小程序入口文件中调用一次 promisifyAll()方法

    import {
            promisifyAll } from 'miniprogram-api-promise'
    
  2. 声明一个常量,为一个空对象

    const wxp = wx.p = {
           }
    
  3. 调用 promisifyAll()方法

    promisifyAll(wx, wxp)
    
  4. 上述代码是什么含义呢 ?

    • promisifyAll : 做的事就是将 wx 拥有的属性方法都 copy 并改造了一份给了 wxp 这个对象
    • 然而, wxp 只是当前 js 文件的一个常量,只能在当前文件使用
    • 因此:我们在 wx 上挂载一个属性 p 让他和 wxp 指向同一个空对象
    • 在其他页面或者组件就可以通过全局对象 wx 点出 p 来访问到 wxp
    • 此时 wx.p 发起异步的请求时,得到的是一个 promise 对象
    • 那么我们就可以使用 async/await 简化 Promise 语法
// 1、导入 promisifyAll 这个方法
import {
      promisifyAll } from 'miniprogram-api-promise'

// 2、声明一个空对象 wxp
// wxp 只是一个单纯的变量,只能够在当前 js 中使用,外部不能使用
// wx 是微信小程序最顶级的对象
// 只需要往 wx 上去挂载一个对象即可
// 挂载好,以后 wxp 和 wx.p 指定的是同一个内存空间
// 也就是说 wxp 拷贝得到的 wx 的属性和方法
// wx.p 同样也是拥有的
// 调用方式: wx.p.xxxxx  即 wx.p.request({})
const wxp = wx.p = {
     }

// 3、promisifyAll 作用就是将 wx 内部的方法和属性深拷贝一份给 wxp 这个对象
promisifyAll(wx, wxp)

9.10 调用 Promise 化之后的异步 API

前端与移动开发----微信小程序----小程序(四)_第33张图片

<van-button type="warning" bindtap="getInfo">警告按钮van-button>
async getInfo () {
     
  const {
      data: res } = await wx.p.request({
     
    url: 'https://www.escook.cn/api/get',
    method: 'GET',
    data: {
     
      name: 'zs',
      age: 19
    }
  })

  console.log(res)
}
  • 此时 wx.p 发起异步的请求时,得到的是一个 promise 对象
  • 那么我们就可以使用 async/await 简化 Promise 语法
// 1、导入 promisifyAll 这个方法
import {
      promisifyAll } from 'miniprogram-api-promise'

// 2、声明一个空对象 wxp
// wxp 只是一个单纯的变量,只能够在当前 js 中使用,外部不能使用
// wx 是微信小程序最顶级的对象
// 只需要往 wx 上去挂载一个对象即可
// 挂载好,以后 wxp 和 wx.p 指定的是同一个内存空间
// 也就是说 wxp 拷贝得到的 wx 的属性和方法
// wx.p 同样也是拥有的
// 调用方式: wx.p.xxxxx  即 wx.p.request({})
const wxp = wx.p = {
     }

// 3、promisifyAll 作用就是将 wx 内部的方法和属性深拷贝一份给 wxp 这个对象
promisifyAll(wx, wxp)

如有不足,请多指教,
未完待续,持续更新!
大家一起进步!

你可能感兴趣的:(前端与移动开发学习笔记,微信小程序,前端,小程序)