微信小程序学习笔记

      • 1. 小程序-起步
        • 1.1 小程序简介
          • 1.1.1 小程序与普通网页开发的区别
        • 1.2 第一个小程序
        • 1.3 小程序代码的构成
        • 1.4 小程序的宿主环境
          • 1.4.1 什么是宿主环境
          • 1.4.2 小程序的宿主环境
          • 1.4.3 小程序宿主环境包含的内容
      • 2. 小程序-模板与配置
        • 2.1 使用WXML模板语法渲染页面结构
          • 2.1.1 数据绑定
          • 2.1.2 事件绑定
          • 2.1.3 条件渲染
          • 2.1.4 列表渲染
        • 2.2 使用WXSS样式美化页面结构
          • 2.2.1 rpx
          • 2.2.2 样式导入
          • 2.2.3 全局样式和局部样式
        • 2.3 使用app.json对小程序进行全局配置
          • 2.3.1 全局配置文件及常用的配置项
          • 2.3.2 window节点常用的配置项
          • 2.3.3 tabBar
        • 2.4 使用page.json对小程序页面进行个性化配置
        • 2.5 发起网络数据请求
          • 2.5.1 GET和POST请求
      • 3. 小程序-视图与逻辑
        • 3.1 页面导航
          • 3.1.1 声明式导航
          • 3.1.2 编程式导航
          • 3.1.3 导航传参
        • 3.2 页面事件
          • 3.2.1 下拉刷新
          • 3.2.2 上拉触底事件
          • 3.2.3 自定义编译模式
        • 3.3 生命周期
          • 3.3.1 生命周期与声明周期函数
        • 3.4 WXS脚本
          • 3.4.1 WXS与JavaScript的关系
          • 3.4.2 基础语法
      • 4. 小程序-基础加强
        • 4.1 自定义组件
          • 4.1.1 组件的创建与引用
          • 4.1.2 样式
          • 4.1.3 数据、方法和属性
          • 4.1.4 数据监听器
          • 4.1.5 纯数据字段
          • 4.1.6 组件的生命周期
          • 4.1.7 组件所在页面的生命周期
          • 4.1.8 插槽
          • 4.1.9 父子组件之间的通信
          • 4.1.10 behaviors
        • 4.2 使用npm包
          • 4.2.1 Vant Weapp
          • 4.2.2 API Promise化
        • 4.3 全局数据共享
          • 4.3.1 MobX
        • 4.4 分包
          • 4.4.1 概念
          • 4.4.2 分包的基本用法
          • 4.4.3 独立分包
          • 4.4.4 分包预下载
        • 4.5 自定义tabBar

1. 小程序-起步

1.1 小程序简介

1.1.1 小程序与普通网页开发的区别
  1. 运行环境不同:网页运行在浏览器环境中,小程序运行在微信环境中
  2. API不同:由于运行 环境的不同,小程序无法调用DOM和BOM的API
  3. 开发模式不同:网页的开发模式–>浏览器+代码编辑器;小程序的开发模式–>申请小程序开发账号,安装小程序开发工具,创建和配置小程序项目

1.2 第一个小程序

  1. 注册小程序开发账号:使用浏览器打开: https://mp.weixin.qq.com 网址,点击右上角的"立即注册",即可进入小程序开发账号的注册流程,完成相关流程。

  2. 获取小程序的AppID:扫码登入网址后->点击开发->开发设置->AppID

  3. 下载开发者工具:https://developers.weixin.qq.com/miniprogram/dev/devtools/stable.html

  4. 安装成功后,扫码登录

1.3 小程序代码的构成

微信小程序学习笔记_第1张图片

  1. App.json 文件

    app.json是当前⼩程序的全局配置,包括了⼩程序的所有⻚⾯路径、界⾯表现、⽹络超时时间、底部tab等。普通快速启动项⽬⾥边的app.json配置

    {  
        "pages":[    
            "pages/index/index",    
            "pages/logs/logs" 
        ],  
        "window":{    
            "backgroundTextStyle":"light",    
            "navigationBarBackgroundColor": "#fff",    
            "navigationBarTitleText": "WeChat",   
            "navigationBarTextStyle":"black" 
        },
        "style":"v2",
       "sitemapLocation":"sitemap.json"
    }
    

    字段的含义:

    • pages字段⽤于描述当前⼩程序所有⻚⾯路径,这是为了让微信客⼾端知道当前你的⼩程序⻚⾯定义在哪个⽬录。
    • window字段定义⼩程序所有⻚⾯的顶部背景颜⾊,⽂字颜⾊定义等。
    • style:全局定义小程序组件所使用的样式版本
    • sitemapLocation:用来指明sitemap.json的位置
  2. sitemap.json文件

    sitemap的索引提示是默认开启的,如需要关闭sitemap的索引提示,可在小程序项目配置文件project.config.jsonsetting中配置字段checkSiteMapfalse

  3. 页面的.json文件

    页面中的配置会覆盖app.json的window中相同的配置项

    微信小程序学习笔记_第2张图片

1.4 小程序的宿主环境

1.4.1 什么是宿主环境

