微信小程序开发


一、目录结构

image-20210721232154909

app.json

pages : 配置页面,小程序默认启动展示 pages 的第一个页面

window : 配置窗口

    - enablePullDownRefresh : 下拉刷新
    - navigationBarTitleText :小程序标题,最上面中间显示的文字

tabBar :底部菜单栏

- iconPath:菜单未选择时图片
- selectedIconPath:菜单选择时图片
{
  "pages":[
    "pages/home/home",
    "pages/img/img",
    "pages/mine/mine",
    "pages/search/search"
  ],
  "window":{
    "backgroundTextStyle":"dark",
    "navigationBarBackgroundColor": "#fff",
    "navigationBarTitleText": "Rewind",
    "navigationBarTextStyle":"black",
    "enablePullDownRefresh": true
  },
  "tabBar": {
    "list": [
      {
      "pagePath": "pages/home/home",
      "text": "首页",
      "iconPath": "icon/_home.png",
      "selectedIconPath": "icon/home.png"
    },
    {
      "pagePath": "pages/img/img",
      "text": "图片",
      "iconPath": "icon/_img.png",
      "selectedIconPath": "icon/img.png"
    },
    {
      "pagePath": "pages/mine/mine",
      "text": "用户",
      "iconPath": "icon/_my.png",
      "selectedIconPath": "icon/my.png"
    },
    {
      "pagePath": "pages/search/search",
      "text": "搜索",
      "iconPath": "icon/_search.png",
      "selectedIconPath": "icon/search.png"
    }
  ]
  },
  "style": "v2",
  "sitemapLocation": "sitemap.json"
}
<!-- 
  导航组件 navigator
  0 块级元素 默认会换行  可以直接加宽度和高度 
  1 url 要跳转的页面路径  绝对路径 相对路径
  2 target 要跳转到当前的小程序 还是其他的小程序的页面
    self 默认值 自己 小程序的页面 
    miniProgram 其他的小程序的页面
  3 open-type 跳转的方式
    1 navigate 默认值     保留当前页面(有返回按钮),跳转到应用内的某个页面,但是不能跳到 tabbar 页面
    2 redirect    关闭当前页面(无返回按钮),跳转到应用内的某个页面,但是不允许跳转到 tabbar 页面。
    3 switchTab    跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面
    4 reLaunch    关闭所有页面,打开到应用内的某个页面
 -->

 <navigator url="/pages/demo10/demo10"> 轮播图页面 </navigator>
 <navigator url="/pages/index/index"> 直接跳转到 tabbar页面 </navigator>
 <navigator open-type="redirect" url="/pages/demo10/demo10">  轮播图页面 redirect </navigator>
 <navigator open-type="switchTab" url="/pages/index/index">  switchTab直接跳转到 tabbar页面 </navigator>
 <navigator open-type="reLaunch" url="/pages/index/index">  reLaunch 可以随便跳 </navigator> 

二、常用标签

  • text 相当于以前web中的 span标签 行内元素 不会换行

  • view 相当于以前web中的 div标签 块级元素 会换行

block 占位符标签

1 占位符的标签
2 写代码的时候 可以看到这标签存在
3 页面渲染 小程序会把它移除掉

  <view>
    <block 
   wx:for="{{list}}"
   wx:for-item="item"
   wx:for-index="index"
   wx:key="id"
   class="my_list"
    >
      索引:{{index}}
      --
      值:{{item.name}}
    </block>
  </view>

input 输入框

<!-- 
  1 需要给input标签绑定 input事件 
    绑定关键字 bindinput
  2 如何获取 输入框的值 
    通过事件源对象来获取  
    e.detail.value 
  3 把输入框的值 赋值到 data当中
    不能直接 
      1 this.data.num=e.detail.value 
      2 this.num=e.detail.value 
    正确的写法
      this.setData({
        num:e.detail.value 
      })
  4 需要加入一个点击事件 
      1 bindtap
      2 无法在小程序当中的 事件中 直接传参 
      3 通过自定义属性的方式来传递参数
      4 事件源中获取 自定义属性
 -->

bindinput

键盘输入时触发,event.detail = {value, cursor, keyCode},keyCode 为键值

2.1.0 起支持,处理函数可以直接 return 一个字符串,将替换输入框的内容。

<input type="text" bindinput="handleInput" />

<!-- <button bindtap="方法名" data-operation="{{参数}}" >+</button> -->
<button bindtap="handletap" data-operation="{{1}}" >+</button>
<button bindtap="handletap" data-operation="{{-1}}">-</button>
<view>  
  {{num}}
