小程序学习笔记(一)

小程序与普通网页的开发

  1. 小程序的逻辑层和视图层是分开的。
  2. 小程序提供了自己的视图层描述语言 WXML 和 WXSS,以及基于 JavaScript 的逻辑层框架,并在视图层与逻辑层间提供了数据传输和事件系统,让开发者能够专注于数据与逻辑。

代码构成

JSON 配置

1. app.json

常用的app配置
{
  // 页面路径列表,每一项都对应一个页面的 路径(含文件名) 信息。文件名不需要写文件后缀,框架会自动去寻找对应位置的 .json, .ts, .wxml, .less 四个文件进行处理。
  "pages": [
    "pages/index/index",
    "pages/logs/index"
  ],
  // 全局的默认窗口表现,用于设置小程序的状态栏、导航条、标题、窗口背景色。
  "window": {
    "navigationBarTitleText": "Demo"
  },
  // 底部 tab 栏的表现,其中 list 接受一个数组,只能配置最少 2 个、最多 5 个 tab。
  "tabBar": {
    "list": [{
      "pagePath": "pages/index/index",
      "text": "首页"
    }, {
      "pagePath": "pages/logs/index",
      "text": "日志"
    }]
  },
  // 网络超时时间,单位均为毫秒。
  "networkTimeout": {
    "request": 10000,
    "downloadFile": 10000
  },
  // 是否开启 debug 模式,默认关闭。调试信息以 info 的形式给出,其信息有 Page 的注册,页面路由,数据更新,事件触发等。
  "debug": true
}
完整配置项说明请参考[小程序全局配置](https://developers.weixin.qq.com/miniprogram/dev/reference/configuration/app.html)

2. 页面配置

每一个小程序页面也可以使用同名 .json 文件来对本页面的窗口表现进行配置,页面中配置项会覆盖 app.json 的 window 中相同的配置项。
完整配置项说明请参考小程序页面配置

3. sitemap 配置

用来配置小程序及其页面是否允许被微信索引。
完整配置项说明请参考小程序 sitemap 配置
注:sitemap 的索引提示是默认开启的,如需要关闭 sitemap 的索引提示,可在小程序项目配置文件 project.config.json 的 setting 中配置字段 checkSiteMap 为 false。

框架

场景值

1. 介绍

场景值用来描述用户进入小程序的路径。一个场景值代表一种进入小程序的路径。
完整场景值的含义请查看场景值列表

2. 获取

对于小程序,可以在 App 的 onLaunch 和 onShow,或wx.getLaunchOptionsSync 中获取上述场景值。

逻辑层

1. 介绍

逻辑层将数据进行处理后发送给视图层,同时接受视图层的事件反馈。
注意:小程序框架的逻辑层并非运行在浏览器中,因此 JavaScript 在 web 中一些能力都无法使用,如 window,document 等。

2. 注册小程序

使用App()注册小程序实例,App() 必须在 app.js 中调用,必须调用且只能调用一次,不然会出现无法预期的后果。
详细的参数含义和使用请参考 App 参考文档

注册实例常用的监听函数
// app.js
App({
  onLaunch (options) {
    // 生命周期回调——监听小程序初始化,全局只触发一次
  },
  onShow (options) {
    // 生命周期回调——监听小程序启动或切前台
  },
  onHide () {
    // 生命周期回调——监听小程序切后台
  },
  onError (msg) {
    // 错误监听函数
    console.log(msg)
  },
  globalData: 'I am global data'
})

整个小程序只有一个 App 实例,是全部页面共享的。开发者可以通过 getApp 方法获取到全局唯一的 App 实例,获取App上的数据或调用开发者注册在 App 上的函数。

// xxx.js
const appInstance = getApp()
console.log(appInstance.globalData) // I am global data

3. 注册页面

每个页面,都需要在页面对应的 js 文件中进行注册,指定页面的初始数据、生命周期回调、事件处理函数等。

  • 简单的页面可以使用 Page() 进行构造。详细的参数含义和使用请参考 Page 参考文档
Page 注册页面
//index.js
Page({
  data: {
    text: "This is page data."
  },
  onLoad: function(options) {
    // 页面创建时执行
  },
  onShow: function() {
    // 页面出现在前台时执行
  },
  onReady: function() {
    // 页面首次渲染完毕时执行
  },
  onHide: function() {
    // 页面从前台变为后台时执行
  },
  onUnload: function() {
    // 页面销毁时执行
  },
  onPullDownRefresh: function() {
    // 触发下拉刷新时执行
  },
  onReachBottom: function() {
    // 页面触底时执行
  },
  onShareAppMessage: function () {
    // 页面被用户分享时执行
  },
  onPageScroll: function() {
    // 页面滚动时执行
  },
  onResize: function() {
    // 页面尺寸变化时执行
  },
  onTabItemTap(item) {
    // tab 点击时执行
    console.log(item.index)
    console.log(item.pagePath)
    console.log(item.text)
  },
  // 事件响应函数
  viewTap: function() {
    this.setData({
      text: 'Set some data for updating view.'
    }, function() {
      // this is setData callback
    })
  },
  // 自由数据
  customData: {
    hi: 'MINA'
  }
})

- 复杂的页面可以使用 Component 构造器来构造,这种创建方式非常类似于 自定义组件 。 Component 构造器的主要区别是:方法需要放在 methods: { } 里面。具体细节请阅读 [Component 构造器 章节](https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/component.html)
Component 注册页面
Component({
  data: {
    text: "This is page data."
  },
  methods: {
    onLoad: function(options) {
      // 页面创建时执行
    },
    onPullDownRefresh: function() {
      // 下拉刷新时执行
    },
    // 事件响应函数
    viewTap: function() {
      // ...
    }
  }
})
- 页面可以引用 behaviors 。 behaviors 可以用来让多个页面有相同的数据字段和方法。具体用法参见 [behaviors](https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/behaviors.html)
behaviors 用法
// my-behavior.js
module.exports = Behavior({
  data: {
    sharedText: 'This is a piece of data shared between pages.'
  },
  methods: {
    sharedMethod: function() {
      this.data.sharedText === 'This is a piece of data shared between pages.'
    }
  }
})
// page-a.js
var myBehavior = require('./my-behavior.js')
Page({
  behaviors: [myBehavior],
  onLoad: function() {
    this.data.sharedText === 'This is a piece of data shared between pages.'
  }
})

4. 生命周期

5. 页面路由

  • 采用栈的思想控制页面路由

6. 模块化

  • 可以将一些公共的代码抽离成为一个单独的 js 文件,作为一个模块。模块只有通过 module.exports 或者 exports 才能对外暴露接口(推荐使用 module.exports)。
  • 小程序目前不支持直接引入 node_modules , 开发者需要使用到 node_modules 时候建议拷贝出相关的代码到小程序的目录中,或者使用小程序支持的 npm 功能。

视图层

1. 介绍

框架的视图层由 WXML(WeiXin Markup language) 与 WXSS(WeiXin Style Sheet) 编写,由组件来进行展示。

2. WXML

  • 数据绑定

    标题 内容 示例
    内容 使用双大括号将变量包起来 <view> {{ message }} </view>
    组件属性 需要在双引号之内 <view id="item-{{id}}"> </view>
    控制属性 需要在双引号之内 <view wx:if="{{condition}}"> </view>
    关键字 需要在双引号之内 <checkbox checked="{{false}}"> </checkbox>
    三元运算 可以在 {{}} 内进行简单的运算 <view hidden="{{flag ? true : false}}"> Hidden </view>
    算数运算 可以在 {{}} 内进行简单的运算 <view> {{a + b}} + {{c}} + d </view>
    逻辑判断 可以在 {{}} 内进行简单的运算 <view wx:if="{{length > 5}}"> </view>
    字符串运算 可以在 {{}} 内进行简单的运算 <view>{{"hello" + name}}</view>
    数据路径运算 可以在 {{}} 内进行简单的运算 <view>{{object.key}} {{array[0]}}</view>
    数组 可以在 {{}} 内直接进行组合 <view wx:for="{{[zero, 1, 2, 3, 4]}}"> {{item}} </view>
    对象 可以在 {{}} 内直接进行组合 <template is="objectCombine" data="{{for: a, bar: b}}"></template>
  • 列表渲染

    标题 内容 示例
    wx:for 默认数组的当前项的下标变量名默认为 index,数组当前项的变量名默认为 item。 <view wx:for="{{array}}">{{index}}: {{item.message}}</view>
    wx:for 使用 wx:for-item 可以指定数组当前元素的变量名,使用 wx:for-index 可以指定数组当前下标的变量名。 <view wx:for="{{array}}" wx:for-index="idx" wx:for-item="itemName">{{idx}}: {{itemName.message}}</view>
    block wx:for 渲染一个包含多节点的结构块 <block wx:for="{{[1, 2, 3]}}"><view> {{index}}: </view><view> {{item}} </view></block>
    wx:key 指定列表中项目的唯一的标识符。如果明确知道该列表是静态,或者不必关注其顺序,可以选择忽略。 wx:key 的值以两种形式提供:1. 字符串,代表在 for 循环的 array 中 item 的某个 property,该 property 的值需要是唯一的。<switch wx:for="{{objectArray}}" wx:key="unique" style="display: block;"> {{item.id}} </switch> 2. 保留关键字 *this 代表在 for 循环中的 item 本身,这种表示需要 item 本身是一个唯一的字符串或者数字。<switch wx:for="{{numberArray}}" wx:key="*this" style="display: block;"> {{item}} </switch>
  • 条件渲染

    标题 内容 示例
    wx:if 判断是否需要渲染该代码块,也可以用 wx:elifwx:else 来添加一个 else 块。 <view wx:if="{{length > 5}}"> 1 </view><view wx:elif="{{length > 2}}"> 2 </view><view wx:else> 3 </view>
    block wx:if 一次性判断多个组件标签 <block wx:if="{{true}}"><view> view1 </view><view> view2 </view></block>

    【注意】:<block/> 并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性。

    wx:if vs hidden
    • wx:if:在切换时组件会销毁和重新渲染。
    • hidden:组件始终会渲染,只是简单的控制显示与隐藏。
    • 一般来说,wx:if 有更高的切换消耗而 hidden 有更高的初始渲染消耗。因此,如果需要频繁切换的情景下,用 hidden 更好,如果在运行时条件不大可能改变则 wx:if 较好。
  • 模板
    定义模板:使用name属性,作为模板的名字。

    点击查看代码
    <!--
     index: int
     msg: string
     time: string
    -->
    <template name="msgItem">
     <view>
       <text> {{index}}: {{msg}} </text>
       <text> Time: {{time}} </text>
     </view>
    </template>
    

    使用模板:使用 is 属性,声明需要的使用的模板,然后将模板所需要的 data 传入。is 属性可以使用 Mustache 语法,来动态决定具体需要渲染哪个模板。

    点击查看代码
    <template is="msgItem" data="{{...item}}"/>
    
    <block wx:for="{{[1, 2, 3, 4, 5]}}">
      <template is="{{item % 2 == 0 ? 'even' : 'odd'}}"/>
    </block>
    
    

    模板的作用域:模板拥有自己的作用域,只能使用 data 传入的数据以及模板定义文件中定义的 <wxs /> 模块。

  • 引用

    1. import可以在该文件中使用目标文件定义的template
    2. include 可以将目标文件除了 <template/> <wxs/> 外的整个代码引入,相当于是拷贝到 include 位置。

组件

视图容器

1. page-container

页面容器。用于在页面内进行复杂的界面设计(比如在页面中弹出半屏的弹窗,在页面内夹在一个全屏的子页面等),用户进行返回操作会直接离开当前页面,不符合用户预期,预期应为关闭当前弹出的组件。 为此提供“假页”容器组件,效果类似于 popup 弹出层,页面内存在该容器时,当用户进行返回操作,关闭该容器不关闭页面。返回操作包括三种情形,右滑手势、安卓物理返回键和调用 navigateBack 接口。

2. view

视图容器。

posted @ 2022-03-15 16:15  shellon  阅读(114)  评论(0编辑  收藏  举报