​ 宿主环境:指的是程序运行所必须的依赖环境,脱离了宿主环境的软件是没有任何意义的

1.4.2 小程序的宿主环境

​ 手机微信就是小程序的宿主环境,小程序借助宿主环境提供的能力,可以完成许多普通网页无法完成的功能

1.4.3 小程序宿主环境包含的内容
  1. 通信模型

    • 小程序通信的主体是逻辑层和渲染层,其中:WXML模板和WXSS样式工作在渲染层,JS脚本工作在逻辑层

    • 小程序的通信模型:逻辑层和渲染层之间的通信(由微信客户端进行转发);逻辑层和第三方服务器之间的通信(由微信客户端进行转发)

  2. 运行机制

    • 小程序启动过程:下载代码包到本地–>解析app.json全局配置文件–>执行app.js小程序入口文件,调用App()创建小程序实例–>渲染小程序首页–>小程序启动完成

    • 页面渲染过程:加载解析页面的.json配置文件–>加载页面的.wxml模板和.wxss样式–>执行页面的.js文件,调用Page()创建页面实例–>页面渲染完成

  3. 组件

    • 容器类组件:view(普通视图区域,类似于div,是块级元素,用来实现页面的布局效果);scroll-view:(可滚动的视图区域,常用来实现滚动列表效果);swiper和swiper-item(轮播图组件和轮播图item组件)

      如下是swiper的属性:

      微信小程序学习笔记_第3张图片

    • 基础类组件:text(文本文件,类似于span,是行内元素,text的selectable属性,实现长按选中文本内容);rich-text(富文本文件,通过组件的nodes属性结点,把HTML字符串渲染为对应的UI结构)

      nodes属性设置:

      微信小程序学习笔记_第4张图片

    • button(按钮组件,通过open-type属性可以调用微信提供的各种功能)

      微信小程序学习笔记_第5张图片

      微信小程序学习笔记_第6张图片

    • img(图片组件,默认width=300px,height=240px,支持懒加载)

      微信小程序学习笔记_第7张图片

      微信小程序学习笔记_第8张图片

    • navigator(页面导航组件,类似于a标签)

      微信小程序学习笔记_第9张图片

  4. API

    • 事件监听API:以on开头,用来监听某些事件的触发,如:wx.onWindowResize(function callback)监听窗口尺寸变化的事件
    • 同步API:以Sync结尾的API,同步API的执行结果,可以通过函数返回值直接获取,如果执行出错会抛出异常,如:wx.setStorageSync(‘key’,‘value’) 向本地存储中写入内容
    • 异步API:类似jquery中的**$.ajax(options)**函数,需要通过success、fail、complete接收调用的结果,如:wx.request() 发起网络数据请求,通过success回调函数接收数据

2. 小程序-模板与配置

2.1 使用WXML模板语法渲染页面结构

2.1.1 数据绑定
  1. 数据绑定的基本原则

    • 在data中定义数据
    • 在WXML中使用数据
  2. 在data中定义页面的数据:在页面对应的js文件中,把数据定义到data对象中即可

    Page({
        data: {
            info:'hello world'
        },
    })
    
  3. Mustache语法的格式:把data中的数据绑定到页面中渲染,使用Mustache语法(双大括号)将变量包起来即可

    {{info}}

  4. Mustache语法的应用场景:绑定内容、绑定属性、运算

  5. 动态绑定内容:{{info}}

  6. 动态绑定属性:

    Page({
        data: {
            imgSrc:'http://www.itheima.com/images/logo.png'
         },
    })
    <image src="{{imgSrc}}"></image>
    
  7. 三元运算:

  8. 算数运算:randomNum:Math.random().toFixed(2)

2.1.2 事件绑定
  1. 常用事件
类型 绑定方式 事件描述
tap bindtap或bind:tap 手指触摸后马上离开,类似于HTML中的click时间
input bindinput或bind:input 文本框的输入事件
change bindchange或bind:change 状态改变时触发
  1. 事件对象的属性列表

    微信小程序学习笔记_第10张图片

    其中,target是触发该事件的源头组件,而currentTarget则是当前事件所绑定的组件

  2. bindtap的语法格式

    <input bindinput="handleInput" />	<!-- wxml -->
    Page({  // js
        // 绑定的事件  
        handleInput: function(e) {    
            console.log(e);    
            console.log("值被改变了"); 
        }
    })
    
  3. 在事件处理函数中为data中的数据赋值

    通过调用this.setData(dataObject)方法,可以给页面data中的数据重新赋值,实例如下

    Page({
      data: {
        count:0
      },
      // 修改count的值
      changeCount(){
        this.setData({
          count:this.data.count+1
        })
      },
    })
    
  4. 事件传参

    不能在绑定事件的同时为事件处理函数传递参数,可以通过为组件提供data-*自定义属性传参,其中的*代表的是参数的名字,在事件处理函数中,可以通过even.target.dataset.参数名即可获取到具体参数的值,实例代码如下:

    <!-- wxml -->
    <button type="primary" data-currentCount="{{2}}" bindtap="btnTap2">+2</button> 
    <!-- js -->
    btnTap2(e){
        this.setData({
            count:this.data.count+e.target.dataset.current
        })
    }
    

    注意:data-后面的参数不能写驼峰

  5. bindinput的语法格式

    inputHandler(e){
        console.log(e.detail.value);
    },
        
    <input type="text" bindinput="inputHandler"/>
    
  6. 实现文本框和data之间的数据同步:定义数据,渲染结构,美化样式,绑定input事件处理函数

    <!-- js -->
    Page({
        data:{
            msg:'你好'
        },
        inputHandler(e){
            // console.log(e.detail.value);
            this.setData({
                msg:e.detail.value
            })
        }
    })
    <!-- wxml -->
    <input type="text" bindinput="inputHandler" value="{{msg}}" />
    <!-- wxss -->
    input{
      border: 1px solid #eee;
      margin: 5px;
      padding: 5px;
      border-radius: 3px;
    }
    
