微信小程序零基础入门(下)

目录

第七章、页面导航

7.1 页面导航简述

7.2 声明式导航

7.3 编程式导航

7.4 导航传参

第八章、页面事件

8.1 下拉刷新事件

8.2 上拉触底事件

第九章、生命周期

9.1 小程序生命周期

9.2 生命周期的分类

9.3 生命周期函数的应用

9.4 页面的生命周期函数

第十章、WXS脚本

10.1 WXS脚本概述

10.2 基本使用

第十一章、自定义组件

11.1 组件的创建与应用

11.2 样式

11.3 数据、方法和属性

11.4 数据监听器

11.5 纯数据字段

11.6 组件的生命周期

11.7 组件所在页面的生命周期

11.8 插槽

​ 11.9 父子组件之间的通信

11.10 behaviors(插件)

第十二章、使用npm包

12.1 概述

12.2 Vant Weapp(第三方组件库)

12.3 API Promise化

12.4 全局数据共享(MobX)

第十三章、分包

13.1 基础概念

13.2 使用分包

13.3 独立分包


内容接上:

微信小程序零基础入门(上)_❆VE❆的博客-CSDN博客

第七章、页面导航

7.1 页面导航简述

(1)什么是页面导航(可类比vue中的导航传参)

        -- 页面导航指的是页面之间的相互跳转

                · <a>链接

                · location.href

(2)小程序中实现页面导航的两种方式

        -- 声明式导航

                ·在页面上声明一个<navigator>导航组件

                ·通过点击<navigator>组件实现页面跳转

        -- 编程式导航

                · 调用小程序的导航API,实现页面的跳转

                · 通过编程式导航跳转到 tabBar 页面