</view>
Page({
  data: {
    num: 0
  },
  // 监听input输入框的内容,改变则执行该方法
  handleInput(e) {
    // console.log(e.detail.value );
    this.setData({
      num: e.detail.value
    })
  },
  // 加 减 按钮的事件
  handletap(e) {
    // console.log(e);
    // 1 获取自定义属性 operation
    const operation = e.currentTarget.dataset.operation;
    this.setData({
      num: this.data.num + operation
    })
  }
})

text 文本标签

  • 只能嵌套 text
  • 长按文字可复制(只有该标签有这个功能)
  • 可对空格回车进行编码
<!-- 
  1 长按文字复制 user-select
  2 对文本内容 进行 解码 decode
 -->
 <text user-select decode>
  text &nbsp; 123 &lt;
</text>

image 图片标签

<!-- 
  image 图片标签
  1 src 指定要加载的图片的路径
    图片存在默认的宽度和高度 320 * 240      原图大小是 200 * 100
  2 mode 决定 图片内容 如何 和 图片标签 宽高 做适配
    1 scaleToFill 默认值 不保持纵横比缩放图片,使图片的宽高完全拉伸至填满 image 元素 
    2 aspectFit 保持宽高比 确保图片的长边 显示出来   页面轮播图 常用
    3 aspectFill 保持纵横比缩放图片,只保证图片的 短 边能完全显示出来。  少用
    4 widthFix 以前web的图片的 宽度指定了之后 高度 会自己按比例来调整   常用  
    5 bottom。。 类似以前的backgroud-position 
  3 小程序当中的图片 直接就支持 懒加载  lazy-load
    1 lazy-load 会自己判断 当 图片 出现在 视口  上下 三屏的高度 之内的时候  自己开始加载图片 
 -->
 <image mode="bottom" lazy-load src="https://tva2.sinaimg.cn/large/007DFXDhgy1g51jlzfb4lj305k02s0sp.jpg" />

WSS 配置图片样式

image{
  box-sizing: border-box;
  border: 1px solid red;

  width: 300px;
  height: 200px;
}

swiper 轮播图

<!-- 
  1 轮播图外层容器 swiper
  2 每一个轮播项 swiper-item
  3 swiper标签 存在默认样式
    1 width 100%
    2 height 150px    image 存在默认宽度和高度 320 * 240 
    3 swiper 高度 无法实现由内容撑开 
  4 先找出来 原图的宽度和高度 等比例 给swiper 定 宽度和高度
    原图的宽度和高度  1125 * 352 px
    swiper 宽度 / swiper  高度 =  原图的宽度  /  原图的高度
    swiper  高度  =  swiper 宽度 *  原图的高度 / 原图的宽度
    height: 100vw * 352 /  1125
  5 autoplay 自动轮播
  6 interval 修改轮播时间
  7 circular 衔接轮播
  8 indicator-dots 显示 指示器 分页器 索引器 
  9 indicator-color 指示器的未选择的颜色 
  10 indicator-active-color 选中的时候的指示器的颜色 
 -->
<swiper autoplay interval="1000" circular indicator-dots indicator-color="#0094ff" indicator-active-color="#ff0094">
    <swiper-item> <image mode="widthFix" src="//gw.alicdn.com/imgextra/i1/44/O1CN013zKZP11CCByG5bAeF_!!44-0-lubanu.jpg" /> </swiper-item>
    <swiper-item> <image mode="widthFix" src="//aecpm.alicdn.com/simba/img/TB1CWf9KpXXXXbuXpXXSutbFXXX.jpg_q50.jpg" /> </swiper-item>
    <swiper-item> <image mode="widthFix" src="//gw.alicdn.com/imgextra/i2/37/O1CN01syHZxs1C8zCFJj97b_!!37-0-lubanu.jpg" /> </swiper-item>
</swiper>

WSS 样式

swiper {
  width: 100%;
  /* height: calc(100vw * 352 /  1125); */
  height: 31.28vw;
}
image {
  width: 100%;
}

button 按钮