2.1.3 条件渲染
  1. wx:if

    在框架中,使⽤wx:if="{{condition}}"来判断是否需要渲染该代码块

    
    
    保密
    
  2. 结合使用wx:if

    :实现一次性控制多个组件的展示和隐藏,并在block标签上使用wx:if来控制属性,另外,block并不是一个组件,只是一个包裹性质的容器,不会在页面中做任何渲染

    
      view1
      view2
    
    
    
  3. hidden:直接使用hidden="{{condition}}"也可以实现元素的显示与隐藏

    
    
    
2.1.4 列表渲染
  1. wx:for 可以根据指定的数组,循环渲染重复的组件结构

    wx:for-item可以指定数组当前元素的变量名,wx:for-index可以指定数组当前下标的变量名

    <view wx:for="{{arr}}" wx:key="*this">
      索引是:{{index}},item项是:{{item}}
    </view>
    <view wx:for="{{arr}}" wx:for-index="idx" wx:for-item="itemName" wx:key="*this">
      索引是:{{idx}},item项是:{{itemName}}
    </view>
    <!-- 默认情况下,当前循环项的索引用index表示,当前循环用item表示 -->
    
  2. wx:key ⽤来提⾼数组渲染的性能

    <view wx:for="{{userList}}" wx:key="id">{{item.name}}</view>
    data:{
        userList:[
          {id:1,name:'小红'},
          {id:2,name:'小白'},
          {id:3,name:'小化'},
        ]
    }
    // wx:key的值还可取:保留字*this,它的意思是item本⾝,*this代表的必须是唯⼀的字符串和数组
    

2.2 使用WXSS样式美化页面结构

​ 与CSS相比,WXSS扩展的特性:rpx尺寸单位,@import样式导入

2.2.1 rpx

rpx(responsive pixel):可以根据屏幕宽度进行自适应。规定屏幕宽为750rpx

微信小程序学习笔记_第11张图片

建议:开发微信小程序时设计师可以⽤iPhone6作为视觉稿的标准。

使用步骤:

  1. 确定设计稿宽度pageWidth
  2. 计算比例750rpx = pageWidth px,因此1px=750rpx/pageWidth。
  3. 在less⽂件中,只要把设计稿中的px=>750/pageWidth rpx即可
2.2.2 样式导入

​ 语法格式:@import后跟需要导入的外联样式表的相对路径,用==;==表示语句结束,如

@import '/common/common.wxss';

2.2.3 全局样式和局部样式
  1. 全局样式:定义在app.wxss中的样式为全局样式,作用于每一个页面

  2. 在页面的.wxss文件中定义的样式为局部样式,只作用于当前页面

  3. 当局部样式和全局样式冲突时,根据就近原则,局部样式会覆盖全局样式

  4. 当局部样式的权重大于或等于全局样式的权重时,才会覆盖全局样式

2.3 使用app.json对小程序进行全局配置

2.3.1 全局配置文件及常用的配置项

微信小程序学习笔记_第12张图片

2.3.2 window节点常用的配置项

微信小程序学习笔记_第13张图片

2.3.3 tabBar
  1. tabBar是移动端应用常见的页面效果,用于实现页面的快速切换,小程序中通常将其分为:底部tabBar,顶部tabBar

  2. 注意:tabBar中只能配置最后2个,最多5个tab页签,当渲染顶部tabBar时,不显示icon,只显示文本

  3. tabBar的6个组成部分

    • backgroundColor:tabBar的背景色
    • selectedIconPath:选中时的图片路径
    • selectedColor:tabBar上的文字选中时的颜色
    • borderStyle:tabBar上边框的颜色
    • iconPath:未选中时的图片路径
    • color:tabBar上文字的默认(未选中)颜色
  4. tabBar节点的配置项

    微信小程序学习笔记_第14张图片

  5. 每个tabBar项的配置选项

    微信小程序学习笔记_第15张图片

2.4 使用page.json对小程序页面进行个性化配置

  1. 当页面配置与全局配置冲突时,根据就近原则,最终的效果以页面配置为准
  2. 页面配置中常用的配置项与全局一样

2.5 发起网络数据请求