wx.switchTab({
   url: '/pages/message/message'
})

                · 通过编程式导航跳转到一个<navigator>导航的正常页面组件(所有非tabBar 页面

wx.navigateTo({
   url: '/pages/info/info'
})

7.2 声明式导航

tabBar页面配置——

"tabBar": {
    "list": [
      {
        "pagePath": "pages/home/home",
        "text": "首页",
        "iconPath": "/images/tabs/home.png",
        "selectedIconPath": "/images/tabs/home-active.png"
      },
      {
        "pagePath": "pages/message/message",
        "text": "消息",
        "iconPath": "/images/tabs/message.png",
        "selectedIconPath": "/images/tabs/message-active.png"
      },
      {
        "pagePath": "pages/contact/contact",
        "text": "联系我们",
        "iconPath": "/images/tabs/contact.png",
        "selectedIconPath": "/images/tabs/contact-active.png"
      }
    ]
  },

非tabBar也页面配置——

"pages": [
    "pages/home/home",   //在tabBar配置中配置成tarBar页面
    "pages/message/message",    //在tabBar配置中配置成tarBar页面
    "pages/contact/contact",    //在tabBar配置中配置成tarBar页面
    "pages/info/info"    //非tarBar页面
  ],

(1)导航到tabBar页面

        -- tabBar页面:指的是被配置为tabBar的页面

        -- 在使用<navigator>组件跳转到指定的tabBar页面时,需要指定url属性和open-type属性:

                ·url表示要跳转的页面的地址,必须以' / '开头

                ·open-type表示跳转tabBar的方式,必须设置为switchTab

//注意url和open-type,/pages/message/message为tabBar页面
<navigator url="/pages/message/message" open-type="switchTab">
    导航到消息页面(tabBar页面)
</navigator>

(2)导航到非tabBar页面

        -- 非tabBar页面:指的是没有被配置为tabBar的页面

        -- 在使用<navigator>组件跳转到指定的tabBar页面时,需要指定url属性和open-type属性:

                · url表示要跳转的页面的地址,必须以* / *开头,路径如果带参以'?'分隔,'&'连接参数

                · open-type表示跳转的方式,必须设置为navigate

//注意url和open-type,/pages/info/info为非tabBar页面
<navigator url="/pages/info/info" open-type="navigate"> //不带参
    导航到info页面(非tarBar页面)
</navigator>

        注意:为了简便,在导航非tabBar页面时*open-type="navigate"*属性可以省略(默认)

(3)后退导航(只针对非tabBar页面)

        -- 如果要后退到上一页面或多级页面,则需要指定open-type属性和delta 属性,其中:

                ·open-type的值必须是navigateBack,表示要进行后退导航

                ·delta的值必须是数字,表示要后退的层级

//返回上一级(常用返回一级)
<navigator open-type="navigateBack">后退</navigator>

        注意:如果只是返回到上一页面,则可以省略dalta属,因为其默认值就是1

7.3 编程式导航

(1)导航到tabBar页面 --> 绑定方法,使用wx.switchTab

        -- 调用wx.switchTab(Object object)方法,跳转到tabBar页面。其中Object参数对象的属性列表如下:(导航到tabBar的页面不会携带参数)

参数类型是否必选描述
url string 必选 需要跳转的tabBar页面的路径,路径后不能带参数
successfunction非必选 接口调用成功的回调函数
failfunction 非必选 接口调用失败的回调函数
completefunction非必选

接口调用结束的回调函数(调用成功、失败都会执行)

//绑定方法(bindtap相当于click,上一篇文章讲过)
<button bindtap="gotoMessage">跳转Message页面</button>
//方法,导航到tabBar页面
gotoMessage() {
  wx.switchTab({
    url: '/pages/message/message'
  })
},

(2)导航到非tabBar页面

        -- 调用wx.navigateTo(Object object)方法,跳转到非tabBar的页面。其中Object 参数对象的属性列表,如下:

参数类型是否必选描述
url string 必选 需要跳转的非tabBar页面的路径,路径后能带参数
successfunction非必选 接口调用成功的回调函数
failfunction 非必选 接口调用失败的回调函数
completefunction非必选

接口调用结束的回调函数(调用成功、失败都会执行)

        --> 与导航到tabBar页面区别url路径可以携带参数

<button bindtap="gotoInfo">跳转到info页面</button>
//导航到非tabBar页面的方法
gotoInfo() {
  wx.navigateTo({
    url: '/pages/info/info' //不带参
  })
},

(3)后退导航(只针对非tabBar页面)

        -- 调用wx.navigateBack(Object object)方法,可以返回上一页面或多级页面。其中Object参数对象可选的:

属性类型默认值必填描述
 delta number1非必选返回的页面数,如果delta大于现有页面数,则返回到首页
<button bindtap="goBack">后退</button>
goBack() {
  wx.navigateBack({
    delta: 1
  })
},

7.4 导航传参

(1)声明式导航传参(可类比vue的传参)

        -- navigate组件的url属性用来指定将要跳转的页面路径。同时,路径后面是可以携带参数的:

                ·参数与路径之间使用"?"分隔

                ·参数键值对使用=相连

                ·不同的参数使用"&"分隔

<navigator url="/pages/info/info?name=zs&age=20"> //带参
    跳转到info页面(非tarBar页面)
</navigator>

(2)编程式导航传参

        -- 调用wx.navigateTo(Object object)方法,可以携带参数,在URL上:

        -- 绑定方法,bindtap

<button bindtap="gotoInfo2">跳转到info页面(非tarBar页面)</button>
gotoInfo2() {
  wx.navigateTo({
    url: '/pages/info/info?name=ls&gender=男' //带参
  })
},

(3)在onLoad中接收导航参数

        -- 通过声明式导航传参或者编程式导航传参所携带的参数,可以直接在onLoad事件中直接获取到--->也就是onLoad中的options参数。

        -- 为了使这个参数可以在每一个方法中使用,会利用this.setData在data中存储该参数,命名query

//data中存储数据
data: {
  // 导航传递过来的参数对象
  query: {}
},
//onLoad生命周期获取传过来的参数对象
onLoad: function (options) {
  console.log(options)
  this.setData({    //利用this.setData修改data中的数据
    query: options
  })
},

第八章、页面事件

8.1 下拉刷新事件

(1)什么是下拉刷新

        -- 下拉刷新是移动端的专有名词,指的是通过手指在屏幕上的下拉滑动操作,从而重新加载页面数据的行为

(2)启用下拉刷新

        -- 在页面的.json文件中,设置enablePullDownRefresh为true

"enablePullDownRefresh": true

(3)配置下拉刷新窗口的样式

        -- backgroundColor -->下拉刷新窗口的背景颜色,16进制

        -- backgroundTextStyle -->下拉刷新loading的样式,仅支持dark和light

"backgroundColor": "#efefef",
"backgroundTextStyle": "dark"

(4)监听下拉刷新的事件

        -- 在页面.js文件中,通过onPullDownRefresh()函数即可监听当前页面的下拉刷新事件。

(5)停止下拉刷新

        -- 真实情况中,当完成下拉之后loading还会显示,不会消失,所有需要手动隐藏效果。调用wx.stopPullDownRefresh()可以停止当前页面下拉刷新

//当前页面的下拉刷新事件在该生命周期钩子执行
onPullDownRefresh: function () {
  
  //停止当前页面下拉刷新
  wx.stopPullDownRefresh()
},

8.2 上拉触底事件

(1)什么是上拉触底

        -- 上拉触底是移动端的专有名词,通过手指在屏幕上的上拉滑动操作,从而加载更多数据的行为

(2)监听页面的上拉触底事件

        -- 在页面的.js文件中,通过onReachBottom()函数即可监听当前页面的上拉触底事件。

            注意:要使用节流防止多次发送请求

(3)对上拉触底进行节流处理

        -- data中定义isLoading节流阀

                · isLoading中布尔值

                · true 当前正在进行数据请求

                · false 当前没有进行数据请求

data: {
  isloding: false
},

        -- 修改isLoading节流阀的值

                · 在调用方法时将节流阀设置为true

                · 在网络请求的complete回调函数中,将节流阀重置为false

//获取颜色为例子
getColors() {
  //首先将节流阀设置为true
  this.setData({
    isloding: true
  })
  // 需要展示 loading 效果
  wx.showLoading({
    title: '数据加载中...'
  })
  //请求数据
  wx.request({
    url: 'https://……/api/color',
    method: 'get',
    success: ({ data: res }) => {
      this.setData({
        colorList: [...this.data.colorList, ...res.data]
       })
     },
     //数据请求成功/失败,将节流阀设置为false
     complete: () => {
       wx.hideLoading()
       this.setData({
         isloding: false
       })
     }
})

        -- 在onReachBottom中判断节流阀的值,从而对数据请求进行节流控制

                · 如果节流阀值为true,阻止

                · 否则,允许

//在上拉刷新的生命周期钩子函数中
onReachBottom: function () {
  //如果节流阀不是false(也就是说数据还在请求中),不放行,不发送多次请求
  if (this.data.isloding) return
  //true,发送请求
  this.getColors()
},

第九章、生命周期

9.1 小程序生命周期

        -- 一个对象从创建->运行->销毁的整个阶段,强调的是一个时间段

        -- 生命周期函数:是小程序提供的内置函数,会伴随着生命周期,自动按次序执行

        -- 作用:允许程序员在特定的时间点,执行某些特定的操作。

9.2 生命周期的分类

        -- 在小程序中,生命周期分为两类,分别是:

        (1)应用生命周期

                ·特指小程序从启动->运行->销毁的过程

        (2)页面生命周期

                ·特指小程序中,每个页面的加载->渲染->销毁的过程

        注意:其中页面的生命周期范围较小,应用程序的生命周期范围较大

        小程序启动->页面A的生命周期->页面B的生命周期->···->小程序结束

9.3 生命周期函数的应用

(1)小程序的应用生命周期函数需要在根目录app.js中进行声明:

onLaunch当小程序初始化完成时,会触发 onLaunch(全局只触发一次)
onShow当小程序启动,或从后台进入前台显示,会触发 onShow
onHide当小程序从前台进入后台,会触发 onHide

(2)使用方法:

App({
    //当小程序初始化完成时,会触发 onLaunch(全局只触发一次)
    onLaunch(){},
    //当小程序启动,或从后台进入前台显示,会触发 onShow
    onShow(){},
    //当小程序从前台进入后台,会触发 onHide
    onHide(){}
})

9.4 页面的生命周期函数

(1)小程序的页面生命周期函数需要在页面的.js文件中进行声明:

onLoad监听首次页面加载,只调用1次(常用)
onReady监听页面初次渲染完成,只调用一次(常用)
onShow监听页面显示
onHide监听页面隐藏
onUnload监听页面卸载

(2)使用方法:

page({
  //生命周期函数--监听页面加载
  onLoad() {},
  //生命周期函数--监听页面初次渲染完成
  onReady() {},
  //生命周期函数--监听页面显示
  onShow() {},
  //生命周期函数--监听页面隐藏
  onHide() {},
  //生命周期函数--监听页面卸载
  onUnload() {},
})

第十章、WXS脚本

10.1 WXS脚本概述

(1)应用场景(wxs类似于js)

        -- wxml中无法调用在页面的.js中定义的函数,但是,wxml中可以调用wxs中定义的函数,因此,小程序中,wxs的典型应用场景就是过滤器

10.2 基本使用

(1)内嵌wxs脚本

        -- wxs代码可以编写wxml文件中的<wxs>标签内,就像html中<script>标签一样

        -- <wxs>标签,必须提供module属性,用来指定当前wxs的模块名称

<view>{{m1.toUpper(username)}}</view>
//在wxs中写方法
<wxs module="m1">
  module.exports.toUpper = function(str) {
    return str.toUpperCase()
  }
</wxs>

(2)定义外联的wxs脚本

        --wxs 代码还可以编写在以.wxs为后缀名的文件内,就像javascript代码可以编写在以.js为后缀名的文件中

        --使用:

                在wxml中引入外联的wxs脚本时,必须为<wxs>标签添加module和src属性

                · *module*用来指定模块的名称

                · *src*用来指定要引入的脚本的路径,且必须是相对路径

<view>{{m2.toLower(country)}}</view>
//导入外部写好的.wxs方法
<wxs src="../../utils/tools.wxs" module="m2"></wxs>

第十一章、自定义组件

11.1 组件的创建与应用

(1)创建组件(类似Vue中的共享组件和路由)

        -- 在项目的根目录中,鼠标右键,创建components -> test文件夹

        -- 在新建的components -> test文件夹上,鼠标右键,点击“新建Component"

        -- 键入组件的名称之后回车,会自动生成组件对应的4个文件,后缀名分别为.js,.json,.wxml和.wxsSs

(2)引用组件

        -- 组件的引用方式分为局部引用全局引用

                · 局部引用:组件只能在当前被引用的页面内使用-->当前页面

                · 全局引用:组件可以在每个小程序页面中使用-->多个页面

(3)局部引用--->在页面的.json配置文件中引用组件的方式,叫做局部引用

"usingComponents": {

     键(自定义名字):"值(组件路径)"

}

        配置之后只有该页面可是使用配置的组件

(4)全局引用-->在app.json 全局配置文件中引用组件的方式,叫做“全局引用”,所有页面都能使用

"usingComponents": {

  键(自定义名字):"值(组件路径)"

}

"usingComponents": {
  "my-test1": "/components/test/test",
  "my-test2": "/components/test2/test2",
  "my-test3": "/components/test3/test3",
  "my-test4": "/components/test4/test4",
  "my-test5": "/components/test5/test5"
}

(5)组件与页面的区别

        -- 组件与页面的.js和.json文件不相同

            ·组件的.json文件需要声明"component": true页面不需要声明

            ·组件的.js文件中调用的是Component()函数;页面page()函数

            ·组件的事件处理函数需要定义到methods节点中;页面直接定义方法

11.2 样式

(1)组件样式隔离(相当于scoped)

        优点:防止外界的样式影响组件内部的样式;防止组件的样式破环外界的样式

(2)组件样式隔离的注意点

        -- app.wxss中的全局样式对组件无效

        -- 只有class选择器有样式隔离的效果,id选择器、属性选择器、标签选择器不受样式隔离的影响。所以在写样式时,尽量都使用class选择器

(3)修改组件的样式隔离选项

        -- 自定义组件的样式隔离特性能够防止组件内外样式互相干扰的问题。为了解决外部能够控制组件内部的样式,可以通过styleIsolation修改组件的样式隔离选项

用法一:

Component({
  options: {
    styleIsolation: 'islated/apply-shared/shared'
  },
})

用法二:组件的.json文件中新增如下配置

{ "styleIsolation":'islated/apply-shared/shared' }

---styleIsolation的三个可选值

islated表示启用样式隔离,组件内外使用class指定样式不会相互影响,默认值
apply-shared表示*页面wxss样式将影响到自定义组件*,但是自定义组件不会影响页面样式
shared互相影响

11.3 数据、方法和属性

(1)data数据

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

(2)methods方法

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

        -- 注意:区分事件处理函数(正常定义)和自定义方法(以下划线开头)

(3)properties属性(类似Vue中的props)

        -- 在小程序组件中,properties是组件的对外属性,用来接收外界传递到组件中的数据

        · 简化的方式,无法设置默认值

        · 完整定义

properties: {
    // 第一种方式:简化的方式
    // '自定义名':数据类型
    max: Number
    // 第二种方式:完整的定义方式
    /*
        自定义名:{
            type:数据类型,
            value:默认值
        }
    */
    max: {
      type: Number,
      value: 10 //设置默认值
    }
  },

        · 获取:this.properties.xxx

//this.properties.自定义的名字
this.properties.max

(4)data和properties的区别

        -- 小程序的组件中,properties属性和data数据的用法相同,它们都是可读可写的,只不过:

                · data更倾向于存储组件的私有数据

                · properties更倾向于存储外界传递到组件中的数据

(5)使用setData修改properties的值

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

this.setData({
  count: this.data.count + 1, //对data中的数据进行更新
  max: this.properties.max + 1 //对properties中的数据进行更新
})

11.4 数据监听器

(1)什么是数据监听器(类似Vue中的watch)

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

(2)数据监听器基本用法

        添加observers:{'监听对象':function(新的监听对象){对其执行一些事}},

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

(3)监听对象属性的变化

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

        -- 数据监听器支持监听对象中单个多个属性的变化,示例语法如下:

observers:{
  '对象.属性A,对象.属性B':function(属性A的新值,属性B的新值){
    对其执行一些事
  }
}
observers: {
   '_rgb.r, _rgb.g, _rgb.b': function (r, g, b) {
      this.setData({
        fullColor: `${r}, ${g}, ${b}`
      })
   },
},

(4)监听对象中所有属性的变化

        --如果某个对象中需要被监听的属性太多,为了方便,可以使用通配符"**"监听对象中所有属性的变化,**最后获取的是一整个对象里的值

*'rgb.**':function(obj)*

observers: {
   '_rgb.**': function (obj) {
      this.setData({
        fullColor: `${obj.r}, ${obj.g}, ${obj.b}`
      })
   }
},

11.5 纯数据字段

(1)什么是纯数据字段-->中介值

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

(2)使用规则

        -- 在Component构造器的options节点中,指定pureDataPattern为一个正则表达式,字段名符合这个正则表达式的字段将成为纯数据字段。

        -- option中配置pureDataPattern:/^_/

//配置如下
options: {
    pureDataPattern: /^_/
},

        -- 配置之后,所有纯数据字段,以_开头,例如:_rgb

11.6 组件的生命周期

(1)组件的全部生命周期函数(components文件下的组件的.js文件)

生命周期函数 参数描述说明
created在组件实例刚刚被创建时执行
attached在组件实例进入页面节点树时执行
ready 在组件在视图层布局完成后执行
moved 在组件实例被移动到节点树另一个位置时执行
detached在组件实例被从页面节点树销毁时执行
errorobject Error每当组件方法抛出错误时执行

(2)组件的主要生命周期函数

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

        -- 组件实例刚被创建好的时候,created生命周期函数会被触发

                · 此时还不能调用setData

                · 通常在这个生命周期函数中,只应该用于给组件的this添加一些自定义的属性字段

        -- 在组件完全初始化完毕、进入页面节点树后,attached 生命周期函数会被触发(类似mounted)

                · 此时,this.data已被初始化完毕

                · 这个生命周期很有用绝大多数初始化的工作可以在这个时机进行(例如发请求获取初始数据)

        -- 在组件离开页面节点树后,detached生命周期函数会被触发(类似Vue中的beforDestory)

                · 退出一个页面时,会触发页面内每个自定义组件的detached生命周期函数此时

                · 适合做一些清理性质的工作

(3)lifetimes节点

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

lifetimes:{
  created(){}
  attached(){}
  ready(){}
  moved(){}
  detached(){}
}

11.7 组件所在页面的生命周期

(1)什么是组件所在页面的生命周期

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

        -- 组件所在页面的生命周期函数有3个,分别是:

生命周期函数参数描述
show组件所在的页面被展示时执行
hide组件所在的页面被隐藏时执行
resizeobject Size组件所在的页面尺寸变化时执行

(2)pageLifetimes节点

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

pageLifetimes: {
  show() {
    console.log('show')
  },
  hide() {
    console.log('hide')
  },
  resize(size) {
    console.log('resize',size)
  }
}

11.8 插槽

(1)什么是插槽(类比vue中的slot)

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

(2)单个插槽

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

<view>
  <slot></slot>
</view>

(3)启用多个插槽

        -- 在小程序的自定义组件中,需要使用多<slot>插槽时,可以在组件的.js文件中,通过multipleSlots:true启用

Component({
  options:{
    multipleSlots:true
  },
})

(4)定义多个插槽

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

//组件的wxml中
<view>
  <slot name="before"></slot>
  <view>这里是组件的内容结构</view>
  <slot></slot>
  <slot name="after"></slot>
</view>

        -- 使用组件时:

<my-test4>
  <view>这是通过插槽插入</view>
  <view slot="before">这里是插多个插槽的地方befor</view>
  <view slot="after">这里是插多个插槽的地方after</view>
</my-test4>

          --得到的效果

​ 11.9 父子组件之间的通信

(1)父子组件之间的三种通信方式

        -- 属性绑定

                · 用于父组件向子组件的指定属性设置数据,仅能设置JSON兼容的数据

        -- 事件绑定

                · 用于子组件向父组件传递数据,可以传递任意数据

        -- 获取组件实例

                · 父组件还可以通过this.selectComponent()获取子组件实例对象

                · 这样就可以直接访问子组件的任意数据和方法

(2)属性绑定(父->子传数据)

        -- 属性绑定用于实现父向子传值,而且只能传递普通类型的数据无法将方法传递给子组件。

        · 父组件做的事

data: {
    count:1
}
<view>~~~父组件~~~</view>
<view>父组件中的count值是{{count}}</view>
<view>~~~子组件~~~</view>
<my-test count="{{count}}" class="sc" id="sc"></my-test>

        · 子组件做的事

//接收父组件传的值
properties: {
    count:Number
},

(3)事件绑定(子向父传数据)

        -- 事件绑定用于实现子向父传值,可以传递任何类型的数据。使用步骤如下:

data: {
    count:1
}

             · 在父组件的js中,定义一个函数,这个函数即将通过自定义事件的形式,传递给子组件

//父组件定义syncCount方法,之后将该方法传给子组件
syncCount(){
  console.log('syncCount')
},

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

<view>~~~父组件~~~</view>
<view>父组件中的count值是{{count}}</view>
<view>~~~子组件~~~</view>
<my-test5 count="{{count}}" bind:sync="syncCount" class="sc" id="sc"></my-test5>

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

//接收父组件传的值
properties: {
    count: Number
},
//子组件修改数据,之后将数据返回父组件
addCount(){
    //修改子组件数据
    this.setData({
      count:this.properties.count+1
    })
    // 触发父组件传过来的自定义事件,将数据发送到父组件
    this.triggerEvent('sync',{value:this.properties.count})
}

            · 在父组件的js 中,通过e.detail.value获取到子组件传递过来的数据

// 定义一个接收子组件数据的方法
syncCount(e){
  console.log("自定义事件的参数",e)
  this.setData({
    //e.detail.value,获取子组件传过来的值
    count:e.detail.value
  })
},

        -- 自定义事件-->使用bind:自定义事件名称

(4)获取组件实例(子父之间通过组件选择器任意传值)

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

        · 例如 child = this.selectComponent("#sc"),之后可以访问子组件中所有的方法和属性(包括原型链中)

// 获取子组件实例,子组件中的所有方法
getChild() {
    const child = this.selectComponent('#sc')
    console.log(child)
    child.addCount()
},

11.10 behaviors(插件)

(1)什么是behavior

        -- behaviors是小程序中,用于实现组件间代码共享的特性,类似于vue 中的mixins

(2)behaviors的工作方式

        -- 每个 behayior可以包含一组属性、数据、生命周期函数和方法组件引用它时,它的属性、数据和方法会被合并到组件

(3)创建behaviors

        -- 根目录下新建一个behavior文件夹,装所有需要共享的代码

        -- 调用Behavior(Object object)方法即可创建一个共享的behavior实例对象,并向外暴露

module.exports = Behavior({
  data: {
    username: 'zs'
  },
  properties: {},
  methods: {},
  ……
})

(4)导入并使用behavior

        -- 在组件中,使用require()方法导入需要的 behavior,组件内使用behaviors挂载即可访问behavior中的数据或方法

//引入需要的behaviors
const myBehavior = require('../../behaviors/my-behavior')
Component({
  //挂载
  behaviors: [myBehavior],
})

(5)behavior中所有可用的节点

可用的节点类型是否必填 描述
propertiesobject Map同组件的属性
dataobject否 同组件的数据
methodsobject否 同自定义组件的方法
behaviorsstring Array否 引入其它的behavior
createdFunction 否 生命周期函数
attachedFunction 否 生命周期函数
readyFunction 否  生命周期函数
movedFunction 否 生命周期函数
detachedFunction 否 生命周期函数

第十二章、使用npm包

12.1 概述

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

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

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

                ·不支持依赖于浏览器内置对象的包

                ·不支持依赖于C++插件的包

12.2 Vant Weapp(第三方组件库)

官网:Vant Weapp - 轻量、可靠的小程序 UI 组件库

(1)什么是Vant Weapp

        -- Vant weapp是有赞前端团队开源的一套小程序UI组件库,助力我们快速搭建小程序应用。它所使用的是MIT开源许可协议,对商业使用比较友好。

(2)安装Vant组件库

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

                ·通过npm安装(建议指定版本为@1.3.3)

         右键-->内部终端打开-->npm init -y(初始化)-->npm i @vant/weapp@1.3.3 -S --production

                ·构建npm包:工具-->构建npm包

                 ·修改app.json:去除"style": "v2"

(3)使用Vant组件

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

"usingComponents": {
    "van-button": "@vant/weapp/button/index",
    "van-tabbar": "@vant/weapp/tabbar/index",
    "van-tabbar-item": "@vant/weapp/tabbar-item/index",
},

(4)定制全局主题样式

        -- 在app.wxss中,找到要改的元素,写入CSS变量

page{
  --button-danger-background-color:#c00000;
  --button-danger-border-color:#D60000;
}

        -- 注意:定义CSS变量方式:以--开头

        -- 样式修改查看文档:

vant-weapp/var.less at dev · youzan/vant-weapp · GitHub

12.3 API Promise化

(1)基于回电函数的异步API的缺点

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

wx.request({
  url: '',  //路径
  method:'',  //请求方法
  data:'',  //参数
  success:()=>{}, //成功时回调
  fail:()=>{},  //失败时回调
  complete:()=>{}  //完成时回调
})

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

(2)什么时API Promise化

APl Promise化,指的是*通过额外的配置*,将官方提供的、基于回调函数的异步API,*升级改造为基于Promise的异步API*,从而提高代码的可读性、维护性,避免回调地狱的问题。

(3)如何实现API Promise化

        -- 在小程序中,实现 APl Promise化主要依赖miniprogram-api-promise这个第三方的npm包。

        -- npm i -S miniprogram-api-promise@1.0.4

        -- 之后需要重新构建npm包

                · 在小程序入口文件中(app.js),只需调用一次promisifyAll()方法

                · 引用

//导入 promisifyAl1()方法
import {promisifyAll} from 'miniprogram-api-promise'
const wxp = wx.p = {}
promisifyAll(wx,wxp)

(4)调用Promise化之后的异步API

<!--页面的.wxml,绑定事件方法getPInfo-->
<van-button type="primary" bindtap="getPInfo">主要按钮</van-button>
//定义getPInfo方法,之后所有的wx.xxx 都修改成 wx.p.xxx
// 调用Promise化之后的异步API
async getPInfo(){
  const {data:res} = await wx.p.request({
    url:'https://xxx/api/get',
    method:'GET',
    data:{
      name:'xx',
      age:18
    }
  })
  console.log("调用Promise化之后的异步API",res)
},

12.4 全局数据共享(MobX)

(1)什么是全局数据共享(Vue中的Vuex)

        -- 全局数据共享(又叫做:状态管理)是为了解决组件之间数据共享的问题。

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

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

                ·mobx-miniprogram用来创建Store实例对象(类似先下载vuex包)

                ·mobx-miniproaram-bindings用来把Store中的共享数据或方法,绑定到组件或页面中使用(创建小仓库)

(3)安装MobX相关的包

        (1)安装

npm i -S mobx-miniprogram@4.13.2 mobx-miniprogram-bindings@1.2.1

        (2)引用

import {observable} from 'mobx-miniprogram'

(4)store中的常用方法

        -- 数据字段

export const store = observable({
  numA:1,
  numB:2,
})

        -- 计算属性(get属性)

export const store = observable({
  // 计算属性
  get sum(){
    return this.numA+this.numB
  },
})

        -- action方法,专门用来修改store中数据

export const store = observable({
  // action方法,用来修改store中数据
  updataNum1:action(function (params) {
    this.numA += params
  }),
  updataNum2:action(function (params) {
    this.numB += params
  }),
})

(5)将Store中的成员绑定到页面

        -- 导入对应的文件

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

        -- 在页面.js文件onLoad生命周期函数引入共享数据

onLoad(options) {
   this.storeBindings = createStoreBindings(this,{
      store,
      fields:['numA','numB','sum'],
      actions:['updataNum1','updataNum2']
   })
},

        -- 在页面的.js文件的onUnload生命周期函数注销

onUnload() {
  this.storeBindings.destroyStoreBindings()
},

(6)在页面使用Store中的成员

        -- 数据和计算属性(field中的所有值):可以直接在页面上使用

        -- 方法(actions):则是绑定事件后在当前.js文件调用

(7)将Store中的成员绑定到组件中-->组件中

        -- 导入对应的包

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

        -- 通过storeBindingsBehavior实现自动绑定

Component({
  behaviors:[storeBindingsBehavior],
})

        -- 使用storeBindings获取共享的数据源

storeBindings:{
  //数据源
  store, //指定要绑定的Store
  fields:{  //指定要绑定的字段数据
    // 自定义名字:'共享数据的名字'
    numA:()=>store.numA,   //绑定字段的第1种方式
    numB:(store)=>store.numB,   //绑定字段的第2种方式
    sum:'sum'     //绑定字段的第3种方式
  },
  actions:{  //指定要绑定的方法
    updataNum2:'updataNum2'
  }
},

(8)在页面使用Store中的成员

        -- 数据和计算属性(field中的所有值):可以直接在组件上使用

        -- 方法(actions):则是绑定事件后在当前.js文件的methods中的函数调用

第十三章、分包

13.1 基础概念

(1)什么是分包

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

(2)分包的好处

        -- 可以优化小程序首次启动的下载时间

        -- 在多团队共同开发时可以更好的解耦协作

(3)分包前项目的构成

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

(4)分包后的项目构成

        -- 分包后,小程序项目由1个主包+多个分包组成:

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

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

(5)分包的加载规则

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

                ·tabBar页面需要放到主包中

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

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

(6)分包体积限制

        -- 目前小程序的大小有一下两个限制:

                ·整个小程序所有非分包大小,不超过16M(主包+所有分包)

                ·单个分包/主包大小不能超过2M

13.2 使用分包

(1)使用目的:小程序项目中所有的页面和资源都被打包到了一起,导致整个项目体积过大,影响小程序首次启动的下载时间,使用分包之后能按需加载,优化

        配置方法:app.json添加配置项subPackages——

"subPackages": [
  {
    "root": "pagA", //根目录
    "name": "p2",   //给该包命名代替
    "pages": [
      "pages/cat/cat", //根目录下的分包
      "pages/dog/dog"
    ]
  },
  {},
  ……,
  {}
]

(2)分包的打包原则

        -- 小程序会按subpackages的配置进行分包,subpackages之外的目录将被打包到主包中

        -- 主包也可以有自己的 pages(即最外层的pages字段)

        -- tabBar页面必须在主包内

        -- 分包之间不能互相嵌套

(3)引用原则

        -- 主包无法引用分包内的私有资源

        -- 分包之间不能相互引用私有资源

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

13.3 独立分包

(1)什么是独立分包

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

(2)独立分包和普通分包的区别

        最主要的区别是:是否依赖于主包才能运行

        -- 普通分包必须依赖于主包才能运行

        -- 独立分包可以在不下载主包的情况下,独立运行

(3)独立分包的应用场景

        -- 开发者可以按需,将某些具有一定功能独立性的页面配置到独立分包中。原因如下:

                · 当小程序从普通的分包页面启动时,需要首先下载主包

                · 而独立分包不依赖主包即可运行,可以很大程度上提升分包页面的启动速度

         注意:一个小程序可以有多个独立分包

(4)独立分包的配置方法

        -- 与普通分包配置一样,但是区别在于,独立分包需要添加配置项:"independent": true

"subPackages": [
    //独立分包
    {
      "root": "pagB",
      "name": "p2",
      "pages": [
        "pages/apple/apple"
      ],
      //配置独立分包
      "independent": true
    }
  ],

(5)引用原则

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

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

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

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

                ·特别注意:独立分包中不能引用主包内的公共资源(与普通分包的区别)

  • 9
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值