<!-- 
  button 标签
  1 外观的属性
    1 size 控制按钮的大小
      1 default 默认大小
      2 mini 小尺寸
    2 type 用来控制按钮的颜色
      1 default 灰色
      2 primary 绿色
      3 warn 红色
    3 plain  按钮是否镂空,背景色透明
    4 loading 文字前显示正在等待图标
 -->
 <button>默认按钮</button>
 <button size="mini">  mini 默认按钮</button>
 <button type="primary"> primary 按钮</button> 
 <button type="warn"> warn 按钮</button> 
 <button type="warn" plain> plain 按钮</button> 
 <button type="primary" loading> loading 按钮</button> 

 <!-- 

  button 开发能力
  open-type:
  1 contact 直接打开  客服对话功能  需要在微信小程序的后台配置   只能够通过真机调试来打开 
  2 share 转发当前的小程序 到微信朋友中   不能把小程序 分享到 朋友圈 
  3 getPhoneNumber 获取当前用户的手机号码信息 结合一个事件来使用  不是企业的小程序账号 没有权限来获取用户的手机号码 
    1 绑定一个事件 bindgetphonenumber 
    2 在事件的回调函数中  通过参数来获取信息 
    3 获取到的信息  已经加密过了 
      需要用户自己待见小程序的后台服务器,在后台服务器中进行解析 手机号码,返回到小程序中 就可以看到信息了
  4 getUserInfo 获取当前用户的个人信息
    1 使用方法 类似 获取用户的手机号码
    2 可以直接获取 不存在加密的字段 
  5 launchApp 在小程序当中 直接打开 app
    1 需要现在 app中 通过app的某个链接 打开 小程序
    2 在小程序 中 再通过 这个功能 重新打开 app
    3 找到 京东的app 和 京东的小程序  
  6 openSetting 打开小程序内置的 授权页面
    1 授权页面中 只会出现 用户曾经点击过的 权限 
  7 feedback 打开 小程序内置的 意见反馈页面 
    1 只能够通过真机调试来打开 

  -->
<button open-type="contact">contact</button>
<button open-type="share">share</button>
<button open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber">getPhoneNumber</button>
<button open-type="getUserInfo" bindgetuserinfo="getUserInfo">getUserInfo</button>
<button open-type="launchApp">launchApp</button>
<button open-type="openSetting">openSetting</button>
<button open-type="feedback">feedback</button>
Page({
  // 获取用户的手机号码信息
  getPhoneNumber(e){
    console.log(e);
  },
  // 获取用户个人信息
  getUserInfo(e){
    console.log(e);
  }
})

icon 图标

<!-- 
  小程序中的字体图标
  1 type 图标的类型
    success|success_no_circle|info|warn|waiting|cancel|download|search|clear
  2 size 大小 
  3 color 图标的颜色
 -->
<icon  type="cancel" size="60" color="#0094ff"> </icon>

radio 单选框


<!-- 
  radio 单选框
  1 radio标签 必须要和 父元素 radio-group来使用
  2 value 选中的单选框的值 
  3 需要给 radio-group 绑定 change事件 
  4 需要在页面中显示 选中的值
 -->
 <radio-group bindchange="handleChange">
   <radio color="red" value="male"></radio>
   <radio color="red" value="female" ></radio>
 </radio-group>

 <view>您选中的是:{{gender}}</view>
// pages/demo15/demo15.js
Page({
  data: {
    gender: ""
  },
  handleChange(e){
    // 1 获取单选框中的值
    let gender=e.detail.value;
    // 2 把值 赋值给 data中的数据
    this.setData({
      // gender:gender
      gender
    })
  }
})

checkbox 复选框

<view>
  <checkbox-group bindchange="handleItemChange">
    <checkbox value="{{item.value}}" wx:for="{{list}}" wx:key="id">
      {{item.name}}
    </checkbox>

  </checkbox-group>
  <view>
    选中的水果:{{checkedList}}
  </view>
</view>
// pages/demo16/demo16.js
Page({
  data: {
    list:[
      {
        id:0,
        name:"🍎",
        value:"apple"
      },
      {
        id:1,
        name:"🍇",
        value:"grape"
      },
      {
        id:2,
        name:"🍌",
        value:"bananer"
      }
    ],
    checkedList:[]
  },
  // 复选框的选中事件
  handleItemChange(e){
    // 1 获取被选中的复选框的值
    const checkedList=e.detail.value;
    // 2 进行赋值
    this.setData({
      checkedList
    })
  }
})

三、语法

1、赋值语法

把输入框的值 赋值到 data当中,和vue不同

  • 不能直接 用以下写法
// 错误写法
this.data.num=e.detail.value 
this.num=e.detail.value 
  • 正确的写法(以对象的方式进行赋值)