2.5.1 GET和POST请求
  1. 小程序中网络数据请求的限制

    • 只能请求HTTPS类型的接口
    • 必须将接口的域名添加到信任列表中
  2. 配置request的合法域名

    登录到微信小程序的管理后台->开发->开发设置->服务器域名->修改request合法域名

  3. 发起GET请求

    调用微信小程序提供的wx.request()方法,可以发起GET数据请求

    getInfo(){
        wx.request({
            url: 'https://www.escook.cn/api/get',
            method:'GET',
            data:{
                name:'zs',
                age:20
            },
            success:(res)=>{
                console.log(res.data);
            }
        })
    },
    
  4. 发起POST请求

    调用微信小程序提供的wx.request()方法,可以发起POST数据请求

    postInfo(){
        wx.request({
            url: 'https://www.escook.cn/api/post',
            method:"POST",
            data:{
                name:'ls',
                age:33
            },
            success:(res)=>{
                console.log(res.data);
            }
        })
    },
    
  5. 在页面加载时请求数据

    onLoad: function (options) {
        this.getInfo()
        this.postInfo()
    }
    
  6. 跳过request合法域名校验(只能在开发与调试阶段使用)

    微信小程序学习笔记_第16张图片

3. 小程序-视图与逻辑

3.1 页面导航

3.1.1 声明式导航
  1. 小程序中实现页面导航的两种方式

    • 声明式导航:在页面上声明一个导航组件;通过点击组件实现页面跳转
    • 编程式导航:调用小程序的导航 API,实现页面的跳转
  2. 导航到 tabBar 页面:在使用组件跳转到指定的 tabBar 页面时,需要指定 url 属性和 open-type 属性,其中:

    • url 表示要跳转的页面的地址,必须以 /开头
    • open-type 表示跳转的方式,必须为 switchTab
  3. 导航到非tabBar页面:在使用 组件跳转到普通的非 tabBar 页面时,则需要指定 url 属性和 open-type 属性,其中:

    • url 表示要跳转的页面的地址,必须以 /开头
    • open-type 表示跳转的方式,必须为 navigate
    • 在导航到非 tabBar 页面时,open-type=“navigate” 属性可以省略
  4. 后退导航:如果要后退到上一页面或多级页面,则需要指定 open-type 属性和 delta 属性,其中:

    • open-type 的值必须是 navigateBack,表示要进行后退导航
    • delta 的值必须是数字,表示要后退的层级
    • 如果只是后退到上一页面,则可以省略 delta 属性,因为其默认值就是 1
<navigator url="/pages/message/message" open-type="switchTab">导航到消息页面</navigator>
<navigator url="/pages/index/index" open-type="navigate">导航到index页面</navigator>
<navigator open-type="navigateBack" delta="1">后退一个页面</navigator>
3.1.2 编程式导航
  1. 导航到 tabBar 页面:调用 wx.switchTab(Object object) 方法。参数的属性如下:

    属性 类型 是否必选 说明
    url string 需要跳转的 tabBar 页面的路径,路径后不能带参数
    success function 接口调用成功的回调函数
    fail function 接口调用失败的回调函数
    complete function 接口调用结束的回调函数(调用成功、失败都会执行)
  2. 导航到非tabBar页面:调用 wx.navigateTo(Object object) 方法,参数的属性如下:

    属性 类型 是否必选 说明
    url string 需要跳转到的非 tabBar 页面的路径,路径后可以带参数
    success function 接口调用成功的回调函数
    fail function 接口调用失败的回调函数
    complete function 接口调用结束的回调函数(调用成功、失败都会执行)
  3. 后退导航:调用 wx.navigateBack(Object object) 方法,可以返回上一页面或多级页面,参数的属性如下:

    属性 类型 默认值 是否必选 说明
    delta number 1 返回的页面数,如果 delta 大于现有页面数,则返回到首页
    success function 接口调用成功的回调函数
    fail function 接口调用失败的回调函数
    complete function 接口调用结束的回调函数(调用成功、失败都会执行)
<button bindtap="gotoMessage">跳转到message页面</button>
<button bindtap="gotoIndex">跳转到index页面</button>
<button bindtap="gotoBack">后退一个页面</button>
// 通过编程式导航跳转到tabBar页面
gotoMessage(){
    wx.switchTab({
        url: '/pages/message/message',
    })
}
// 通过编程式导航跳转到非tabBar页面
gotoIndex(){
    wx.navigateTo({
        url: '/pages/index/index',
    })
}
// 后退一个页面
gotoBack(){
    wx.navigateBack()
},
3.1.3 导航传参
  1. 声明式导航传参:在路径的后面还可以携带参数:参数与路径之间使用?分隔;参数键与参数值用 =相连;不同参数用& 分隔

    <navigator url="/pages/index/index?name=zs&age=20">跳转到index页面</navigator>
    
  2. 编程式导航传参:调用 wx.navigateTo(Object object) 方法跳转页面时,也可以携带参数

    <button bindtap="gotoIndex2">跳转到index页面</button>
    gotoIndex2(){
        wx.navigateTo({
            url: '/pages/index/index?name=zs&age=20',
        })
    },
    
  3. 在onLoad中接收导航参数(声明式或编程式都一样接收,并且是在跳转页面对应的onLoad中接收)

    onLoad: function (options) {
        console.log(options);
    },
    

