微信小程序

文章目录

  • 1.[微信小程序介绍](https://developers.weixin.qq.com/miniprogram/introduction/)
    • 1.1.为什么是微信小程序
    • 1.2.微信小程序历史
    • 1.3.疯狂的微信小程序
    • 1.4.还有其他的小程序 不容忽视
    • 1.5.体验
      • 1.5.1.官方微信小程序体验
      • 1.5.2. 优秀的微信第三方小程序
  • 2.环境准备
    • 2.1.注册账号
    • 2.2.获取APPID
    • 2.3.开发工具
  • 3.第一个微信小程序
    • 3.1.打开微信开发者工具
    • 3.2.新建小程序项目
    • 3.3.填写项目信息
    • 3.4.创建成功
  • 4.微信开发者工具介绍
  • 5.小程序结构目录
    • 5.1.小程序文件结构和传统web对比
    • 5.2.基本的项目目录
  • 6.小程序配置文件
    • 6.1.[全局配置app.json](https://developers.weixin.qq.com/miniprogram/dev/reference/configuration/app.html)
      • 6.1.1.[tabbar](https://developers.weixin.qq.com/miniprogram/dev/reference/configuration/app.html#tabBar)
    • 6.2.[pageName.json](https://developers.weixin.qq.com/miniprogram/dev/reference/configuration/page.html)
    • 6.3.[sitemap配置-了解即可](https://developers.weixin.qq.com/miniprogram/dev/reference/configuration/sitemap.html)
  • 7.模板语法
    • 7.1.[数据绑定](https://developers.weixin.qq.com/miniprogram/dev/reference/wxml/data.html)
      • 7.1.1.普通写法
      • 7.1.2.组件属性
      • 7.1.3.bool类型
      • 7.1.4.示例
      • 7.1.5.复杂data数据设置
    • 7.2.表达式运算
      • 7.2.1.三元运算
      • 7.2.2.算数运算
      • 7.2.3.逻辑判断
      • 7.2.4.字符串运算
      • 7.2.5.注意
      • 7.2.6.示例
    • 7.3.[列表渲染](https://developers.weixin.qq.com/miniprogram/dev/reference/wxml/list.html)
      • 7.3.1.列表循环
      • 7.3.2.对象循环
      • 7.3.3.列表循环
      • 7.3.4.block
    • 7.4.[条件渲染](https://developers.weixin.qq.com/miniprogram/dev/reference/wxml/conditional.html)
      • 7.4.1.wx:if
      • 7.4.2.hidden
      • 7.4.3.二者选择
  • 8.小程序事件的绑定
    • 8.1.wxml绑定事件
    • 8.2.page定义函数
    • 8.3.注意
    • 8.4.示例
  • 9.[样式WXSS](https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxss.html)
    • 9.1.尺寸单位
      • 9.1.1.像素定义元素长度
      • 9.1.2.使用rpx定义元素长度
      • 9.1.3.总结
    • 9.2.样式导入
    • 9.3.选择器
    • 9.4.小程序中使用less
  • 10.[常见组件](https://developers.weixin.qq.com/miniprogram/dev/component/)
    • 10.1.[view](https://developers.weixin.qq.com/miniprogram/dev/component/view.html)
    • 10.2.[text](https://developers.weixin.qq.com/miniprogram/dev/component/text.html)
    • 10.3.image
    • 10.4.[swiper](https://developers.weixin.qq.com/miniprogram/dev/component/swiper.html)
      • 10.4.1.swiper
      • 10.4.2.swiper-item
      • 10.4.3.示例
    • 10.5.[navigator](https://developers.weixin.qq.com/miniprogram/dev/component/navigator.html)
    • 10.6.[rich-text](https://developers.weixin.qq.com/miniprogram/dev/component/rich-text.html)
      • 10.6.1.nodes属性
    • 10.7.[button](https://developers.weixin.qq.com/miniprogram/dev/component/button.html)
    • 10.8.[icon](https://developers.weixin.qq.com/miniprogram/dev/component/icon.html)
    • 10.9.[radio](https://developers.weixin.qq.com/miniprogram/dev/component/radio.html)
    • 10.10.[checkbox](https://developers.weixin.qq.com/miniprogram/dev/component/checkbox.html)
  • 11.[自定义组件](https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/)
    • 11.1.创建自定义组件
      • 11.1.1.声明组件
      • 11.1.2.编辑组件
    • 11.2. 声明引入自定义组件
    • 11.3. 页面中使用自定义组件
    • 11.4.其他属性
    • 11.5. 定义段与示例方法
    • 11.6.组件-自定义组件传参
      • 11.6.1. 过程
    • 11.7. 小结
  • 12.小程序生命周期
    • 12.1. [应用生命周期](https://developers.weixin.qq.com/miniprogram/dev/reference/api/App.html)
    • 12.2.[页面生命周期](https://developers.weixin.qq.com/miniprogram/dev/reference/api/Page.html)
    • 12.3. 页面生命周期图解
  • 13.补充说明
    • 13.1微信小程序版本发布
      • 13.1.1.设置小程序的APPID
      • 13.1.2.在微信公众平台设置小程序访问的后台地址(http协议)
      • 13.1.3.关闭不进行Https协议以及证书的校验
      • 13.1.4.上传
      • 13.1.5.提交审批
    • 13.2.版本测试说明
    • 13.3.小程序开发常见错误
      • 13.3.1.微信小程序开发出现:Unexpected token o in JSON at position 1;at api request success callback function异常
      • 13.3.2.微信小程序开发出现:Cannot read property 'setData' of undefined;at api request success callback
    • 13.4.小程序访问后台网络数据建议格式
      • 13.4.1.涉及文件
      • 13.4.1.在app.js定义后台请求地址IPURL
      • 13.4.2.定义net.js的工具方法getUserOpenid
      • 13.4.3.在登录页面的login.js使用该方法
    • 13.5.setData函数设置复杂数据
      • 13.5.1.设置类似map类型数据
      • 13.5.2.设置类似list数据
    • 13.6.消息订阅接口
    • 13.7.获取openid
      • 13.7.1.小程序端通过wx.login获取code
      • 13.7.2.将code和appid传递给后台服务器请求微信接口获取openid
    • 13.8.小程序之间的跳转
      • 13.8.1.原小程序通过准备跳转到其他小程序
      • 13.8.2.目标小程序的接收参数并加载页面
    • 13.9.微信小程序嵌套H5页面
      • 13.9.1.定义小程序的H5容器container.js
      • 13.9.2.定义小程序的H5容器container.wxml
      • 13.9.3.其他页面跳转到该页面
    • 13.10.H5.页面的事件携带参数跳转到微信小程序
      • 13.10.1.H5.页面引入相关的JS文件
      • 13.10.2.H5.页面JS函数跳转到微信小程序页面
      • 13.10.3.微信小程序准备downloadFile页面
    • 13.11.定义全局变量
      • 13.11.1.在微信小程序的app.js定义全局变量
      • 13.11.2.在需要使用的页面的js中使用全局变量
    • 13.12.获取小程序APPID
    • 13.13.注意请求异步性问题
    • 13.14.文件下载
      • 13.14.1.downloadFile.wxml
      • 13.14.2.downloadFile.js
    • 13.15.在图标加上数量提示
      • 13.15.1.index.wxml
      • 13.15.2.index.js
      • 13.15.3.index.wxss
    • 13.16.在H5页面增加排序图片
      • 13.16.1.示例
      • 13.16.2.实现
    • 13.17.在首页生成九宫格
      • 13.17.1.在数据库中配置不同的功能模块
      • 13.17.2.index.js加载功能模块
      • 13.17.3.index.wxml
      • 13.17.4.index.wxss

1.微信小程序介绍

微信小程序_第1张图片

微信小程序,简称小程序,英⽂名 Mini Program ,是⼀种不需要下载安装即可使⽤的应⽤,它实现了应⽤“触⼿可及”的梦想,用户扫⼀扫或搜⼀下即可打开试用。

1.1.为什么是微信小程序

  1. 微信有海量用户,而且粘性很高,在微信里开发产品更容易触达⽤⼾;
  2. 推广app的成本太⾼。
  3. 微信小程序开发适配成本低。
  4. 规模小容易试错,然后快速迭代。
  5. 跨平台。

1.2.微信小程序历史

  • 2016年1⽉11⽇,微信之父张小龙时隔多年的公开亮相,解读了微信的四⼤价值观。张小龙指出,越来越多产品通过公众号来做,因为这⾥开发、获取用户和传播成本更低。拆分出来的服务号并没有提供更好的服务,所以微信内部正在研究新的形态,叫**「微信小程序」 需要注意的是,之前是叫做「应用号」 **。
  • 2016年9⽉21⽇,微信⼩程序正式开启内测。在微信生态下,触⼿可及、用完即⾛的微信小程序引
    起⼴泛关注。腾讯云正式上线微信小程序解决方案,提供小程序在云端服务器的技术⽅案。
  • 2017年1⽉9⽇,微信推出的“小程序”正式上线。“小程序”是⼀种⽆需安装,即可使⽤的⼿机“应用”。不需要像往常⼀样下载App,用户在微信中“用完即⾛”。

1.3.疯狂的微信小程序

  1. 微信月活已经达到10.82亿。其中55岁以上的用户也达到6300万
  2. 信息传达数达到450亿,较去年增长18%;视频通话4.1亿次,增长100%
  3. 小程序覆盖超过200+行业,交易额增长超过6倍,服务1000亿+人次,创造出了5000亿+的商业价值。

1.4.还有其他的小程序 不容忽视

  1. 支付宝小程序
  2. 百度小程序
  3. QQ小程序
  4. 今日头条+抖音小程序

1.5.体验

1.5.1.官方微信小程序体验

小程序示例源码

微信小程序_第2张图片

1.5.2. 优秀的微信第三方小程序

  • 拼多多
  • 滴滴出行
  • 欢乐斗地主
  • 智行火车票
  • 唯品会

2.环境准备

开发微信小程序之前,必须要准备好相应的环境

2.1.注册账号

微信小程序需要标注唯一的开发者信息,因此需要申请注册账号。建议使用全新的邮箱(作为登录帐号,请填写未被微信公众平台注册,未被微信开放平台注册,未被个人微信号绑定的邮箱),没有注册过其他小程序或者公众号的。

访问注册页面,耐心完成注册即可。

  • 账户信息

    微信小程序_第3张图片
  • 邮箱激活

  • 信息登记

    微信小程序_第4张图片

2.2.获取APPID

由于后期调⽤微信⼩程序的接⼝等功能,需要索取开发者的⼩程序中的 APPID ,所以在注册成功后, 可登录,然后获取APPID。

登录成功后可看到如下界面

然后复制你的APPID,悄悄的保存起来,不要给别⼈看到。

微信小程序_第5张图片 微信小程序_第6张图片

2.3.开发工具

下载地址

微信小程序_第7张图片

微信小程序自带开发者工具,集 **开发、预览、调试、发布 **于⼀⾝的 完整环境。

但是由于编码的体验不算好,因此 建议使⽤ vs code + 微信小程序编辑工具 来实现编码

vs code 负责敲代码, 微信编辑工具 负责预览

3.第一个微信小程序

3.1.打开微信开发者工具

注意 第⼀次登录的时候 需要扫码登录
微信小程序_第8张图片

3.2.新建小程序项目

微信小程序_第9张图片

3.3.填写项目信息

微信小程序_第10张图片

3.4.创建成功

微信小程序_第11张图片

4.微信开发者工具介绍

详细的使⽤,可以查看官网

微信小程序_第12张图片

5.小程序结构目录

小程序框架的目标是通过尽可能简单、⾼效的方式让开发者可以在微信中开发具有原生APP体验的服务。

小程序框架提供了自己的视图层描述语言WXML 和 WXSS ,以及 JavaScript (小程序有自己的标签、样式、文件以及逻辑文件),并在视图层与逻辑层间提供了数据传输和事件系统,让开发者能够专注于数据与逻辑**(我们写代码的时候尽可能少关注操作页面结构,只需要关注页面本身)**。

5.1.小程序文件结构和传统web对比

传统web 微信小程序
结构 HTML WXML
样式 CSS WXSS
逻辑 JavaScript javascript
配置 JSON

通过以上对比得出,传统web是三层结构。而微信小程序是四层结构,多了⼀层配置.json

5.2.基本的项目目录

微信小程序_第13张图片

6.小程序配置文件

⼀个小程序应用程序会包括最基本的两种配置⽂件。⼀种是全局的app.json和页面自己的page.json

注意:JSON配置文件中不能出现注释

6.1.全局配置app.json

app.json 是当前小程序的全局配置,包括了小程序的所有页面路径、界⾯表现、网络超时时间、底部tab等。普通快速启动项目里面的 app.json 配置。如果想将哪个页面作为首页,只需要在pages中放在第一即可。

此时为index页面在第一位置

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

字段的含义

  1. pages 字段⸺用于描述当前小程序所有页面路径,这是为了让微信客户端知道当前你的小程序页面定义在哪个目录。

    • pages保存页面路径,不需要保存文件名后缀

      微信小程序_第14张图片
    • 新增页面的只需要在微信小程序的开发者工具中编辑app.json的新增页面名称,保存就可以自动生成页面的文件夹以及配置文件。

  2. window 标题⸺定义小程序所有页面的顶部背景颜色,文字颜色定义等。

    微信小程序_第15张图片

    具体内容可参考

    其他参考位置

6.1.1.tabbar

微信小程序_第16张图片

下方的页面的导航栏设置在app.jsp配置,主要用于导航操作。

  1. 首先准备导航栏图标样式,同一个功能图标设置两种。一是未点击状态下显示的图标,而是点击状态下显示的图标

    微信小程序_第17张图片
  2. 在app.json中进行配置

    {
      "pages":[
        "pages/index/index",
        "pages/img/img",
        "pages/mine/mine",
        "pages/search/search",
        "pages/demo2/demo2",
        "pages/logs/logs",
        "pages/demo1/demo1"
      ],
      "window":{
        "backgroundTextStyle":"dark",
        "navigationBarBackgroundColor": "#0094ff",
        "navigationBarTitleText": "我的应用",
        "navigationBarTextStyle":"white",
        "enablePullDownRefresh": true,
        "backgroundColor":"#FFFF00"
      },
      "tabBar": {
        "list": [{
          "pagePath": "pages/index/index",
          "text": "首页",
          "iconPath": "icon/_home.png",
          "selectedIconPath": "icon/home.png"
        },{
          "pagePath": "pages/img/img",
          "text": "图片",
          "iconPath": "icon/_img.png",
          "selectedIconPath": "icon/img.png"
        },{
          "pagePath": "pages/search/search",
          "text": "搜索",
          "iconPath": "icon/_search.png",
          "selectedIconPath": "icon/search.png"
        },{
          "pagePath": "pages/mine/mine",
          "text": "我的",
          "iconPath": "icon/_my.png",
          "selectedIconPath": "icon/my.png"
        }],
        "color": "#0094ff",
        "selectedColor": "#ff9400",
        "backgroundColor": "#ff5533",
        "position":"buttom"
      },
      "style": "v2",
      "sitemapLocation": "sitemap.json"
    }
    
    • 首先在pages设置所有的显示页面,首页放在第一位置
    • 在tabBar中的list中存放所有导航栏每个按钮的信息。
      • pagePath为跳转的页面地址
      • text为显示提示文本信息
      • iconPath为默认状态下的图标
      • selectedIconPath选中状态下的图标
    • 在tabBar的color设置text为显示提示文本的颜色。
    • 在tabBar的selectedColor设置text为显示提示文本选中后的颜色
    • 在tabBar的position设置tabBar的位置,默认为buttom即在屏幕底部,设置为top则显示在顶部
  3. 显示效果

    微信小程序_第18张图片

6.2.pageName.json

微信小程序_第19张图片

这里的page.json其实用来表示页面目录下的page.json 这类和小程序页面相关的配置。

开发者可以独立定义每个页面的⼀些属性,如顶部颜色、是否允许下拉刷新等等。

页面的配置只能设置 app.json 中部分 window 配置项的内容,页面中配置项会覆盖 app.json 的 window 中相同的配置项数据。

属性 类型 默认值 描述
navigationBarBackgroundColor HexColor #000000 导航栏背景颜色,如 #000000
navigationBarTextStyle String white 导航栏标题颜色,仅⽀持 black / white
navigationBarTitleText String 导航栏标题文字内容
backgroundColor HexColor #ffffff 窗口的背景色
backgroundTextStyle String dark 下拉 loading 的样式,仅支持 dark / light
enablePullDownRefresh Boolean false 是否全局开启下拉刷新。 详见Page.onPullDownRefresh
onReachBottomDistance Number 50 页面上拉触底事件触发时距页面底部距离,单位为px。 详见Page.onReachBottom
disableScroll Boolean false 设置为 true 则页⾯整体不能上下滚动;只在页面配置中有 效,无法在app.json中设置该项

6.3.sitemap配置-了解即可

微信小程序_第20张图片

小程序根目录下的sitemap.json⽂件⽤于配置小程序及其页面是否允许被微信索引。

7.模板语法

WXML(WeiXin Markup Language)是框架设计的⼀套标签语言,结合基础组件、事件系统,可以构建出页面的结构。

小程序因为存在模板语法,所有才能实现页面渲染和动态功能。

7.1.数据绑定

pageName.js中Page()方法传入一个对象{……},对象有格式要求。data:{},名字是关键字,不可修改,存放初始化数据,其他的都是生命周期函数。

数据绑定的主要内容就是获取pageName.js中的data:{}中的数据,展示出来。

VS CODE可以使用微信小程序开发助手插件辅助编程

微信小程序_第21张图片

7.1.1.普通写法

  1. 准备数据

    Page({
          data: {
            	message: 'Hello MINA!'
         }
    })
    
  2. 获取数据

    <view> {{ message }} view>
    

7.1.2.组件属性

  1. 准备数据

    Page({
          data: {
            	id: 0
         }
    })
    
  2. 获取数据

    <view id="item-{{id}}"> view>
    

7.1.3.bool类型

不要直接写 checked=false,其计算结果是⼀个字符串

<checkbox checked="{{false}}"> checkbox>

7.1.4.示例

  1. 准备数据

    Page({
          /**
           * 页面的初始数据
           */
          data: {
                msg: "hello mina",
                num: 10000,
                isGirl: false,
                person: {
                      age: 74,
                      height: 145,
                      weight: 200,
                      name: "牛"
                },
                isChecked:true
          },
    })
    
  2. 测试

    
    
    
    
    <view> {{msg}} view>
    
    <view>{{num}}view>
    
    <view> 是否是女生: {{isGirl}} view>
    
    <view>{{person.age}}view>
    <view>{{person.height}}view>
    <view>{{person.weight}}view>
    <view>{{person.name}}view>
    
    
    <view data-num="{{num}}"> 自定义属性view>
    
    
    <view>
      <checkbox checked="{{isChecked}}"> checkbox>
    view>
    
  3. 效果

    微信小程序_第22张图片

7.1.5.复杂data数据设置

Page({
    data: {
        userInfo:{},
    },
    
    /**
     * 生命周期函数--监听页面加载
     */
    onLoad: function (options) {
        //页面加载是接受数据,设置参数
        this.setData({
            userInfo: {
                xm: options.xm,
                sfzh: options.sfzh,
                openid:options.opendid
            },
        })
    },
})

7.2.表达式运算

表达式运算是指可以在花括号中加入表达式进行简单运算

概念区分:

  • 表达式:指的是一些简单运算、数字运算、字符串拼接、逻辑运算。
    1. 数字的加减
    2. 字符串拼接
    3. 三元表达式
  • 语句:指复杂的代码段
    1. if else
    2. switch
    3. do while
    4. for

7.2.1.三元运算

<view hidden="{{flag ? true : false}}"> Hidden view>

7.2.2.算数运算

Page({
  data: {
    a: 1,
    b: 2,
    c: 3
 }
})
<view> {{a + b}} + {{c}} + d view>

最终显示结果:3 + 3 + d

7.2.3.逻辑判断

Page({
  data: {
    length:6
 }
})
<view wx:if="{{length > 5}}">大于5view>

最终结果:大于5

7.2.4.字符串运算

Page({
  data:{
    name: 'Stonebridge'
 }
})
<view>{{"hello," + name}}view>

最终显示结果:hello,Stonebridge

7.2.5.注意

花括号和引号之间如果有空格,将最终被解析成为字符串

7.2.6.示例

<view>{{1+1}}view>
<view>{{'1'+'1'}}view>
<view>{{ 11%2===0 ? '偶数' : '奇数' }}view>

最终效果:

微信小程序_第23张图片

7.3.列表渲染

7.3.1.列表循环

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

  2. wx:key=“唯一的值” 用来提高列表渲染的性能

    • wx:key 绑定一个普通的字符串的时候那么这个字符串名称肯定是循环数组中的对象的唯一属性

    • wx:key ="*this" 就表示你的数组是一个普通的数组 *this 表示是循环项

      [1,2,3,44,5]
      [“1”,“222”,“adfdf”]

  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”)可以省略。

示例

  1. 准备数据

    Page({
        /**
       * 页面的初始数据
       */
        data: {
            list:[
                    {
                        id:0,
                        name:"尤里"
                    },
                    {
                        id:1,
                        name:"普莱斯"
                    },
                    {
                        id:2,
                        name:"麦克塔维什"
                    }
            	]
        	},
    })
    
  2. 显示数据

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

    **wx:for-item=“item” wx:for-index=“index”**可省略

  3. 最终效果

    微信小程序_第24张图片

7.3.2.对象循环

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

示例

  1. 准备数据

    Page({
      /**
       * 页面的初始数据
       */
        person: {
          age: 74,
          height: 145,
          weight: 200,
          name: "麦克塔维什"
        }
      },
    })
    
  2. 展示数据

    <view>
       <view>对象循环view>
       <view wx:for="{{person}}" wx:for-item="value"  wx:for-index="key" wx:key="age">属性:{{key}}--值:{{value}}view>
     view>
    
  3. 最终效果

    微信小程序_第25张图片

7.3.3.列表循环

result.modlist为一个JSON列表,通过for循环进行遍历,通过编号获取其中的值,进行修改后再赋值进去

var result = JSON.stringify(response);
result = JSON.parse(result);
//遍历首页的功能模块,为其跳转的地址根据功能代码(gndm)为其赋值参数
//1.如果是跳转到H5页面,将地址和参数准备好后使用Base64编码后存放在url中,在container.js中获取后直接解码使用
for (var i = 0; i < result.modlist.length; i++) {
    var module = result.modlist[i];
    if (module.gndm == "WAK01") {
        module.url = Base64.encode(module.url + "?openid=" + userInfo.openid + "&yhdm=" + userInfo.yhdm);
    } else if (module.gndm == "WAK02") {
        module.url = Base64.encode(module.url + "?yhid=" + userInfo.yhdm + "&fydm=" + userInfo.dwdm);
    }
}

7.3.4.block

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

示例

  1. 展示数据

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

    微信小程序_第26张图片

7.4.条件渲染

7.4.1.wx:if

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

以及if , else , if else
wx:if
wx:elif
wx:else

示例:

<view>
     <view>条件渲染view>
     <view wx:if="{{true}}">显示view>
     <view wx:if="{{false}}">隐藏view>

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

示例:

微信小程序_第27张图片

7.4.2.hidden

  1. 在标签上直接加入属性 hidden
  2. hidden="{{true}}"

示例

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

     <view>-----000-------</view>
     <view wx:if="{{false}}">wx:if</view>
     <view hidden>hidden</view>
</view>
微信小程序_第28张图片

**注意:**hidden属性不要和样式display一起使用

7.4.3.二者选择

**当标签频繁的切换显示的时候 优先使用 hidden通过添加样式的方式来切换显示 **

8.小程序事件的绑定

小程序中绑定事件,通过bind关键字来实现。如bindtap、bindinput、bindchange等不同的组件支持不同的事件,具体看组件的说明即可。

8.1.wxml绑定事件

<input bindinput="handleInput" />

8.2.page定义函数

Page({
      // 绑定的事件
      handleInput: function(e) {
            console.log(e);
            console.log("值被改变了");
     }
})

8.3.注意

  1. 绑定事件时不能带参数不能带括号,以下为错误写法

    <input bindinput="handleInput(100)" />
    
  2. 事件传值通过标签自定义属性的方式 和 value

    <input bindinput="handleInput" data-item="100" />
    
  3. 事件触发时获取数据

    handleInput: function(e) {
        // {item:100}
        console.log(e.currentTarget.dataset)
        // 输入框的值
        console.log(e.detail.value);
    }
    

8.4.示例

需求:

微信小程序_第29张图片
  1. page.WXML

    <input type="text" bindinput="handleInput"/>
    <view>
          {{num}}  
    view>
    <button style="color:red;background:#0044ff" bindtap="handletap" data-operation="{{1}}">+button>
    <button style="color:blue;background:#ff4400" bindtap="handletap" data-operation="{{-1}}">-button>
    
  2. page.JS

    // pages/demo4/demo4.js
    Page({
    
          /**
           * 页面的初始数据
           */
          data: {
                num:0
          },
          handleInput(e){
                this.setData({
                  	num:e.detail.value
                })
                console.log(e.detail.value);
          },
          handletap(e) {
                // console.log(e);
                // 1 获取自定义属性 operation
                const operation = e.currentTarget.dataset.operation;
                this.setData({
                  	num: this.data.num + operation
                })
          }
    })
    

注意点:

  • 需要给input标签绑定input事件绑定关键字 bindinput

  • 如何获取输入框的值通过事件<源对象e>来获取e.detail.value

    微信小程序_第30张图片
  • 把输入框的值赋值到data当中

    不能直接

    1. this.data.num=e.detail.value

    2. this.num=e.detail.value

    正确的写法

    this.setData({

    ​ num:e.detail.value

    })

  • 需要加入一个点击事件

    1. bindtap

    2. 无法在小程序当中的事件中直接传参

    3. 通过自定义属性的方式来传递参数

    4. 事件源中获取自定义属性

      微信小程序_第31张图片

9.样式WXSS

WXSS( WeiXin Style Sheets )是⼀套样式语言,⽤于描述 WXML 的组件样式。

与 CSS 相比,WXSS 扩展的特性有:

  • 响应式长度单位
  • rpx 样式导入

9.1.尺寸单位

rpx (responsive pixel): 可以根据屏幕宽度进行自适应。规定屏幕宽为 750rpx ,不管使用iPhone,iPad其屏幕宽度均是750rpx,故不同的设备单位rpx的长度(像素)不同

如在 iPhone6 上,屏幕宽度为375px ,共有750个物理像素,则 750rpx = 375px = 750物理像素 , 1rpx = 0.5px = 1物理像素

当我们要做一个页面布局的时候,如果要实现页面的某些元素大小跟随屏幕做自适应变化,就要使用rpx。

设备 rpx换算px (屏幕宽度/750) px换算rpx (750/屏幕宽度)
iPhone5 1rpx = 0.42px 1px = 2.34rpx
iPhone6 1rpx = 0.5px 1px = 2rpx
iPhone6 Plus 1rpx = 0.552px 1px = 1.81rpx

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

使用步骤:

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

9.1.1.像素定义元素长度

  1. wxml

    <view>RPXview>
    
  2. wxss

    view{
            width:200px;
            height:200px;
            font-size:40px;
            background-color:aqua;
    }
    
  3. 效果

    使用像素定义元素长度不管使用什么设备,元素长度不变。

    iPhone6屏幕

    微信小程序_第32张图片

    iPad屏幕

    微信小程序_第33张图片

9.1.2.使用rpx定义元素长度

  1. wxss

    view{
            width:200rpx;
            height:200rpx;
            font-size:40rpx;
            background-color:aqua;
    }
    
  2. 效果

    使用rpx定义元素长度,元素长度自适应屏幕比例为该长度在750rpx的长度比例

    • iPhone6屏幕

      微信小程序_第34张图片
    • ipad屏幕

      微信小程序_第35张图片

9.1.3.总结

  1. 小程序中不需要主动来引入样式文件,页面的会自动引入其样式文件PageName.wxss

  2. 需要把页面中某些元素的单位由px改成 rpx

    • 设计稿 750x

      750 px = 750 rpx

      1 px = 1 rpx

    • 把屏幕宽度 改成 375px

      375 px = 750 rpx

      1 px = 2rpx

      1rpx = 0.5px

  3. 存在一个设计稿宽度100像素(px)在未知页面page像素

    • 设计稿 page存在一个元素宽度100px

    • 拿以上的需求 去实现 不同宽度的页面适配

      page px = 750 rpx

      1px = 750 rpx / page

      100 px = 750 rpx * 100 / page

  4. 利用一个属性calc属性 css 和 wxss 都支持一个属性

    width:calc(750rpx * 100 / 375);,375为屏幕像素

    • 750 和 rpx 中间不要留空格
    • 运算符的两边也不要留空格

    示例:

     view{
       /* width: 200rpx; */
       height: 200rpx;
       font-size: 40rpx;
       background-color: aqua;
      /* 以下代码写法是错误  */
      /*  width:750 rpx * 100 / 375 ;  */
      width:calc(750rpx * 100 / 375);
     }
    

    效果

    微信小程序_第36张图片

9.2.样式导入

wxss中直接就⽀持,样式导⼊功能。

也可以和 less中的导⼊混⽤。

使用@import 语句可以导⼊外联样式表,只⽀持相对路径。

  1. 创建style/common.wxss

    view{
      color: aqua;
      font-size: 100px;
    }
    
  2. 在页面的wxss中引入

    /* 
    1 引入的 代码 是通过 @import 来引入
    2 路径 只能写相对路径
     */
    @import "../../styles/common.wxss";
    

9.3.选择器

特别需要注意的是小程序不支持通配符 * 因此以下代码无效!

*{
    margin:0;
    padding:0;
    box-sizing:border-box;
}

解决方案:view,text,img{……}

目前支持的选择器有:

选择器 样例 样例描述
.class .intro 选择所有拥有 class=intro 的组件
#id #firstname 选择拥有 id=firstname 的组件
element view 选择所有 view 组件
element, element view, checkbox 选择所有⽂档的 view 组件和所有的 checkbox 组 件
nth-child(n) view:nth-child(n) 选择某个索引的标签
::after view::after 在 view 组件后边插⼊内容
::before view::before 在 view 组件前边插⼊内容

9.4.小程序中使用less

原⽣⼩程序不⽀持 less ,其他基于⼩程序的框架⼤体都⽀持,如 wepy , mpvue , taro 等。 但是仅仅因为⼀个less功能,⽽去引⼊⼀个框架,肯定是不可取的。因此可以⽤以下⽅式来实现

  1. 编辑器是 vscode

  2. 安装插件 easy less

    微信小程序_第37张图片
  3. 在vs code的设置中settings.json加入如下

     "less.compile": {
            "outExt":".wxss"
       }
    
  4. 在要编写样式的地⽅,新建 less ⽂件,如 index.less ,然后正常编辑即可。

10.常见组件

重点讲解小程序中常⽤的布局组件 view,text,rich–text,button,image,navigator,icon,swiper,radio,checkbox。 等

10.1.view

代替原来的 div 标签

<view hover-class="h-class">
    点击我试试
view>

10.2.text

  1. ⽂本标签
  2. 只能嵌套text
  3. ⻓按⽂字可以复制(只有该标签有这个功能) ,增加selectable属性即可
  4. 可以对空格 回⻋ 进⾏编码,增加decode属性即可
属性名 类型 默认值 说明
selectable Boolean false ⽂本是否可选
decode Boolean false 是否解码

示例:

  1. 不使用decode属性

    
    <text selectable>
      text   123 <
    text>
    
    

    效果

    微信小程序_第38张图片
  2. 使用decode属性

    <text selectable decode>
      text   123 <
    text>
    
    微信小程序_第39张图片

10.3.image

  1. 图片标签,image组件默认宽度320px、⾼度240px
  2. ⽀持懒加载
  3. 建议最好把图片放在网络上,通过src引用
属性名 类型 默认值 说明
src String 图⽚资源地址
mode String scaleToFill 图⽚裁剪、缩放的模式
lazy-load Boolean false 图⽚懒加载

mode 有效值:

mode 有 13 种模式,其中 4 种是缩放模式,9.种是裁剪模式。

模式 说明
缩放 scaleToFill 不保持纵横比缩放图片,使图片的宽⾼完全拉伸⾄填满image 元素
缩放 aspectFit 保持纵横比缩放图片,使图片的长边能完全显⽰出来。
缩放 aspectFill 保持纵横比缩放图片,只保证图片的短边能完全显⽰出来。
缩放 widthFix 宽度不变,⾼度⾃动变化,保持原图宽⾼⽐不变
裁剪 top 不缩放图片,只显示图片的顶部区域
裁剪 bottom 不缩放图片,只显示图片的底部区域
裁剪 center 不缩放图片,只显示图片的中间区域
裁剪 left 不缩放图片,只显示图片的左边区域
裁剪 right 不缩放图片,只显示图片的右边区域
裁剪 top left 不缩放图片,只显示图片的左上边区域
裁剪 top right 不缩放图片,只显示图片的右上边区域
裁剪 bottom left 不缩放图片,只显示图片的左下边区域
裁剪 bottom right 不缩放图片,只显示图片的右下边区域

示例:

  1. WXML

    
     <image mode="widthFix" lazy-load src="https://tva2.sinaimg.cn/large/007DFXDhgy1g51jlzfb4lj305k02s0sp.jpg" />
    
  2. WXSS

    image{
      box-sizing: border-box;
      border: 1px solid red;
    
      width: 300px;
      height: 200px;
    }
    
  3. 效果

    宽度不变,高度自动变化,保持原图宽高比不变

    微信小程序_第40张图片

10.4.swiper

微信内置轮播图组件

微信小程序_第41张图片

轮播图的默认宽度 100% 高度 150px

属性名 类型 默认值 说明
indicator-dots Boolean false 是否显⽰⾯板指⽰点(小圆点)
indicator-color Color rgba(0, 0, 0, .3) 指⽰点(小圆点)颜⾊
indicator-active-color Color #000000 当前选中的指⽰点(小圆点)颜⾊
autoplay Boolean false 是否⾃动切换
interval Number 5000 ⾃动切换时间间隔
circular Boolean false 是否循环轮播

10.4.1.swiper

滑块视图容器。

10.4.2.swiper-item

滑块

滑块 默认宽度和⾼度都是100%

10.4.3.示例

  1. WXML

    
    <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>
    
  2. WXSS

    /* pages/demo10/demo10.wxss */
    swiper {
      width: 100%;
      /* height: calc(100vw * 352 /  1125); */
      height: 31.28vw;/*calc(100vw * 352 /  1125)的结果*/
    }
    image {
      width: 100%;
    }
    
  3. 效果

    微信小程序_第42张图片

10.5.navigator

导航组件 类似超链接标签

属性名 类型 默认值 说明
target String self 在哪个目标上发⽣跳转,默认当前小程序,可选值 self/miniProgram
url String 当前小程序内的跳转链接
opentype String navigate 跳转方式

open-type 有效值:

说明
navigate 保留当前页面,跳转到应⽤内的某个页面,但是不能跳到tabbar 页面
redirect 关闭当前页面,跳转到应⽤内的某个页面,但是不允许跳转到tabbar 页面。
switchTab 跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面
reLaunch 关闭所有页面,打开到应⽤内的某个页面
navigateBack 关闭当前页面,返回上一页⾯或多级页面。可通过 getCurrentPages() 获取当 前的页⾯栈,决定需要返回几层
exit 退出小程序,target=miniProgram时⽣效

示例

  1. WXML

    
     <navigator url="/pages/demo10/demo10"> open-type的默认值(navigate)轮播图页面 navigator>
     <navigator url="/pages/index/index">open-type的默认值(navigate) 不能直接跳转到 tabbar页面 navigator>
     <navigator open-type="redirect" url="/pages/demo10/demo10"> open-type的redirect 轮播图页面  navigator>
     <navigator open-type="switchTab" url="/pages/index/index">  switchTab直接跳转到 tabbar页面 navigator>
     <navigator open-type="reLaunch" url="/pages/index/index">  reLaunch 可以随便跳 navigator> 
    
    
  2. 效果

    微信小程序_第43张图片

10.6.rich-text

富文本标签

可以将字符串解析成 对应标签,类似 vue中 v–html 功能

微信小程序_第44张图片

10.6.1.nodes属性

nodes 属性⽀持 字符串 和 标签节点数组

属性 说明 类型 必填 备注
name 标签名 string ⽀持部分受信任的 HTML 节点
attrs 属性 object ⽀持部分受信任的属性,遵循 Pascal 命名法
children ⼦节点列表 array 结构和 nodes ⼀致

⽂本节点:type = text

属性 说明 类型 必填 备注
text ⽂本 string ⽀持entities
  1. nodes 不推荐使⽤ String 类型,性能会有所下降。
  2. rich–text 组件内屏蔽所有节点的事件。
  3. attrs 属性不⽀持 id ,⽀持class 。
  4. name 属性大小写不敏感。 如果使⽤了不受信任的 HTML 节点,该节点及其所有子节点将会被移除。
  5. img 标签仅⽀持⽹络图⽚。

示例1:

  1. js(拷贝淘宝主页div串)

    // pages/demo12/demo12.js
    Page({
    
      /**
       * 页面的初始数据
       */
      data: {
            html:'
    ……
' }, })
  • wxml

    
     <rich-text nodes="{{html}}">rich-text>
    
  • 效果
    微信小程序_第45张图片

  • 示例2:

    1. js

      // pages/demo12/demo12.js
      Page({
        data: {
          // 1 标签字符串 最常用的
          // 2 对象数组
          html:[
            {
              // 1 div标签 name属性来指定
              name:"div",
              // 2 标签上有哪些属性
              attrs:{
                // 标签上的属性 class  style
                class:"my_div",
                style:"color:red;"
              },
              // 3 子节点 children 要接收的数据类型和 nodes第二种渲染方式的数据类型一致 
              children:[
                {
                  name:"p",
                  attrs:{},
                  // 放文本
                  children:[
                    {
                      type:"text",
                      text:"hello"
                    }
                  ]
                }
              ]
            }
          ]
        }
      })
      
    2. WXML

      同示例1

    3. 效果

      微信小程序_第46张图片

    10.7.button

    微信小程序_第47张图片
    
    <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>primary按钮button>
    
    属性 类型 默认值 必填 说明
    size string default 按钮的大小
    type string default 按钮的样式类型
    plain boolean false 按钮是否镂空,背景⾊透明
    disabled boolean false 是否禁⽤
    loading boolean false 名称前是否带 loading 图标
    form-type string ⽤于 组件,点击分别会触发 组件的 submit/reset 事件
    form-type string 微信开放能⼒

    size 的合法值

    说明
    default 默认大小
    mini ⼩尺⼨

    type 的合法值

    说明
    primary 绿⾊
    default ⽩⾊
    warn 红⾊

    form-type 的合法值

    说明
    submit 提交表单
    reset 重置表单

    open-type 的合法值

    说明
    contact 打开客服会话,如果用户在会话中点击消息卡片后返回⼩程序,可以从 bindcontact 回调中获得具体信息,具体说明
    share 触发用户转发,使⽤前建议先阅读使用指引
    getPhoneNumber 获取用户手机号,可以从bindgetphonenumber回调中获取到⽤⼾信息, 具体说明
    getUserInfo 获取用户信息,可以从bindgetuserinfo回调中获取到用户信息
    launchApp 打开APP,可以通过app-parameter属性设定向APP传的参数具体说明
    openSetting 打开授权设置页
    feedback 打开“意见反馈”页面,⽤⼾可提交反馈内容并上传日志,开发者可以登 录小程序管理后台后进⼊左侧菜单“客服反馈”页面获取到反馈内容

    open-type 的contact的实现流程

    1. 将小程序 的 appid 由测试号改为自己的 appid
    2. 登录微信小程序官网,添加 客服 – 微信
    3. . 为了方便演示,准备了两个账号
      1. 普通用户
      2. 客服-微信
    4. 操作
    
    <button open-type="contact">contactbutton>
    <button open-type="share">sharebutton>
    <button open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber">getPhoneNumberbutton>
    <button open-type="getUserInfo" bindgetuserinfo="getUserInfo">getUserInfobutton>
    <button open-type="launchApp">launchAppbutton>
    <button open-type="openSetting">openSettingbutton>
    <button open-type="feedback">feedbackbutton>
    
    微信小程序_第48张图片

    10.8.icon

    属性 类型 默认值 必填 说明
    type string icon的类型,有效值:success, success_no_circle, info, warn, waiting, cancel, download, search, clear
    size number/string 23 icon的⼤⼩
    color string icon的颜⾊,同css的color
    微信小程序_第49张图片
    1. WXML

      <view class="group">
        <block wx:for="{{iconSize}}">
          <icon type="success" size="{{item}}"/>
        block>
      view>
      <view class="group">
        <block wx:for="{{iconType}}">
          <icon type="{{item}}" size="40"/>
        block>
      view>
      <view class="group">
        <block wx:for="{{iconColor}}">
          <icon type="success" size="40" color="{{item}}"/>
        block>
      view>
      
      
    2. JS

      Page({
        data: {
          iconSize: [20, 30, 40, 50, 60, 70],
          iconType: [
            'success', 'success_no_circle', 'info', 'warn', 'waiting', 'cancel',
      'download', 'search', 'clear'
         ],
          iconColor: [
            'red', 'orange', 'yellow', 'green', 'rgb(0,255,255)', 'blue', 'purple'
         ],
       }
      })
      
      

    10.9.radio

    可以通过 color属性来修改颜色

    需要搭配radio-group⼀起使用

    1. WXML

      
       <radio-group bindchange="handleChange">
         <radio color="red" value="male">radio>
         <radio color="red" value="female" >radio>
       radio-group>
      
       <view>您选中的是:{{gender}}view>
      
    2. javascript

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

      微信小程序_第50张图片

    10.10.checkbox

    可以通过 color属性来修改颜色

    微信小程序_第51张图片

    需要搭配radio-group⼀起使用

    11.自定义组件

    类似vue或者react中的自定义组件

    小程序允许我们使用自定义组件的方式来构建页面。

    11.1.创建自定义组件

    类似于页面,一个自定义组件由 json、wxml、wxss、js 4个文件组成

    可以在微信开发者工具中的根目录下快速创建组件的文件结构components文件夹-》创建一个和自定义组件名相同的文件夹componentsName,在该文件夹上点击右键<新建Component>并输入componentsName就创建好相应的组件的需要的文件

    微信小程序_第52张图片

    在⽂件夹内 components/Tabs ,创建组件 名为Tabs

    11.1.1.声明组件

    ⾸先需要在组件的 json 文件中进行自定义组件声明

    Tabs.json

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

    11.1.2.编辑组件

    同时,还要在组件的 wxml 文件中编写组件模板,在 wxss 文件中加入组件样式 slot 表⽰插槽,类似vue中的slot

    Tabs.wxml

    
    <view class="inner">
     {{innerText}}
        <slot>slot>
    view>
    

    在组件的 wxss ⽂件中编写样式

    注意:在组件wxss中不应使用ID选择器、属性选择器和标签名选择器。

    Tabs.wxss

    /* 这里的样式只应用于这个自定义组件 */
    .inner {
      color: red;
    }
    

    Tabs.json

    {
      "component": true,//标注这是一个component
      "usingComponents": {}//如果引用其他组件,在这里添加即可
    }
    

    11.1.3.注册组件

    在组件的 js ⽂件中,需要使⽤ Component() 来注册组件,并提供组件的属性定义、内部数据和自定义方法

    Tab.js

    Component({
      properties: {
        // 这里定义了innerText属性,属性值可以在组件使用时指定
        innerText: {
          // 期望要的数据是 string类型
          type: String,
          value: 'default value',
        }
      },
       data: {
         // 这里是一些组件内部数据
         someData: {}
      },
       methods: {
         // 这里是一个自定义方法
         customMethod: function(){}
      }
     })
    

    11.2. 声明引入自定义组件

    首先要在页面的 json 文件中进行引用声明。还要提供对应的组件名和组件路径。

    index.json

    {   
       "usingComponents": {
         "Tabs":"../../components/Tabs/Tabs"
      }
     }
    

    11.3. 页面中使用自定义组件

    index.wxml

    <Tabs>Tabs>
    

    效果:

    微信小程序_第53张图片

    11.4.其他属性

    11.5. 定义段与示例方法

    Component 构造器可用于定义组件,调⽤ Component 构造器时可以指定组件的属性、数据、方法等。

    定义段 类型 是否必填 描述
    properties Object Map 组件的对外属性,是属性名到属性设置的映射表,参⻅下⽂
    data Object 组件的内部数据,和 properties ⼀同⽤于组件的模板渲 染
    observers Object 组件数据字段监听器,⽤于监听 properties 和 data 的变 化,参见数据监听器
    methods Object 组件的方法,包括事件响应函数和任意的⾃定义⽅法,关于 事件响应函数的使用,参见组件事件
    created Function 组件⽣命周期函数,在组件实例刚刚被创建时执行,注意此 时不能调⽤ setData ,参见组件生命周期
    attached Function 组件⽣命周期函数,在组件实例进⼊页面节点树时执行,参见组件生命周期
    ready Function 组件⽣命周期函数,在组件布局完成后执行,参见组件⽣命周期
    moved Function 组件生命周期函数,在组件实例被移动到节点树另⼀个位置 时执行,参见组件生命周期
    detached Function 组件生命周期函数,在组件实例被从页面节点树移除时执 行,参见组件生命周期

    11.6.组件-自定义组件传参

    1. ⽗组件通过属性的⽅式给⼦组件传递参数
    2. ⼦组件通过事件的⽅式向⽗组件传递参数

    11.6.1. 过程

    1. ⽗组件 把数据 {{tabs}} 传递到 ⼦组件的 tabItems 属性中
    2. ⽗组件 监听 onMyTab 事件
    3. ⼦组件 触发 bindmytap 中的 mytap 事件
      1. ⾃定义组件触发事件时,需要使⽤ triggerEvent ⽅法,指定 事件名 、 detail 对象
    4. ⽗ -> ⼦ 动态传值 this.selectComponent("#tabs");

    父组件代码

    微信小程序_第54张图片

    子组件代码

    微信小程序_第55张图片

    11.7.示例

    1. 要求

      微信小程序_第56张图片
    2. 自定义组件components(子组件)

      • 组件Tab的tab.wxml

        
        <view class="tabs">
          <view class="tabs_title">
            
        
            <view 
            wx:for="{{tabs}}"
            wx:key="id"
            class="title_item {{item.isActive?'active':''}}"
            bindtap="hanldeItemTap"
            data-index="{{index}}"
            >
            {{item.name}}
          view>
          view>
          <view class="tabs_content">
            
            <slot>slot>
          view>
        view>
        
      • 组件Tab的tab.js

        // components/Tabs.js
        Component({
          /**
           * 里面存放的是 要从父组件中接收的数据
           */
          properties: {
            // 要接收的数据的名称
            // aaa:{
            //   // type  要接收的数据的类型 
            //   type:String,
            //   // value  默认值
            //   value:""
            // }
            tabs:{
              type:Array,
              value:[]
            }
          },
        
          /**
           * 组件的初始数据
           */
          data: {
            // tabs
          },
          /* 
          1 页面.js 文件中 存放事件回调函数的时候 存放在data同层级下!!!
          2 组件.js 文件中 存放事件回调函数的时候 必须要存在在 methods中!!!
           */
         
        
          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});
              // 3 获取data中的数组
              // 解构  对 复杂类型进行结构的时候 复制了一份 变量的引用而已
              // 最严谨的做法 重新拷贝一份 数组,再对这个数组的备份进行处理,
              // let tabs=JSON.parse(JSON.stringify(this.data.tabs));
              // 不要直接修改 this.data.数据 
              // let {tabs}=this.data;
              // let tabs=this.data;
              // 4 循环数组
              // [].forEach 遍历数组 遍历数组的时候 修改了 v ,也会导致源数组被修改
              // tabs.forEach((v,i)=>i===index?v.isActive=true:v.isActive=false);
        
              // this.setData({
                // tabs
              // })
            }
          }
        })
        
      • 组件Tab的Tab.wxss

        .tabs_title{
          display: flex;
          padding: 10rpx 0;
        }
        .title_item{
          flex: 1;
          display: flex;
          justify-content: center;
          align-items: center;
        }
        .active{
          color:red;
          border-bottom: 5rpx solid currentColor;
        }
        
      • 组件Tab的Tab.json

        {
          "component": true,
          "usingComponents": {}
        }
        
    3. 在页面(父组件)中使用组件Tab(子组件)

      • 引入组件Page.json

        {
          "usingComponents": {
            "Tabs":"../../components/Tabs/Tabs"
          }
        }
        
      • Page.js

        // pages/demo17/demo18.js
        Page({
        
          /**
           * 页面的初始数据
           */
          data: {
        
            tabs: [
              {
                id: 0,
                name: "首页",
                isActive: true
              },
              {
                id: 1,
                name: "原创",
                isActive: false
              }
              ,
              {
                id: 2,
                name: "分类",
                isActive: false
              }
              ,
              {
                id: 3,
                name: "关于",
                isActive: false
              }
            ]
        
          },
        
          // 自定义事件 用来接收子组件传递的数据的
          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
            })
          }
        })
        
      • Page.wxml

        
        <Tabs tabs="{{tabs}}" binditemChange="handleItemChange" >
        <block wx:if="{{tabs[0].isActive}}">0 block>
        <block wx:elif="{{tabs[1].isActive}}">1 block>
        <block wx:elif="{{tabs[2].isActive}}">2 block>
        <block wx:else>3block>
        Tabs>
        

    11.7. 小结

    1. 标签名 是 中划线的⽅式
    2. 属性的⽅式 也是要中划线的⽅式
    3. 其他情况可以使⽤驼峰命名
      1. 组件的⽂件名如 myHeader.js 的等
      2. 组件内的要接收的属性名 如 innerText
    4. 更多参考文档

    12.小程序生命周期

    分为应用生命周期页面生命周期

    关于小程序前后台的定义和小程序的运行机制,请参考运行机制章节。

    12.1. 应用生命周期

    应用指小程序的入口文件,也就是app.js

    属性 类型 必填 说明
    onLaunch function 监听小程序初始化,应用第一次启动就会触发的事件(例如在应用第一次启动的时候,获取用户的个人信息)。
    onShow function 监听小程序启动或切前台,应用被用户看到时候触发(例如应用切换启动时,页面效果重置)。
    onHide function 监听小程序切后台,应用被隐藏的时候触发(暂停或者清除定时器触发)。
    onError function 错误监听函数,当应用代码发生错误的时候会触发,会有一个err的错误信息参数(在应用发生代码错误触发,可以通过异步请求将错误信息发送给后台)。
    onPageNotFound function 页面不存在监听函数,页面找不到的时候报错,相当于onError中的一种()。
    //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");
      }
    })
    

    12.2.页面生命周期

    属性 类型 说明
    data Object 页面的初始数据
    onLoad function 页面加载完毕触发,一般在这个函数发送一些异步请求来初始化页面数据
    onShow function 页面显示时触发
    onReady function 页面初次渲染完毕后触发
    onHide function 页面隐藏的时候触发,应用隐藏以及跳转到其他页面时触发
    onUnload function 页面卸载的时候触发,即关闭当前页面,跳转其他页面。(可参考10.5navigator中opne-type为关闭的时候)
    onPullDownRefresh function 监听用户下拉动作触发,在app.js的window中设置。可以进行页面数据属性
    onReachBottom function 页面上拉触底事件的处理函数,当页面数据足够多,需要往上拉到底部的时候触发。可以用来加载下一页数据。
    onShareAppMessage function 用户点击右上角转发时触发
    onPageScroll function 页面滚动触发事件的处理函数
    onResize function 页面尺寸改变时触发,详见响应显示区域变化,横屏,竖屏的时候发生。如果要可以发生横屏竖屏在page.json中添加"pageOrientation": “auto”,或者在app.json中设置,所有的页面都可以。
    onTabItemTap function 当前是tab页时,点击tab时触发

    Page.js

    // 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");
      }
    })
    

    12.3. 页面生命周期图解

    微信小程序_第57张图片

    13.补充说明

    13.1微信小程序版本发布

    13.1.1.设置小程序的APPID

    13.1.2.在微信公众平台设置小程序访问的后台地址(http协议)

    • 小程序访问的后台程序地址

      微信小程序_第58张图片
    • 在微信公众平台设置访问地址

      微信小程序_第59张图片 微信小程序_第60张图片

    13.1.3.关闭不进行Https协议以及证书的校验

    微信小程序_第61张图片

    13.1.4.上传

    微信小程序_第62张图片

    13.1.5.提交审批

    微信小程序_第63张图片

    13.2.版本测试说明

    当版本发布后现场进行手机端测试时,一定要将手机端的小程序删除后重新搜索添加到手机上,再进行测试

    13.3.小程序开发常见错误

    13.3.1.微信小程序开发出现:Unexpected token o in JSON at position 1;at api request success callback function异常

    该错误一般出现在处理返回JSON数据时

    RN解析数据时报错,原因是返回的数据已经是object格式

    解决方案:

    1. JSON.stringify(对象);把对象转String
    2. 2.JSON.parse();把string转对象

    示例:

     App.request.loadModInfo(App.globalData.IPURL, param, function (response) {
        var result = JSON.stringify(response);
        result = JSON.parse(result);
        console.log(result);
        if(result.CODE=="00"){
            that.setData({
                tab: result.MODLIST
            })
        }        
    })
    

    13.3.2.微信小程序开发出现:Cannot read property ‘setData’ of undefined;at api request success callback

    作用域问题——回调函数中的作用域已经脱离了调用函数了,因此需要在回调函数外边把this赋给一个新的变量才可以了。
    此处将this赋值给变量self

    loadModInfo :function(){
        var self = this
        var param ={
            "MOD_ID":"WAK",
            "FYDM":App.globalData.FYDM
        }
        console.log(param);
        App.request.loadModInfo(App.globalData.IPURL, param, function (response) {
            var result = JSON.stringify(response);
            result = JSON.parse(result);
            console.log(result);
            if(result.CODE=="00"){
                that.setData({
                    tab: result.MODLIST
                })
            }        
        })
    }
    

    13.4.小程序访问后台网络数据建议格式

    13.4.1.涉及文件

    微信小程序_第64张图片

    13.4.1.在app.js定义后台请求地址IPURL

    var net_js = require('./net/net')
    App({
        globalData: {
            userInfo: null,
            CID: "0000",
            // 示例:IPURL:'http://ip:port/xszfweb/'
            IPURL: 'http://192.168.1.169:8088/xszfweb/',
            FYDM: "320000",
            //订阅消息模板
            SubscribeMsgTemplate:['F9eVJkbsidSFWadWAdXsj7Cjlzxg_CbtCc5e3CyOK1g']
        },
        request: {
            checkUserYhdm:net_js.checkUserYhdm,
            getUserOpenid:net_js.getUserOpenid,
            bindUser:net_js.bindUser,
            loadModInfo:net_js.loadModInfo,
        }
    })
    

    13.4.2.定义net.js的工具方法getUserOpenid

    module.exports创建接口,便于引用

    var Base64 = require('../utils/base64Decode');
    /**
     * 1.根据code,appid,fydm获取用户openid
     * @param {*} ip :请求地址
     * @param {*} param :携带参数;1.code.appid,3.fydm
     * @param {*} callback :回调函数
     */
    function getUserOpenid(ip,param,callback){
        var data={"method":"getOpenid","body":param};
        postRequest(ip+"web/wakTransmit", data, "application/json", function (res) {
            return typeof callback == "function" && callback(res)
        })
    }
    /**
     * 发送post请求
     * @param {*} ip 
     * @param {*} param 
     * @param {*} content_type 
     * @param {*} callback 
     */
    function postRequest(ip, param, content_type, callback) {
        wx.request({
            url: ip,
            header: {
                'Content-Type': content_type
            },
            method: "POST",
            data: param,
            async:false,
            success: function (res) {
                return typeof callback == "function" && callback(res.data)
            },
            fail: function (res) {
                var msg = res.errMsg
                var err = {
                    code: '1',
                    message: msg
                }
                return typeof callback == "function" && callback(err)
            }
        })
    }
    
    module.exports = {
        getUserOpenid: getUserOpenid,
    }
    

    13.4.3.在登录页面的login.js使用该方法

    引入getApp(),通过App.request.checkUserYhdm调用

    var Base64 = require('../../utils/base64Decode.js');
    const App = getApp();
    Page({
        data: {
            xm: '',
            sfzh: '',
        },
        /**
         * 根据用户的身份信息以及openid开始验证用户是否已绑定用户
         */
        verifyUser: function(openid){
            const xm = this.data.xm;
            const sfzh = this.data.sfzh;
            var param = {
                "yhxm":xm,
                "sfzhm":sfzh,
                "openid":openid
            }
            App.request.checkUserYhdm(App.globalData.IPURL,param,function(response){
                var result = JSON.stringify(response);
                result = JSON.parse(result);
                if(result.code=='00'){
                    var userInfo = {
                        "xm": xm,
                        "sfzh": sfzh,
                        "yhdm": result.userinfo.yhdm,
                        "openid": openid,
                        "dwdm": result.userinfo.dwdm,
                    }
                    wx.setStorageSync("userInfos", userInfo)
                    wx.reLaunch({
                        url: "/pages/index/index",
                    })
                }
            })
        },
    })
    

    13.5.setData函数设置复杂数据

    13.5.1.设置类似map类型数据

    Page({
        data: {
            userInfo:{},
        },
        
        /**
         * 生命周期函数--监听页面加载
         */
        onLoad: function (options) {
            //页面加载是接受数据,设置参数
            this.setData({
                userInfo: {
                    xm: options.xm,
                    sfzh: options.sfzh,
                    openid:options.opendid
                },
            })
        },
    })
    

    13.5.2.设置类似list数据

    直接将json中返回的list赋值即可

    Page({
        /**
         * 页面的初始数据
         */
        data: {
            tab:[]
            //测试数据
            //tab: [
                 //     {"name": "我的案款","url": "web/login","info": "浏览本人办理的案件款项","code": "1"}, 				
                 //   	{"name":"我的审批","url": "web/login", "info": "本人的待审批信息","code": "2"}
         		 //]
        },
         /**
         * 初始化时获取页面的功能模块信息
         */
        loadModInfo :function(){
            var self = this
            var param ={
                "mod_id":"WAK",
                "fydm":App.globalData.FYDM
            }
            console.log(param);
            App.request.loadModInfo(App.globalData.IPURL, param, function (response) {
                var result = JSON.stringify(response);
                result = JSON.parse(result);
                if(result.code=="00"){
                    //直接将json中返回的list赋值即可
                    self.setData({
                        tab: result.modlist
                    })
                }        
            })
        }
    }
    

    13.6.消息订阅接口

    13.7.获取openid

    获取openid首先要获取通过wx.login()获取code,然后code获取appid

    13.7.1.小程序端通过wx.login获取code

    获取openid首先要获取通过wx.login()获取code

    checkYhdm: function(){
            var self = this
            //1.通过微信获取code
            wx.login({
                success:function(res){
                    //2.根据获取的code,appid,fydm调用后台服务器去获取openid
                    var code = res.code;
                    var data={
                        "code": code,
                        "appid": wx.getAccountInfoSync().miniProgram.appId,
                        "fydm":App.globalData.FYDM
                    };
                    App.request.getUserOpenid(App.globalData.IPURL,data,function(response){
                        var result = JSON.stringify(response);
                        result = JSON.parse(result);
                        if(result.code=="00"){
                            //3.当获取openid成功后进行绑定操作
                            self.verifyUser(result.openid)
                        }else{
                            wx.showModal({
                                title: '温馨提示',
                                content: "openid获取失败,请联系管理员",
                                showCancel: false
                            })
                        }
                    })
                }
            })
        },
    

    13.7.2.将code和appid传递给后台服务器请求微信接口获取openid

    public WxMaJscode2SessionResult jsCode2SessionInfo(String jsCode) throws WxErrorException {
            WxMaConfig config = this.getWxMaConfig();
            Map<String, String> params = new HashMap(8);
            params.put("appid", config.getAppid());
            params.put("secret", config.getSecret());
            params.put("js_code", jsCode);
            params.put("grant_type", "authorization_code");
            String result = this.get("https://api.weixin.qq.com/sns/jscode2session", Joiner.on("&").withKeyValueSeparator("=").join(params));
            return WxMaJscode2SessionResult.fromJson(result);
        }
    

    13.8.小程序之间的跳转

    13.8.1.原小程序通过准备跳转到其他小程序

    通过wx.navigateToMiniProgram完成跳转

    • appId是目标小程序的APPID
    • path是目标小程序的页面,如果需要携带参数,在path后加?param1=xxxx¶m2=yyyy
    //跳转博思支付小程序完成支付
    payBosiRequest: function(res){
        if (res.data.success == true) {
            var extraInfo = JSON.parse(res.data.extraInfo);
            wx.navigateToMiniProgram({
                appId: extraInfo.miniprogram.appid,
                path: extraInfo.miniprogram.pagepath,
                success(res) {
                    console.log("跳转博思支付成功");
                }
            })
        }
    }
    

    13.8.2.目标小程序的接收参数并加载页面

     /**
       * 生命周期函数--监听页面显示
       */
      onShow: function () {
        this.setData({
          zfje: 0.00
        })
        var obj = wx.getLaunchOptionsSync()
        var userInfo = obj.referrerInfo.extraData
        var appId = obj.referrerInfo.appId
        if (appId != undefined && appId.length > 0) {
          if (userInfo != undefined) {
            var xm = userInfo.xm
            var sfzh = userInfo.sfzh
            if (xm != undefined && xm.length > 0 && sfzh != undefined && sfzh.length > 0) {
              wx.setStorageSync("userInfos", userInfo)
              this.getWjYjDzfRequest()
            } else {
              wx.navigateTo({
                url: '/pages/login/login',
              })
            }
          } else {
            wx.navigateTo({
              url: '/pages/login/login',
            })
          }
        } else {
          this.getWjYjDzfRequest()
        }
      },
    
    

    13.9.微信小程序嵌套H5页面

    13.9.1.定义小程序的H5容器container.js

    对于调用H5页面使用微信小程序的H5容器,对传递来的参数先使用base64编码,避免链接中的问号等情况造成错误

    const App = getApp();
    var Base64 = require('../../utils/base64Decode.js');
    Page({
        /**
         * 页面的初始数据
         */
        data: {
            urlstr:""
        },
    
        /**
         * 生命周期函数--监听页面加载
         */
        onLoad: function (options) {
            //页面加载时
            //1.获取服务后台地址+options携带的h5页面路径+缓存的必要参数拼接页面地址
            var userInfos = wx.getStorageSync("userInfos");
            this.setData({
                urlstr: App.globalData.IPURL + Base64.decode(options.pageUrl)+"?yhdm="+userInfos.yhdm
            })
        },
    })
    

    13.9.2.定义小程序的H5容器container.wxml

    <web-view src="{{urlstr}}">web-view>
    

    container.wxss和container.json不需要任何配置,省略即可

    13.9.3.其他页面跳转到该页面

    通过navigator标签携带参数跳转到container页面,携带参数通过onLoad的options接受处理

    
    <view class="weui-grids">
        <view class="weui-grid" wx:for="{{tab}}" wx:key="gndm">
            <navigator url="/pages/container/container?pageUrl={{item.url}}&openid={{openid}}&yhdm={{yhdm}}">
                <view class='weui_grid_bg'>
                    
                    <view class="weui_grid_icon">
                        <image src="{{item.icon}}" mode="scaleToFill" />
                    view>
                    
                    <text class="weui_grid_label">{{item.name}}text>
                    
                    <text class="weui_grid_info">{{item.info}}text>
                view>
            navigator>
        view>
    view>
    

    13.10.H5.页面的事件携带参数跳转到微信小程序

    13.10.1.H5.页面引入相关的JS文件

    <script type="text/javascript" th:src="@{/static/js/jweixin-1.3.2.js}"></script>
    

    13.10.2.H5.页面JS函数跳转到微信小程序页面

    function downloadSp(id) {
        if("miniProgram" == pageType){
            var wsAhdm = $.trim(id.split("_", -1)[0]);
            var xh = $.trim(id.split("_", -1)[1]);
            if (wsAhdm == "" || xh == "") {
                layerMsg("文书尚未生成");
                return;
            }
            wx.miniProgram.navigateTo({url: "/pages/downloadFile/downloadFile?ahdm=" +wsAhdm + "&jzxh=" + xh});
        }else {
          //略
        }
    }
    

    13.10.3.微信小程序准备downloadFile页面

    1. downloadFile.js

      // pages/downloadFile/downloadFile.js
      const App = getApp();
      Page({
          /**     
           * 页面的初始数据     
           */
          data: {},
          /**     
           * 生命周期函数--监听页面加载     
           */
          onLoad: function (options) {
              var ahdm = options.ahdm;
              var jzxh = options.jzxh;
              console.log("ahdm:" + ahdm);
              wx.downloadFile({
                  url: App.globalData.IPURL + 'wak/downloadSp?ahdm=' + ahdm + '&jzxh=' + jzxh,
                  success: function (res) {
                      wx.saveFile({
                          tempFilePath: res.tempFilePath,
                          success: function (res2) {
                              wx.openDocument({
                                  filePath: res2.savedFilePath,
                                  success: function (res) {}
                              })
                          }
                      })
                  }
              })
              wx.navigateBack();
          }
      })
      
    2. downloadFile.wxml

      <view>view>
      

    13.11.定义全局变量

    一般设置全局变量做到修改时全部修改,例如后台服务器地址

    13.11.1.在微信小程序的app.js定义全局变量

    globalData: {
        // 示例:IPURL:'http://ip:port/xszfweb/'
        IPURL: 'http://192.168.1.169:8088/xszfweb/',
        //订阅消息模板
        SubscribeMsgTemplate:['F9eVJkbsidSFWadWAdXsj7Cjlzxg_CbtCc5e3CyOK1g']
    },
    

    13.11.2.在需要使用的页面的js中使用全局变量

    1. 首先引用getApp()赋值给App
    2. 然后通过变量App使用获取全局变量App.globalData.IPURL
    const App = getApp();
    Page({
        /**
         * 初始化时获取页面的功能模块信息
         */
        loadModInfo :function(){
            var self = this
            var param ={
                "mod_id":"WAK",
                "fydm":App.globalData.FYDM
            }
            App.request.loadModInfo(App.globalData.IPURL, param, function (response) {
                var result = JSON.stringify(response);
                result = JSON.parse(result);
                if(result.code=="00"){
                    self.setData({
                        tab: result.modlist
                    })
                }        
            })
        }
    })
    

    13.12.获取小程序APPID

    wx.getAccountInfoSync().miniProgram.appId
    

    13.13.注意请求异步性问题

    function sendCheckMsg(param){
        var result="error";
        App.request.noticeCheckRes(App.globalData.IPURL, param, function (response) {
            var msg = JSON.stringify(response);
            msg = JSON.parse(msg);
            console.log(msg);
            if(msg.code=="00"){
                result = "succ";
            }   
        })
        return result;
    }
    

    当别的方法调用该函数,当noticeCheckRes调用成功时,因为其函数的请求的异步性,return函数已经执行,故返回的还是error

    13.14.文件下载

    13.14.1.downloadFile.wxml

    <view>
    	<view class="btn" bindtap="load">下载view>
        <loading hidden="{{  loadingHidden }}">加载中...loading>
    view>
    

    13.14.2.downloadFile.js

    Page({
        /**
         * 页面的初始数据
         */
        data: {
            loadingHidden: "true"
        },
    
        /**
         * 生命周期函数--监听页面加载
         */
        onLoad: function (options) {},
        load: function () {
            this.setData({
                loadingHidden: false
            })
            let self = this;
            wx.downloadFile({
                url: 'http://192.168.1.160:8088/xszfweb/wak/downloadSp?ahdm=115020201002000050&jzxh=0052&ver=1600409402056',
                success: function (res) {
                    var filePath = res.tempFilePath;
                    console.log(res)
                    //页面显示加载动画
                    wx.openDocument({
                        filePath: filePath,
                        success: function (res) {
                            self.setData({
                                loadingHidden: true
                            })
                            console.log('打开文档成功')
                        }
                    })
                }
            })
        }
    })
    

    13.15.在图标加上数量提示

    微信小程序_第65张图片

    在图标上醒目的数字提示,告知用户有待办事项

    13.15.1.index.wxml

    <view class="weui-grid" wx:for="{{tab}}" wx:key="gndm">
        
        <view wx:if="{{item.type=='01'}}">
            <navigator url="/pages/container/container?pageUrl={{item.url}}">
                <view class='weui_grid_bg'>
                    
                    <view class="weui_grid_icon">
                        <image src="{{item.icon}}" mode="scaleToFill" />
                        
                        <text class="span"
                              wx:if="{{(item.mark=='true')&&(item.digital>0)&&(item.digital<=99)}}">{{item.digital}}text>
                        <text class="span" wx:elif="{{(item.mark=='true')&&(item.digital>99)}}">99+text>
                    view>
                    
                    <text class="weui_grid_label">{{item.name}}text>
                    
                    <text class="weui_grid_info">{{item.info}}text>
                view>
            navigator>
        view>
    view>
    

    13.15.2.index.js

    保证item中包含digital参数,大于0即可

    13.15.3.index.wxss

    .weui-grid .span {
        position: absolute;
        /* 根据需要调整top和right */
        top: 0rpx;
        right: 85rpx;
        display: inline-block;
        padding: 4rpx 10rpx;
        min-width: 16rpx;
        border-radius: 36rpx;
        background-color: #fa5151;
        /* background-color: var(--weui-RED); */
        color: #fff;
        line-height: 1.2;
        text-align: center;
        font-size: 24rpx;
    }
    

    13.16.在H5页面增加排序图片

    13.16.1.示例

    31085229571

    13.16.2.实现

    1. 引入对应的layer的js文件和css文件

      <script th:src="@{/static/ext/layui/layui.js}">script>
      <script th:src="@{/static/ext/layer_mobile/layer.js}">script>
      <link rel="stylesheet" th:href="@{/static/ext/layui/css/layui.css}" media="all">
      <style type="text/css">
          html, body {
              width: 100%;
              height: 100%;
          }
      
          .arrUp {
              width: 0;
              height: 0;
              border: 8px solid transparent;
              border-bottom-color: #ccc;
              cursor: pointer;
          }
      
          .arrDown {
              width: 0;
              height: 0;
              border: 8px solid transparent;
              border-top-color: #ccc;
              margin-top: 5px;
              cursor: pointer;
          }
      style>
      
    2. H5

      <div class="arr" style="height: 0.70rem;width: 100%">
          <table style="width: 100%">
              <tr>
                  <td style="width: 25%;text-align: center">已缴金额td>
                  <td style="width: 25%;text-align: left">
                      <div class="arrUp" name="yjje" id="TKZE_ASC">div>
                      <div class="arrDown" name="yjje" id="TKZE_DESC">div>
                  td>
                  <td style="width: 25%;text-align: center">可退金额td>
                  <td style="width: 25%;text-align: left">
                      <div class="arrUp" name="tkje" id="WTKZE_ASC">div>
                      <div class="arrDown" name="tkje" id="WTKZE_DESC">div>
                  td>
              tr>
          table>
      div>
      <input type="hidden" value="" id="sortType"/>
      <input type="hidden" value="ASC" id="sortDirection"/>
      
    3. JS函数

      $(document).ready(function () {
          $("div[name='yjje']").on("click", function () {
              var sortDirection = $('#sortDirection').val();
              if ("ASC" === sortDirection) {
                  $(".arrUp").css("border-bottom-color", '')
                  $(".arrDown").css("border-top-color", '')
                  $("#TKZE_DESC").css("border-top-color", "#3176ee");
                  sort("TKZE_DESC");
              } else {
                  $(".arrUp").css("border-bottom-color", '')
                  $(".arrDown").css("border-top-color", "")
                  $("#TKZE_ASC").css("border-bottom-color", "#3176ee");
                  sort("TKZE_ASC");
              }
          })
          $("div[name='tkje']").on("click", function () {
              var sortDirection = $('#sortDirection').val();
              if ("ASC" == sortDirection) {
                  $(".arrUp").css("border-bottom-color", '')
                  $(".arrDown").css("border-top-color", '')
                  $("#WTKZE_DESC").css("border-top-color", "#3176ee");
                  sort("WTKZE_DESC");
              } else {
                  $(".arrUp").css("border-bottom-color", '')
                  $(".arrDown").css("border-top-color", "")
                  $("#WTKZE_ASC").css("border-bottom-color", "#3176ee");
                  sort("WTKZE_ASC");
              }
          })
          searchData('init');
      });
      function sort(id) {
          var arr = id.split('_');
          $('#sortType').val(arr[0]);
          $('#sortDirection').val(arr[1]);
          search('refreshAll');
      }
      function search(optype) {
          var rowsNum = $("#rowsNum").val();
          var currentPage = Number($("#currentPage").text());
          var totalPage = $("#totalPage").text();
          if ("pageDown" == optype && currentPage < totalPage) {
              currentPage += 1;
          } else if ("pageUp" == optype && currentPage != 1) {
              currentPage -= 1;
          } else if ("refreshAll"==optype){
              //针对输入新的查询内容,全部数据刷新的操作
              currentPage = 1;
          } else if ("refresh" == optype) {
              //针对上拉只刷新刷新本页数据
          }
          var param = {
              "yhdm": $("#yhdm").val(),
              "ahorje": $("#ahorje").val(),
              "pagenum": rowsNum,
              "curpage": (currentPage - 1),
              "sortType": $('#sortType').val(),
              "sortDirection": $('#sortDirection').val()
          };
          sendMsg(param);
      }
      

      sortType,sortDirection存储参数

    13.17.在首页生成九宫格

    一般首页中需要展示为九宫格,或者六宫格展示所有的功能信息。点击功能一般为跳转到H5页面,打开小程序的另一个页面,或者调用小程序的函数等。故需要对不同情况进行不同的配置。

    微信小程序_第66张图片

    13.17.1.在数据库中配置不同的功能模块

    微信小程序_第67张图片

    建表SQL:

    CREATE TABLE T_MODULE_ONLINE (
    	LSH varchar(10) NOT NULL,
    	GNDM varchar(10) NOT NULL,
    	GNMC varchar(20) NOT NULL,
    	GN_URL varchar(250) NULL,
    	IMG_URL varchar(250) NULL,
    	PXH int NULL,
    	STATE varchar(1) NULL,
    	REMAKE varchar(250) NULL,
    	MOD_ID varchar(20) NULL,
    	FYDM varchar(6) NOT NULL,
    	PAGE_TYPE varchar(2) NULL,
    	CONSTRAINT T_MODULE_ONLINE_PK PRIMARY KEY (LSH)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    INSERT T_MODULE_ONLINE (LSH,GNDM,GNMC,GN_URL,IMG_URL,PXH,STATE,REMAKE,MOD_ID,FYDM,PAGE_TYPE) VALUES('1','WAK01','我的案款','wak/wdakView','/icon/wdakLog.png',1,'1','进行线上支付','WAK','999999','01');
    

    13.17.2.index.js加载功能模块

    const App = getApp();
    var Base64 = require('../../utils/base64Decode.js');
    Page({
        /**
         * 页面的初始数据
         */
        data: {
            yhxm: '',
            dwdm: '',
            yhdm: '',
            tab: []
            //测试数据
        },
    
        /**
         * 生命周期函数--监听页面加载
         */
        onLoad: function (options) {
            var userInfo = wx.getStorageSync("userInfos");
            this.setData({
                yhxm: userInfo.xm,
                dwdm: userInfo.dwdm,
                yhdm: userInfo.yhdm,
            })
            //加载功能模块数据
            this.loadModInfo();
        },
        /**
         * 初始化时获取页面的功能模块信息
         */
        loadModInfo: function () {
            var self = this;
            var userInfo = wx.getStorageSync("userInfos");
            var param = {
                "mod_id": "WAK",
                "fydm": App.globalData.FYDM,
                "yhdm": userInfo.yhdm
            }
            console.log("初始化时获取页面的功能模块的参数是:" + param);
            App.request.loadModInfo(App.globalData.IPURL, param, function (response) {
                var result = JSON.stringify(response);
                result = JSON.parse(result);
                // console.log(result);
                if (result.code == "00") {
                    //遍历首页的功能模块,为其跳转的地址根据功能代码(gndm)为其赋值参数
                    //1.如果是跳转到H5页面,将地址和参数准备好后使用Base64编码后存放在url中,在container.js中获取后直接解码使用
                    for (var i = 0; i < result.modlist.length; i++) {
                        var module = result.modlist[i];
                        if (module.gndm == "WAK01") {
                            module.url = Base64.encode(module.url + "?openid=" + userInfo.openid + "&yhdm=" + userInfo.yhdm);
                        } else if (module.gndm == "WAK02") {
                            module.url = Base64.encode(module.url + "?yhid=" + userInfo.yhdm + "&fydm=" + userInfo.dwdm);
                        }
                        //如果module.url为空,则为未配置页面,跳转到指定的404页面
                        if (module.url == " " || module.url == "") {
                            module.type = '01';
                            module.url = Base64.encode("wak/errorPage" + "?title=" + module.name);
                        }
                    }
                    self.setData({
                        tab: result.modlist
                    })
                }
            })
        },
    
        /** 
         * 调用微信扫一扫进行识别二维码进行,并将二维码的内容传递到sendCheckMsg做处理
         */
        getScancode: function () {},
    })
    

    13.17.3.index.wxml

    <view class="safk_index">
    	
    	<view class="index_platform_img">
    		<view class="index_platform_view">
    			<view class="title">view>
    			<image mode="widthFix" src="/images/banner1.jpg" class="background">image>
    			<view class='imagesize'>
    				<image src="/icon/wakLogo.png" style="position: fixed" class="logo"
    					style="width: 200rpx;height:200rpx ;margin-top:60rpx;padding-left:275rpx;padding-right:275rpx">
    				image>
    			view>
    			<view class="child">人民法院微案款平台view>
    		view>
    	view>
    
    	
    	<view class="user_welcome_wrap">
    		<view>{{'欢迎您,'+yhxm}}view>
    	view>
    
    	
    	<view class="weui-grids">
    		<view class="weui-grid" wx:for="{{tab}}" wx:key="gndm">
    			
    			<view wx:if="{{item.type=='01'}}">
    				<navigator url="/pages/container/container?pageUrl={{item.url}}">
    					<view class='weui_grid_bg'>
    						
    						<view class="weui_grid_icon">
    							<image src="{{item.icon}}" mode="scaleToFill" />
    							
    							<text class="span"
    								wx:if="{{(item.mark=='true')&&(item.digital>0)&&(item.digital<=99)}}">{{item.digital}}text>
    							<text class="span" wx:elif="{{(item.mark=='true')&&(item.digital>99)}}">99+text>
    						view>
    						
    						<text class="weui_grid_label">{{item.name}}text>
    						
    						<text class="weui_grid_info">{{item.info}}text>
    					view>
    				navigator>
    			view>
    			
    			<view wx:elif="{{item.type=='03'}}">
    				<navigator url="{{item.url}}">
    					<view class='weui_grid_bg'>
    						
    						<view class="weui_grid_icon">
    							<image src="{{item.icon}}" mode="scaleToFill" />
    						view>
    						
    						<text class="weui_grid_label">{{item.name}}text>
    						
    						<text class="weui_grid_info">{{item.info}}text>
    					view>
    				navigator>
    			view>
    			
    			<view wx:else>
    				<view bindtap="{{item.url}}" class='weui_grid_bg'>
    					
    					<view class="weui_grid_icon">
    						<image src="{{item.icon}}" mode="scaleToFill" />
    					view>
    					
    					<text class="weui_grid_label">{{item.name}}text>
    					
    					<text class="weui_grid_info">{{item.info}}text>
    				view>
    			view>
    		view>
    	view>
    view>
    

    13.17.4.index.wxss

    .safk_index .title_index {
        height: 80rpx;
    }
    
    .safk_index .title_index .title_msg {
        display: flex;
    }
    
    .safk_index .title_index .title_msg .title_img_wrap {
        flex: 1;
        display: flex;
        justify-content: left;
        align-items: center;
    }
    
    .safk_index .title_index .title_msg .title_img_wrap image {
        margin-left: 10rpx;
        width: 65rpx;
        height: 65rpx;
    }
    
    .safk_index .title_index .title_msg .title_info_wrap {
        flex: 7;
        display: flex;
        justify-content: left;
        align-items: left;
        flex-direction: column;
        justify-content: space-around;
    }
    
    .safk_index .index_platform_img .index_platform_view {
        width: 750rpx;
        height: 340rpx;
        position: relative;
    }
    
    .safk_index .index_platform_img .index_platform_view image {
        width: 100%;
    }
    
    .safk_index .user_welcome_wrap {
        margin-top: 80rpx;
        background-color: #fff;
        padding: 20rpx;
    }
    
    .weui-grids {
        position: relative;
        overflow: hidden;
    }
    
    .weui-grids:before {
        content: " ";
        position: absolute;
        left: 0;
        top: 0;
        right: 0;
        height: 2rpx;
        border-top: 2rpx solid #d9d9d9;
        color: #d9d9d9;
        -webkit-transform-origin: 0 0;
        transform-origin: 0 0;
        -webkit-transform: scaleY(0.5);
        transform: scaleY(0.5);
    }
    
    .weui-grids:after {
        content: " ";
        position: absolute;
        left: 0;
        top: 0;
        width: 2rpx;
        bottom: 0;
        border-left: 2rpx solid #d9d9d9;
        color: #d9d9d9;
        -webkit-transform-origin: 0 0;
        transform-origin: 0 0;
        -webkit-transform: scaleX(0.5);
        transform: scaleX(0.5);
    }
    
    .weui-grid {
        position: relative;
        float: left;
        padding: 20rpx 20rpx;
        width: 50%;
        height: 200rpx;
        box-sizing: border-box;
    }
    
    .weui-grid:before {
        content: " ";
        position: absolute;
        right: 0;
        top: 0;
        width: 2rpx;
        bottom: 0;
        border-right: 2rpx solid #d9d9d9;
        color: #d9d9d9;
        -webkit-transform-origin: 100% 0;
        transform-origin: 100% 0;
        -webkit-transform: scaleX(0.5);
        transform: scaleX(0.5);
    }
    
    .weui-grid:after {
        content: " ";
        position: absolute;
        left: 0;
        bottom: 0;
        right: 0;
        height: 2rpx;
        border-bottom: 2rpx solid #d9d9d9;
        color: #d9d9d9;
        -webkit-transform-origin: 0 100%;
        transform-origin: 0 100%;
        -webkit-transform: scaleY(0.5);
        transform: scaleY(0.5);
    }
    
    .weui-grid:active {
        background-color: #ECECEC;
    }
    
    .weui_grid_bg {
        position: relative;
        float: left;
        padding: 0rpx 0rpx;
        width: 100%;
        box-sizing: border-box;
    }
    
    .weui_grid_icon {
        width: 64rpx;
        height: 64rpx;
        margin: 0 auto;
    }
    
    
    .weui_grid_icon image {
        display: block;
        width: 100%;
        height: 100%;
    }
    
    .weui_grid_icon+.weui_grid_label {
        margin-top: 4rpx;
    }
    
    
    .weui_grid_label {
        display: block;
        text-align: center;
        font-weight: bold;
        color: #000;
        font-size: 28rpx;
        white-space: nowrap;
        text-overflow: ellipsis;
        overflow: hidden;
    }
    
    .weui_grid_info {
        display: block;
        text-align: center;
        font-weight: bold;
        color: #C0C0C0;
        font-size: 24rpx;
        text-overflow: ellipsis;
        overflow: hidden;
    }
    
    .child {
        width: 750rpx;
        height: 48rpx;
        position: absolute;
        font-size: 52rpx;
        color: white;
        left: 0;
        top: 260rpx;
        right: 0;
        bottom: 0;
        margin: auto;
        text-align: center;
    }
    
    .background {
        width: 100%;
        height: 100%;
        position: fixed;
        background-size: 100% 100%;
        z-index: -1;
    }
    
    .title_name {
        width: 750rpx;
        height: 40rpx;
        position: absolute;
        font-size: 28rpx;
        color: white;
        left: 0;
        top: 40rpx;
        right: 0;
        bottom: 0;
        text-align: center;
    }
    
    .bgv {
        width: 100%;
        height: auto;
        position: absolute;
        top: 0;
        bottom: 0;
    }
    
    .weui-grid .span {
        position: absolute;
        /* 根据需要调整top和right */
        top: 0rpx;
        right: 85rpx;
        display: inline-block;
        padding: 4rpx 10rpx;
        min-width: 16rpx;
        border-radius: 36rpx;
        background-color: #fa5151;
        /* background-color: var(--weui-RED); */
        color: #fff;
        line-height: 1.2;
        text-align: center;
        font-size: 24rpx;
    }
    

    你可能感兴趣的:(前端,小程序,小程序)