Page({
  data: {
    num: 0
  },
  // 输入框的input事件的执行逻辑
  handleInput(e) {
    // console.log(e.detail.value );
    // 赋值到 data 的num中  
    this.setData({
      num: e.detail.value
    })
  }
})
  • 设置对象的属性值,而不改变对象的其他属性
this.setData({
    "userInfo.phone":'新手机号',
})
  • 修改数组中指定下表元素
this.setData({
    'informations[1].name':'王五'
})
  • 向数组中添加元素
var informations = this.data.informations//必须在暂存一下不然报错
informations.push({
    name:"王五", 
    age:"92"
})

this.setData({
    informations: informations
})

2、数据绑定

(1)标签内容绑定

<view> {{ message }} </view>
Page({
  data: {
    message: 'Hello MINA!'
  }
})

(2)标签属性绑定

<view id="item-{{id}}"> </view>
Page({
  data: {
    id: 0
  }
})
<!-- 特别注意:不要直接写 checked="false",其计算结果是一个字符串,转成 boolean 类型后代表真值。 -->
<checkbox checked="{{false}}"> </checkbox>

3、循环

列表循环

1、wx:for="{{数组或者对象}}"  wx:for-item="循环项的名称"  wx:for-index="循环项的索引"

2、wx:key="唯一的值" 用来提高列表渲染的性能
    1 wx:key 绑定一个普通的字符串的时候 那么这个字符串名称 肯定是 循环数组 中的 对象的 唯一属性
    2 wx:key ="*this"  就表示 你的数组 是一个普通的数组  *this 表示是 循环项 

3、当出现 数组的嵌套循环的时候 尤其要注意  以下绑定的名称 不要重名
    wx:for-item="item" wx:for-index="index"

4、默认情况下 我们 不写
    wx:for-item="item" wx:for-index="index"
    小程序也会把 循环项的名称 和 索引的名称 item 和 index 
    只有一层循环的话 (wx:for-item="item" wx:for-index="index") 可以省略
 <view>
   <view>列表循环:对应js在对象循环下方</view>
   <view wx:for="{{list}}" wx:for-item="item" wx:for-index="index" wx:key="id">
     索引:{{index}}
     --
     值:{{item.name}}
   </view>
 </view>

对象循环

​ 1 wx:for=”“ wx:for-item=”对象的值” wx:for-index=”对象的属性”
​ 2 循环对象的时候 最好把 item和index的名称都修改一下
​ wx:for-item=”value” wx:for-index=”key”

<view>
   <view>对象循环</view>
   <view wx:for="{{person}}" wx:for-item="value" wx:for-index="key" wx:key="age">
     属性:{{key}}
     --
     值:{{value}}
   </view>
 </view>
//Page Object
Page({
  data: {
    person: {
      age: 74,
      height: 145,
      weight: 200,
      name: "富婆"
    },
    list:[
      {
        id:0,
        name:"猪八戒"
      },
      {
        id:1,
        name:"天蓬元帅"
      },
      {
        id:2,
        name:"悟能"
      }
    ]
  }
});

4、条件渲染

  <!-- 
    11 条件渲染
      1 wx:if="{{true/false}}"
        1 if , else , if else
        wx:if
        wx:elif
        wx:else 
      2 hidden 
        1 在标签上直接加入属性 hidden 
        2 hidden="{{true}}"

      3 什么场景下用哪个
        1 当标签不是频繁的切换显示 优先使用 wx:if
          直接把标签从 页面结构给移除掉 
        2 当标签频繁的切换显示的时候 优先使用 hidden
          通过添加样式的方式来切换显示 
          hidden 属性 不要和 样式 display一起使用
   -->
<view>
    <view>条件渲染</view>
    <view wx:if="{{true}}">显示</view>
    <view wx:if="{{false}}">隐藏</view>

    <view wx:if="{{flase}}">1</view>
    <view wx:elif="{{flase}}">2 </view>
    <view wx:else> 3 </view>

    <view>hidden属性条件渲染</view>
    <view hidden >hidden1</view>
    <view hidden="{{false}}" >hidden2</view>

    <view>hidden 属性 和 样式 display一起使用,导致hidden失效</view>
    <view wx:if="{{false}}">wx:if</view>
    <view hidden  style="display: flex;" >hidden</view>
</view>

5、双大括号内调用函数

WXS 代码可以编写在 wxml 文件中的 <wxs> 标签内,或以 .wxs 为后缀名的文件内。

模块