3.2 页面事件

3.2.1 下拉刷新
  1. 启用下拉刷新有两种方式:

    • 全局开启下拉刷新:在 app.json 的 window 节点中,将 enablePullDownRefresh 设置为 true
    • 局部开启下拉刷新:在页面的 .json 配置文件中,将 enablePullDownRefresh 设置为 true(推荐使用)
  2. 在全局或页面的 .json 配置文件中,通过 backgroundColor 和 backgroundTextStyle 来配置下拉刷新窗口的样式,其中:

    • backgroundColor 用来配置下拉刷新窗口的背景颜色,仅支持16 进制的颜色值
    • backgroundTextStyle 用来配置下拉刷新 loading 的样式,仅支持 dark 和 light
  3. 监听页面的下拉刷新事件:在页面的 .js 文件中,通过 onPullDownRefresh() 函数即可监听当前页面的下拉刷新事件

    <button bindtap="addCount">点击+1</button>
    addCount(){
        this.setData({
            count:this.data.count+1
        })
    }
    onPullDownRefresh: function () {
        // console.log("触发了Message下拉刷新事件");
        this.setData({
            count:0
        })
    },
    
  4. 停止下拉刷新:调用 wx.stopPullDownRefresh() 可以停止当前页面的下拉刷新

       /**
       * 页面相关事件处理函数--监听用户下拉动作
       */
    onPullDownRefresh: function () {
        // console.log("触发了Message下拉刷新事件");
        this.setData({
            count:0
        })
        // 当数据重置成功后,调用此函数,关闭下拉刷新的效果
        wx.stopPullDownRefresh()
    },
    
3.2.2 上拉触底事件

​ 是指通过手指在屏幕上的上拉滑动操作,从而加载更多数据的行为。

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

       /**
       * 页面上拉触底事件的处理函数
       */
    onReachBottom: function () {
        console.log("上拉触底事件触发了");
    },
    
  2. 配置上拉触底距离(触发上拉触底事件时,滚动条距离页面底部的距离):可以在全局或页面的 .json 配置文件中,通过 onReachBottomDistance 属性来配置上拉触底的距离(默认50px)

3.2.3 自定义编译模式

微信小程序学习笔记_第17张图片

3.3 生命周期

3.3.1 生命周期与声明周期函数
  1. 生命周期(Life Cycle)是指一个对象从创建 -> 运行 -> 销毁的整个阶段,强调的是一个时间段

  2. 生命周期的分类:

    • 应用生命周期:特指小程序从启动 -> 运行 -> 销毁的过程
    • 页面生命周期:特指小程序中,每个页面的加载 -> 渲染 -> 销毁的过程
  3. 生命周期函数:是由小程序框架提供的内置函数,会伴随着生命周期,自动按次序执行,允许程序员在特定的时间点,执行某些特定的操作

    注意:生命周期强调的是时间段,生命周期函数强调的是时间点

  4. 生命周期函数的分类:

    • 应用的生命周期函数:特指小程序从启动 -> 运行 -> 销毁期间依次调用的那些函数
    • 页面的生命周期函数:特指小程序中,每个页面从加载 -> 渲染 -> 销毁期间依次调用的那些函数
  5. 应用生命周期函数:小程序的应用生命周期函数需要在 app.js 中进行声明

    App({
      // 当小程序初始化完成时,会触发 onLaunch(全局只触发一次)
      onLaunch: function () {},
      // 当小程序启动,或从后台进入前台显示,会触发 onShow
      onShow: function (options) {},
      // 当小程序从前台进入后台,会触发 onHide
      onHide: function () {},
      // 当小程序发生脚本错误,或者 api 调用失败时,会触发 onError 并带上错误信息
      onError: function (msg) {}
    })
    
  6. 页面的生命周期函数:小程序的页面生命周期函数需要在页面的 .js 文件中进行声明

    Page({
      onLoad: function (options) {},  // 生命周期函数--监听页面加载,一个页面只调用一次
      onReady: function () {},  // 生命周期函数--监听页面初次渲染完成,一个页面只调用一次
      onShow: function () {}, // 生命周期函数--监听页面显示
      onHide: function () {}, // 生命周期函数--监听页面隐藏
      onUnload: function () {}, // 生命周期函数--监听页面卸载,一个页面只调用一次
    })
    

3.4 WXS脚本

​ WXS(WeiXin Script)是小程序独有的一套脚本语言,结合 WXML,可以构建出页面的结构

3.4.1 WXS与JavaScript的关系
  1. wxs 有自己的数据类型
    • number 数值类型、string 字符串类型、boolean 布尔类型、object 对象类型、
    • function 函数类型、array 数组类型、 date 日期类型、 regexp 正则
  2. wxs 不支持类似于 ES6 及以上的语法形式
    • 不支持:let、const、解构赋值、展开运算符、箭头函数、对象属性简写、etc…
    • 支持:var 定义变量、普通 function 函数等类似于 ES5 的语法
  3. wxs 遵循 CommonJS 规范
    • module 对象
    • require() 函数
    • module.exports 对象
3.4.2 基础语法
  1. 内嵌WXS脚本

    wxml 文件中的每个标签,必须提供 module 属性,用来指定当前 wxs 的模块名称,方便在 wxml 中访问模块中的成员

    <view>{{m1.toUpper(username)}}</view>
    <wxs module="m1">
      module.exports.toUpper=function(str){
        return str.toUpperCase()
      }
    </wxs>
    
  2. 定义外联的WXS脚本

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

    function toLower(str){
      return str.toLowerCase()
    }
    
    module.exports={
      toLower:toLower
    }
    
  3. 使用外联的WXS脚本

    在 wxml 中引入外联的 wxs 脚本时,必须为 标签添加 module 和 src 属性,其中:module 用来指定模块的名称,src 用来指定要引入的脚本的路径,且必须是相对路径

    <view>{{m2.toLower(country)}}</view>
    <wxs src="../../utils/tools.wxs" module="m2"></wxs>
    

4. 小程序-基础加强

4.1 自定义组件

4.1.1 组件的创建与引用
  1. 创建组件

    • 在项目的根目录中,鼠标右键,创建 components -> test 文件夹
    • 在新建的 components -> test 文件夹上,鼠标右键,点击“新建 Component”
    • 键入组件的名称之后回车,会自动生成组件对应的 4 个文件,后缀名分别为 .js,.json, .wxml 和 .wxss
    • 建议把不同的组件,存放到单独目录中
  2. 局部引用组件:在页面的 .json 配置文件中引用组件的方式

    // 在页面的.json文件中,引入组件
    {
      "usingComponents": {
        "my-test1":"/components/test/test"
      }
    }
    // 在页面的.wxml中引入组件
    <my-test1></my-test1>
    
  3. 全局引用组件:在 app.json 全局配置文件中引用组件的方式

    // 在app.json文件中,引入组件
    {
        "pages":[....],
        "window":{....},
        "usingComponents": {
            "my-test2":"/components/test/test"
         },
    }
    // 在页面的.wxml中引入组件
    <my-test2></my-test2>
    
  4. 组件和页面的区别

    • 组件的 .json 文件中需要声明 “component”: true 属性
    • 组件的 .js 文件中调用的是 Component() 函数
    • 组件的事件处理函数需要定义到 methods 节点中
4.1.2 样式
  1. 组件样式隔离:默认情况下,自定义组件的样式只对当前组件生效,不会影响到组件之外的 UI 结构

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

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

    // 在组件的.js中新增如下配置
    Component({
      options:{
        styleIsolation:'isolated'
      }
    })    
    // 或在组件的.json中新增如下配置
    {
        "styleIsolation":"isolated"
    }
    

    微信小程序学习笔记_第18张图片

建议:在组件和引用组件的页面中建议使用 class 选择器,不要使用 id、属性、标签选择器

4.1.3 数据、方法和属性
  1. data数据:在小程序组件中,用于组件模板渲染的私有数据,需要定义到 data 节点中,data 更倾向于存储组件的私有数据

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

  3. properties属性:在小程序组件中,properties 是组件的对外属性,用来接收外界传递到组件中的数据,properties 更倾向于存储外界传递到组件中的数据

    Component({
        properties: { // 组件的属性列表
            /* max:{ // 完整定义属性的方式
          type:Number,  // 属性值的数据类型
          value:10  // 属性默认值
        }, */
            max:Number  // 简化方式,不指定默认值
        },
        data: { // 组件的初始数据
            count:0
        },
        methods: {  // 组件的方法列表(包含事件处理函数和自定义方法)
            addCount(){ // 事件处理函数
                if(this.data.count>=this.properties.max) return
                this.setData({
                    count:this.data.count+1,
                    // max:this.properties.max+1 // 使用setData修改properties值
                })
                this._showCount() // 通过this调用自定义方法
            },
            _showCount(){ // 自定义方法建议以 _ 开头
                wx.showToast({
                    title: 'count的值为: '+this.data.count,
                    icon:'none'
                })
            }
        }
    })
    <my-test1 max="10"></my-test1>
    