每一个 .wxs 文件和 <wxs> 标签都是一个单独的模块。

每个模块都有自己独立的作用域。即在一个模块里面定义的变量与函数,默认为私有的,对其他模块不可见。

一个模块要想对外暴露其内部的私有变量与函数,只能通过 module.exports 实现。

.wxs 文件

微信开发者工具里面,右键可以直接创建 .wxs 文件,在其中直接编写 WXS 脚本。

示例代码:

// /pages/comm.wxs

var foo = "'hello world' from comm.wxs";
var bar = function(d) {
  return d;
}
module.exports = {
  foo: foo,
  bar: bar
};

上述例子在 /pages/comm.wxs 的文件里面编写了 WXS 代码。该 .wxs 文件可以被其他的 .wxs 文件 或 WXML 中的 <wxs> 标签引用。

module 对象

每个 wxs 模块均有一个内置的 module 对象。

属性

  • exports: 通过该属性,可以对外共享本模块的私有变量与函数。

示例代码:

// /pages/tools.wxs

var foo = "'hello world' from tools.wxs";
var bar = function (d) {
  return d;
}
module.exports = {
  FOO: foo,
  bar: bar,
};
module.exports.msg = "some msg";
<!-- page/index/index.wxml -->

<wxs src="./../tools.wxs" module="tools" />
<view> {{tools.msg}} </view>
<view> {{tools.bar(tools.FOO)}} </view>

四、事件监听

1、bindtap 点击事件

当用户点击该组件的时候会在该页面对应的Page中找到相应的事件处理函数。

bindtap : 点击事件对应的函数

data-*** : 点击事件函数传入的参数

<view id="tapTest" bindtap="tapName" data-item="100" data-hi="Weixin"> Click me! </view>
  tapName: function(event) {
    // 事件,里面有许多参数
    console.log(event)
    // 获取时间传入参数
    console.log(event.currentTarget.dataset.item)   // 100
    console.log(event.currentTarget.dataset.hi)     // Weixin
  },

2、bindinput 输入框监听

<input id="input1" bindinput="inputName" data-item="100" data-hi="Weixin"/>
  inputName:function(e){
    console.log(e.currentTarget.dataset.item)   // 100
    console.log(e.currentTarget.dataset.hi)     // Weixin
    // 如果是input标签的点击事件,以下语句可获得用户输入
    console.log(e.detail.value)
  },

五、组件

1、新增组件

Tabs.json

{
  "component": true,
  "usingComponents": {}
}

Tabs.js

标签的监听事件写在methods

2、主页面使用组件

{
  "usingComponents": {
    "Tabs":"../../components/Tabs/Tabs"
  }
}
<Tabs tabs="{{tabs}}"></Tabs>

3、父向子传递数据

image-20210724200515216

  1 父组件(页面) 向子组件 传递数据 通过 标签属性的方式来传递
    1 在子组件上进行接收
    2 把这个数据当成是data中的数据直接用即可
  2 子向父传递数据 通过事件的方式传递
    1 在子组件的标签上加入一个 自定义事件

4、子向父传递数据

(1)子组件

    <view 
    wx:for="{{tabs}}"
    wx:key="id"
    class="title_item {{item.isActive?'active':''}}"
    bindtap="hanldeItemTap"
    data-index="{{index}}"
    >
    {{item.name}}
  </view>
// components/Tabs.js
Component({
  /**
   * 里面存放的是 要从父组件中接收的数据
   */
  properties: {
    // 要接收的数据的名称
    // aaa:{
    //   // type  要接收的数据的类型 
    //   type:String,
    //   // value  默认值
    //   value:""
    // }
    tabs:{
      type:Array,
      value:[]
    }
  },

  /**
   * 组件的初始数据
   */
  data: {
    // tabs
  },

  methods: {
    hanldeItemTap(e){
      /* 
      1 绑定点击事件  需要在methods中绑定
      2 获取被点击的索引 
      3 获取原数组 
      4 对数组循环
        1 给每一个循环性 选中属性 改为 false
        2 给 当前的索引的 项 添加激活选中效果就可以了!!!

       5 点击事件触发的时候 
          触发父组件中的自定义事件 同时传递数据给  父组件  
          this.triggerEvent("父组件自定义事件的名称",要传递的参数)
       */

      //  2 获取索引
      const {index}=e.currentTarget.dataset;
      // 5 触发父组件中的自定义事件 同时传递数据给父组件  
      this.triggerEvent("itemChange",{index});
    }
  }
})