4.1.4 数据监听器
  1. 数据监听器用于监听和响应任何属性和数据字段的变化,从而执行特定的操作。它的作用类似于 vue 中的 watch 侦听器

    微信小程序学习笔记_第19张图片

  2. 数据监听器的基本用法:

    <view>{{n1}}+{{n2}}={{sum}}</view>
    <button bindtap="addN1">n1+1</button>
    <button bindtap="addN2">n2+1</button>
    
    Component({
        data:{n1:0,n2:0,sum:0},
        methods:{
            addN1(){
                this.setData({
                    n1:this.data.n1+1
                })
            },
            addN2(){
                this.setData({
                    n2:this.data.n2+1
                })
            }
        },
        observers:{
            'n1,n2':function(newN1,newN2){
                this.setData({
                    sum:newN1+newN2
                })
            }
        }
    })
    
  3. 监听对象属性的变化

    微信小程序学习笔记_第20张图片

  4. 数据监听器案例

    <view style="background-color: rgb({{fullColor}});" class="color-box">颜色值:{{fullColor}}</view>
    <button size="mini" type="default" bindtap="changeR">R</button>
    <button size="mini" type="primary" bindtap="changeG">G</button>
    <button size="mini" type="warn" bindtap="changeB">B</button>
    
    Component({
        options:{
            pureDataPattern:/^_/   // 指定所有的_开头的为纯数据字段
        },
        data: {
            rgb:{	// _rgb为纯数据字段
                r:0,
                g:0,
                b:0
            },
            fullColor:'0,0,0'
        },
        methods: {
            changeR(){
                this.setData({
                    '_rgb.r':this.data.rgb.r+5>255?255:this.data.rgb.r+5
                })
            },
            changeG(){
                this.setData({
                    'rgb.g':this.data.rgb.g+5>255?255:this.data.rgb.g+5
                })
            },
            changeB(){
                this.setData({
                    'rgb.b':this.data.rgb.b+5>255?255:this.data.rgb.b+5
                })
            }
        },
        observers:{
            'rgb.r,rgb.g,rgb.b':function(newR,newG,newB){	// 'rgb.**':function(obj){
                this.setData({
                fullColor:`${newR},${newG},${newB}`	// :`${obj.r},${obj.g},${obj.b}`
                })
            }
        }
    })
    
  5. 监听对象中所有属性的变化:使用通配符** 来监听,如 'rgb.**':function(obj){}

4.1.5 纯数据字段
  1. 纯数据字段指的是那些不用于界面渲染的 data 字段

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

    微信小程序学习笔记_第21张图片

4.1.6 组件的生命周期
  1. 小程序组件的声明周期:

    微信小程序学习笔记_第22张图片

微信小程序学习笔记_第23张图片

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

    微信小程序学习笔记_第24张图片

4.1.7 组件所在页面的生命周期
  1. 组件所在页面生命周期函数:

微信小程序学习笔记_第25张图片

  1. pageLifetimes 节点:

    微信小程序学习笔记_第26张图片

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

  2. 单个插槽:在小程序中,默认每个自定义组件中只允许使用一个 进行占位微信小程序学习笔记_第27张图片

  3. 启用多个插槽:在组件的 .js 文件定义

    微信小程序学习笔记_第28张图片

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

    微信小程序学习笔记_第29张图片

    微信小程序学习笔记_第30张图片

4.1.9 父子组件之间的通信
  1. 父子组件的通信方式

    微信小程序学习笔记_第31张图片

  2. 属性绑定

    微信小程序学习笔记_第32张图片

  3. 事件绑定步骤:

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

      微信小程序学习笔记_第33张图片

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

      微信小程序学习笔记_第34张图片

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

      微信小程序学习笔记_第35张图片

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

      微信小程序学习笔记_第36张图片

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

    微信小程序学习笔记_第37张图片

4.1.10 behaviors
  1. 是在小程序中,用于实现组件间代码共享的特性,类似于 Vue.js 中的 “mixins”

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

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

    微信小程序学习笔记_第38张图片

  4. 导入并使用:在组件中,使用 require() 方法导入需要的 behavior,挂载后即可访问 behavior 中的数据或方法

    微信小程序学习笔记_第39张图片

  5. behavior可用节点

    微信小程序学习笔记_第40张图片

  6. 同名字段处理规则:https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/behaviors.html

4.2 使用npm包

4.2.1 Vant Weapp
  1. 官方文档地址 https://youzan.github.io/vant-weapp

  2. 安装 :https://youzan.github.io/vant-weapp/#/quickstart#an-zhuang

    • 通过 npm 安装(建议指定版本为@1.3.3)
    • 构建 npm 包
    • 修改 app.json
  3. 使用:安装完 Vant 组件库之后,可以在 app.json 的 usingComponents 节点中引入需要的组件,即可在 wxml 中直接使用组件

    微信小程序学习笔记_第41张图片

  4. 定义全局主体样式:https://developer.mozilla.org/zh-CN/docs/Web/CSS/Using_CSS_custom_properties

    在 app.wxss 中,写入 CSS 变量,即可对全局生效,所有可用的颜色变量

    微信小程序学习笔记_第42张图片

4.2.2 API Promise化
  1. 默认情况下,小程序官方提供的异步 API 都是基于回调函数实现的

    微信小程序学习笔记_第43张图片

  2. 实现:在小程序中,实现 API Promise 化主要依赖于 miniprogram-api-promise 这个第三方的 npm 包

    微信小程序学习笔记_第44张图片

    注意,微信小程序每次安装第三方包之后必须需要构建npm,建议先将miniprogram_npm先删除再构建

  3. 调用

    微信小程序学习笔记_第45张图片

4.3 全局数据共享

  1. 全局数据共享(又叫做:状态管理)是为了解决组件之间数据共享的问题,如Vuex,Redux,MobX 等

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

    • mobx-miniprogram 用来创建 Store 实例对象
    • mobx-miniprogram-bindings 用来把 Store 中的共享数据或方法,绑定到组件或页面中使用
4.3.1 MobX
  1. 安装包:npm i --save [email protected] [email protected]

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

  2. 创建 MobX 的 Store 实例 store.js

    微信小程序学习笔记_第46张图片

  3. 将 Store 中的成员绑定到页面中

    微信小程序学习笔记_第47张图片

  4. 在页面上使用 Store 中的成员

    微信小程序学习笔记_第48张图片

  5. 将 Store 中的成员绑定到组件中

    微信小程序学习笔记_第49张图片

  6. 在组件中使用 Store 中的成员

    微信小程序学习笔记_第50张图片

4.4 分包

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

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

    • 主包:一般只包含项目的启动页面或 TabBar 页面、以及所有分包都需要用到的一些公共资源
    • 分包:只包含和当前分包有关的页面和私有资源
  3. 加载规则

    • 在小程序启动时,默认会下载主包并启动主包内页面:tabBar 页面需要放到主包中
    • 当用户进入分包内某个页面时,客户端会把对应分包下载下来,下载完成后再进行展示:非 tabBar 页面可以按照功能的不同,划分为不同的分包之后,进行按需下载
  4. 体积限制

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

    微信小程序学习笔记_第51张图片

  2. 打包规则

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

    • 主包无法引用分包内的私有资源
    • 分包之间不能相互引用私有资源
    • 分包可以引用主包内的公共资源
4.4.3 独立分包
  1. 独立分包本质上也是分包,只不过它比较特殊,可以独立于主包和其他分包而单独运行

  2. 独立分包与普通分包的区别:

    • 普通分包必须依赖于主包才能运行
    • 独立分包可以在不下载主包的情况下,独立运行
  3. 应用场景

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

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

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

  4. 配置方法

    微信小程序学习笔记_第52张图片

  5. 引用规则

    • 主包无法引用独立分包内的私有资源
    • 独立分包之间,不能相互引用私有资源
    • 独立分包和普通分包之间,不能相互引用私有资源
    • 特别注意:独立分包中不能引用主包内的公共资源
4.4.4 分包预下载
  1. 是指在进入小程序的某个页面时,由框架自动预下载可能需要的分包,从而提升进入后续分包页面时的启动速度。

  2. 配置:会在进入指定的页面时触发,在 app.json 中,使用 preloadRule 节点定义分包的预下载规则

    微信小程序学习笔记_第53张图片

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

4.5 自定义tabBar

官方文档:https://developers.weixin.qq.com/miniprogram/dev/framework/ability/custom-tabbar.html

  1. 首先在app.json中设置如下:

    微信小程序学习笔记_第54张图片

  2. 在根目录新建store/store.js文件

    // 在这个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中的数据
        updateActiveTabBarIndex:action(function(index){
            this.activeTabBarIndex=index
        })
    })
    
  3. 在根目录新建custom-tab-bar文件夹,在里面新建index组件,名字固定

    // custom-tab-bar/index.js
    import {storeBindingsBehavior} from 'mobx-miniprogram-bindings'
    import {store} from '../store/store'
    Component({
      options:{
        styleIsolation:'shared'
      },
      behaviors:[storeBindingsBehavior],
      storeBindings:{
        // 数据源
        store,
        fields:{
          sum:'sum',
          active:'activeTabBarIndex'
        },
        actions:{
          updateActive:'updateActiveTabBarIndex'
        }
      },
      observers:{
        'sum':function(val){
          this.setData({
            'list[1].info':val
          })
        }
      },
      data: {	// 组件的初始数据
        "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",
            "info":2
          },
          {
            "pagePath": "/pages/contact/contact",
            "text": "联系我们",
            "selectedIconPath": "/images/tabs/contact-active.png",
            "iconPath": "/images/tabs/contact.png"
          }
        ],
      },
      methods: {	// 组件的方法列表
        onChange(event) {
          // event.detail 的值为当前选中项的索引
          // this.setData({ active: event.detail });
          this.updateActive(event.detail)
          wx.switchTab({
            url: this.data.list[event.detail].pagePath,
          })
        },
      }
    })
    
    <!--custom-tab-bar/index.wxml-->
    <van-tabbar active="{{active}}" bind:change="onChange" active-color="#13A7A0">
      <van-tabbar-item wx:for="{{list}}" wx:key="index" info="{{item.info?item.info:''}}">
        <image slot="icon" src="{{item.iconPath}}" mode="aspectFit" style="width: 25px; height: 25px;"/>
        <image slot="icon-active" src="{{item.selectedIconPath}}" mode="aspectFit" style="width: 25px; height: 25px;"/>
        {{item.text}}
      </van-tabbar-item>
    </van-tabbar>
    
    /* custom-tab-bar/index.wxss */
    .van-tabbar-item{
      --tabbar-item-margin-bottom:0
    }
    
  4. 实现效果
    微信小程序学习笔记_第55张图片

你可能感兴趣的:(学习笔记,学习,微信小程序)