(2)父组件

<Tabs tabs="{{tabs}}" binditemChange="handleItemChange" >
  // 自定义事件 用来接收子组件传递的数据的
  handleItemChange(e) {
    // 接收传递过来的参数
    const { index } = e.detail;
    let { tabs } = this.data;
    tabs.forEach((v, i) => i === index ? v.isActive = true : v.isActive = false);
    this.setData({
      tabs
    })
  }

六、生命周期

1、应用生命周期 app.js

image-20210724220712566

//app.js
App({
  //  1 应用第一次启动的就会触发的事件  
  onLaunch() {
    //  在应用第一次启动的时候 获取用户的个人信息 
    // console.log("onLaunch");
    // aabbcc

    // js的方式来跳转 不能触发 onPageNotFound
    // wx.navigateTo({
    //   url: '/11/22/33'
    // });
  },

  // 2 应用 被用户看到 ,切换应用在切回来
  onShow(){
    // 对应用的数据或者页面效果 重置 
    // console.log("onShow");
  },
  // 3 应用 被隐藏了 
  onHide(){
    // 暂停或者清除定时器 
    // console.log("Hide");
  },
  // 4 应用的代码发生了报错的时候 就会触发
  onError(err){
    // 在应用发生代码报错的时候,收集用户的错误信息,通过异步请求 将错误的信息发送后台去
    // console.log("onError");
    // console.log(err);
  },
  // 5 页面找不到就会触发 
  //  应用第一次启动的时候,如果找不到第一个入口页面 才会触发
  onPageNotFound(){
    // 如果页面不存在了 通过js的方式来重新跳转页面 重新跳到第二个首页
    // 不能跳到tabbar页面  导航组件类似  
    wx.navigateTo({
      url: '/pages/demo09/demo09' 
    });  

    // console.log("onPageNotFound");
  }
})

2、页面生命周期

image-20210724220824821

// pages/demo18/demo18.js
Page({

  /**
   * 页面的初始数据
   */
  data: {

  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    console.log("onLoad");
    // onLoad发送异步请求来初始化页面数据 
  },
  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {
    console.log("onShow");
  },
  /**
    * 生命周期函数--监听页面初次渲染完成
    */
  onReady: function () {
    console.log("onReady");
  },
  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {
    console.log("onHide");
  },

  /**
   * 生命周期函数--监听页面卸载 也是可以通过点击超链接来演示 
   * 
   */
  onUnload: function () {
    console.log("onUnload");
  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {
    console.log("onPullDownRefresh");
    // 页面的数据 或者效果 重新 刷新
  },

  /**
   * 页面上拉触底事件的处理函数
   * 需要让页面 出现上下滚动才行 
   */
  onReachBottom: function () {
    console.log("onReachBottom");
    // 上拉加载下一页数据 
  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {
    console.log("onShareAppMessage");
  },
  /**
   * 页面滚动 就可以触发 
   */
  onPageScroll(){
    console.log("onPageScroll");
  },
  /**
   * 页面的尺寸发生改变的时候 触发
   * 小程序 发生了 横屏竖屏 切换的时候触发 
   */
  onResize(){
    console.log("onResize");
  },
  /**
   * 1 必须要求当前页面 也是tabbar页面
   * 2 点击的自己的tab item的时候才触发
   */
  onTabItemTap(){
    console.log("onTabItemTap");
  }
})

七、PDF预览

wx.downloadFile({
    url: this.webUrl,      //要预览的PDF的地址
    success: function (res) {
        console.log(res);
        if (res.statusCode === 200) {//成功
            var Path = res.tempFilePath//返回的文件临时地址,用于后面打开本地预览所用
            wx.openDocument({
                filePath: Path, //要打开的文件路径
                success: function (res) {
                    console.log('打开PDF成功');
                }
            })
        }
    },
    fail: function (res) {
        console.log(res);//失败
    }
})

八、版本区分

创建 wx-env.js,其他名字也可以

function getBaseUrl() {
  let version = __wxConfig.envVersion;
  switch (version) {
    case 'develop':
      return 'http://127.0.0.1:8082'; //开发
    case 'trial':
      return 'https://*****'; //体验
    case 'release':
      return 'https://*****'; //线上正式
    default:
      return 'https://*****';
  }
}

module.exports = {
  getBaseUrl
}

在其他js中引入

import {getBaseUrl} from "./wx-env";
var API_HOST = getBaseUrl()

  目录