微信小程序开发——第2章 小程序代码组成

本文为微信小程序开发的学习总结

2.1 JSON 配置

JSON 是一种数据格式,在小程序中起静态配置的作用。JSON 在小程序运行之前就决定了小程序一些表现,需要注意的是小程序是无法在运行过程中去动态更新JSON 配置文件从而发生对应的变化的。

2.1.1 JSON 语法

JSON文件都是被包裹在一个大括号中 {},通过key-value的方式来表达数据。JSON的Key必须包裹在一个双引号中且无法使用注释。
在这里插入图片描述

2.2 WXML 模板

2.2.1 介绍

打开 pages/wxml/index.wxml 文件:

<!--pages/wxml/index.wxml-->

<text>pages/wxml/index.wxml</text>

​不带有任何逻辑功能的 WXML 基本语法如下:

<!-- 在此处写注释 -->

<标签名 属性名1="属性值1" 属性名2="属性值2" ...> ...</标签名>

​一个完整的 WXML语句由一段开始标签和一段结束标签组成,在标签中可以是内容,也可以是其他的 WXML 语句。WXML 要求标签必须是严格闭合的。
标签可以拥有属性,属性提供了有关的 WXML元素更多信息。属性总是定义在开始标签中,除了一些特殊的属性外,其余属性的格式都是key=“value” 的方式成对出现。WXML中的属性是大小写敏感的。
带有属性的图片标签

<image class="userinfo-avatar" src="./image/a.png" ></image>

2.2.2 数据绑定

可以动态的改变渲染界面
数据绑定示例:

<!--pages/wxml/index.wxml-->
<text>当前时间:{{time}}</text>

打开 pages/wxml/index.js 文件,在 data 的大括号中加入:time: (new Date()).toString()
示例:

// pages/wxml/index.js
Page({
  /**
   * 页面的初始数据
   */
  data: {
    time: (new Date()).toString()
  },
})

模拟器刷新后正确的展示了当前时间,并且每次编译时间都会被更新。
WXML 通过 {{变量名}} 来绑定 WXML 文件和对应的 JavaScript 文件中的 data 对象属性。
为了保持简单,通过以下格式来展示上述的代码逻辑,使用第一段注释来表明 WXML 对应的脚本文件中的 data 结构。
展示格式:

<!--
{
  time: (new Date()).toString()
}
-->
<text>当前时间:{{time}}</text>

属性值也可以动态的去改变,有所不同的是,属性值必须被包裹在双引号中,如下:

<text data-test="{{test}}"> hello world</text>

2.2.3 逻辑语法

可以在 {{ }} 内进行简单的逻辑运算
三元运算:

<!-- 根据 a 的值是否等于 10 在页面输出不同的内容 -->
<text>{{ a === 10? "变量 a 等于10": "变量 a 不等于10"}}</text>

算术运算:

<!--
{ a: 1,  b: 2, c: 3 }
-->


<view> {{a + b}} + {{c}} + d </view>


<!-- 输出 3 + 3 + d -->

支持字符串的拼接:

<!--
{ name: 'world' }
-->


<view>{{"hello " + name}}</view>


<!-- 输出 hello world -->

{{ }}中还可以直接放置数字、字符串或者是数组(常量):

<text>{{[1,2,3]}}</text>

<!-- 输出 1,2,3 -->



<text>{{"hello world"}}</text>

<!-- 输出 hello world -->

2.2.4 条件逻辑

使用 wx:if="{{condition}}" 来判断是否需要渲染该代码块:

<view wx:if="{{condition}}"> True </view>

使用 wx:elif 和 wx:else 来添加一个 else 块:

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

因为 wx:if 是一个控制属性,需要将它添加到一个标签上。如果要一次性判断多个组件标签,可以使用一个 标签将多个组件包装起来,并在上边使用 wx:if 控制属性。

<block wx:if="{{true}}">
  <view> view1 </view>
  <view> view2 </view>
</block>

2.2.5 列表渲染

在组件上使用 wx:for 控制属性绑定一个数组,即可使用数组中各项的数据重复渲染该组件。数组的当前项的下标变量名默认为 index,数组当前项的变量名默认为 item

<!-- array 是一个数组 -->
<view wx:for="{{array}}">
  {{index}}: {{item.message}}
</view>

<!-- 对应的脚本文件
Page({
  data: {
    array: [{
      message: 'foo',
    }, {
      message: 'bar'
    }]
  }
})
-->

若不用默认设置,则应使用 wx:for-item 指定数组当前元素的变量名,使用 wx:for-index 指定数组当前下标的变量名:

<view wx:for="{{array}}" wx:for-index="idx" wx:for-item="itemName">
  {{idx}}: {{itemName.message}}
</view>

类似 block wx:if ,也可以将 wx:for 用在 <block/> 标签上,以渲染一个包含多节点的结构块。例如:

<block wx:for="{{[1, 2, 3]}}">
  <view> {{index}}: </view>
  <view> {{item}} </view>
</block>

如果列表中项目的位置会动态改变或者有新的项目添加到列表中,并且希望列表中的项目保持自己的特征和状态(如 <input/> 中的输入内容, <switch/> 的选中状态),需要使用 wx:key 来指定列表中项目的唯一的标识符。
wx:key 的值以两种形式提供:

  1. 字符串,代表在 for 循环的 array 中 item 的某个 property,该 property 的值需要是列表中唯一的字符串或数字,且不能动态改变。
  2. 保留关键字 this 代表在 for 循环中的 item 本身,这种表示需要 item 本身是一个唯一的字符串或者数字,如:

当数据改变触发渲染层重新渲染的时候,框架会使带有 key 的组件被重新排序,而不是重新创建,以保持组件自身的状态,提高列表渲染效率。
使用 wx:key 示例(WXML)

<switch wx:for="{{objectArray}}" wx:key="unique" > {{item.id}} </switch>
<button bindtap="switch"> Switch </button>
<button bindtap="addToFront"> Add to the front </button>


<switch wx:for="{{numberArray}}" wx:key="*this" > {{item}} </switch>
<button bindtap="addNumberToFront"> Add Number to the front </button>

使用 wx:key 示例(JavaScript)switch函数进行数据交换

Page({
  data: {
    objectArray: [
      {id: 5, unique: 'unique_5'},
      {id: 4, unique: 'unique_4'},
      {id: 3, unique: 'unique_3'},
      {id: 2, unique: 'unique_2'},
      {id: 1, unique: 'unique_1'},
      {id: 0, unique: 'unique_0'},
    ],
    numberArray: [1, 2, 3, 4]
  },
  switch: function(e) {
    const length = this.data.objectArray.length
    for (let i = 0; i < length; ++i) {
      const x = Math.floor(Math.random() * length)
      const y = Math.floor(Math.random() * length)
      const temp = this.data.objectArray[x]
      this.data.objectArray[x] = this.data.objectArray[y]
      this.data.objectArray[y] = temp
    }
    this.setData({
      objectArray: this.data.objectArray
    })
  },
  addToFront: function(e) {
    const length = this.data.objectArray.length
    this.data.objectArray = [{id: length, unique: 'unique_' + length}].concat(this.data.objectArray)
    this.setData({
      objectArray: this.data.objectArray
    })
  },
  addNumberToFront: function(e){
    this.data.numberArray = [ this.data.numberArray.length + 1 ].concat(this.data.numberArray)
    this.setData({
      numberArray: this.data.numberArray
    })
  }
})

2.2.6 模板——类似于C中的函数

WXML提供模板(template),可以在模板中定义代码片段,然后在不同的地方调用。使用 name 属性,作为模板的名字。然后在 <template/> 内定义代码片段,如:
定义模板:

<template name="msgItem">
  <view>
    <text> {{index}}: {{msg}} </text>
    <text> Time: {{time}} </text>
  </view>
</template>

使用 is 属性,声明需要的使用的模板,然后将模板所需要的 data 传入
模板使用示例(将注释中的item放在Page中):

<!--
item: {
  index: 0,
  msg: 'this is a template',
  time: '2016-06-18'
}
-->


<template name="msgItem">
  <view>
    <text> {{index}}: {{msg}} </text>
    <text> Time: {{time}} </text>
  </view>
</template>


<template is="msgItem" data="{{...item}}"/>

<!-- 输出
0: this is a template Time: 2016-06-18
-->

is可以动态决定具体需要渲染哪个模板。
动态使用模板:

<template name="odd">
  <view> odd </view>
</template>


<template name="even">
  <view> even </view>
</template>


<block wx:for="{{[1, 2, 3, 4, 5]}}">
  <template is="{{item % 2 == 0 ? 'even' : 'odd'}}"/>
</block>



<!-- 输出
odd
even
odd
even
odd
-->

2.2.7 引用

WXML 提供两种文件引用方式import和include。
import 可以在该文件中使用目标文件定义的 template,如:
在 item.wxml 中定义了一个叫 item的 template :

<!-- item.wxml -->
<template name="item">
  <text>{{text}}</text>
</template>

在 index.wxml 中引用了 item.wxml,就可以使用 item模板:

<import src="item.wxml"/>

<template is="item" data="{{text: 'forbar'}}"/>

2.3 WXSS样式

用于描述WXML的组件样式,也就是视觉上的效果。

2.3.1 文件组成

在这里插入图片描述
在这里插入图片描述
页面样式:与app.json注册过的页面同名且位置同级的WXSS文件。比如上图app.json注册了pages/rpx/index页面,那pages/rpx/index.wxss为页面pages/rpx/index.wxml的样式。
其它样式:其它样式可以被项目公共样式和页面样式引用

2.3.2 尺寸单位

为了适配不同宽度的屏幕,我们引入了rpx(responsive pixel)尺寸单位。小程序编译后,rpx会做一次px换算。

2.3.3 WXSS引用

样式引用:

@import './test_0.wxss'

由于WXSS最终会被编译打包到目标文件中,用户只需下载一次,在使用过程中不会因为样式引用产生多余的文件请求。

2.3.4 内联样式

WXSS内联样式:

<!--index.wxml-->

<!--内联样式-->
<view style="color: red; font-size: 48rpx"></view>

小程序支持动态更新内联样式:

<!--index.wxml-->

<!--可动态变化的内联样式-->
<!--
{
  eleColor: 'red',
  eleFontsize: '48rpx'
}
-->
<view style="color: {{eleColor}}; font-size: {{eleFontsize}}"></view>

2.3.5 选择器

WXSS优先级:
在这里插入图片描述
WXSS 选择器优先级权重:

view{ // 权重为 1
  color: blue
}

.ele{ // 权重为 10
  color: red
}

#ele{ // 权重为 100
  color: pink
}

view#ele{ // 权重为 1 + 100 = 101,优先级最高,元素颜色为orange
  color: orange
}

view.ele{ // 权重为 1 + 10 = 11
  color: green
}

2.3.6 官方样式库

WeUI.wxss基础样式库:
在这里插入图片描述

2.4 JavaScript 脚本

小程序的主要开发语言是 JavaScript,用来开发业务逻辑以及调用小程序的 API

2.4.1 ECMAScript

JavaScript 是 ECMAScript 的一种实现。小程序中的 JavaScript同浏览器中的 JavaScript 以及 NodeJS 中的 JavaScript 是不相同的。
在这里插入图片描述

2.4.2 小程序的执行环境

不同的平台的小程序的脚本执行环境有所区别。
小程序目前可以运行在三大平台:

  1. iOS平台,包括iOS9、iOS10、iOS11
  2. Android平台
  3. 小程序IDE

区别体现在三大平台实现的 ECMAScript 的标准有所不同。

在项目设置中,勾选 ES6 转 ES5,将 ECMAScript 6代码转为 ECMAScript 5代码,从而在所有的环境都能得到很好的执行。

2.4.3 模块化

小程序中可以将任何一个JavaScript 文件作为一个模块,通过module.exports 或者 exports 对外暴露接口。
B.js 引用模块A,并使用A暴露的multiplyBy2方法完成一个变量乘以 2 的操作。
模块示例:

// moduleA.js
module.exports = function( value ){
  return value * 2;
}

引用模块A:

// B.js

// 在B.js中引用模块A
var multiplyBy2 = require('./moduleA')
var result = multiplyBy2(4)

在需要使用这些模块的文件中,使用 require(path) 将公共代码引入——extern 函数:

var common = require('common.js')
Page({
  helloMINA: function() {
    common.sayHello('MINA')
  },
  goodbyeMINA: function() {
    common.sayGoodbye('MINA')
  }
})

2.4.4 脚本的执行顺序

小程序的执行的入口文件是 app.js 。并且会根据其中 require 的模块顺序决定文件的运行顺序。
app.js

/* a.js
console.log('a.js')
*/
var a = require('./a.js')
console.log('app.js')

/* b.js
console.log('b.js')
*/
var b = require('./b.js')

当 app.js 执行结束后,小程序会按照 app.json 中定义的 pages 的顺序逐一执行。

2.4.5 作用域

在文件中声明的变量和函数只在该文件中有效,不同的文件中可以声明相同名字的变量和函数,不会互相影响

当需要使用全局变量的时,通过使用全局函数 getApp() 获取全局的实例,并设置相关属性值
在脚本 a.js 中设置全局变量:

// a.js
// 获取全局变量
var global = getApp()
global.globalValue = 'globalValue'

在脚本 b.js 中访问 a.js 定义的全局变量:

// b.js
// 访问全局变量
var global = getApp()
console.log(global.globalValue) // 输出 globalValue

上述示例只有在 a.js 比 b.js 先执行才有效,当需要保证全局的数据可以在任何文件中安全的被使用到,那么可以在 App() 中进行设置
定义全局变量

// app.js
App({
  globalData: 1
})

获取以及修改 global 变量的方法

// a.js
// 局部变量
var localValue = 'a'

// 获取 global 变量
var app = getApp()

// 修改 global 变量
app.globalData++  // 执行后 globalData 数值为 2
发布了104 篇原创文章 · 获赞 49 · 访问量 7826

猜你喜欢

转载自blog.csdn.net/weixin_44413191/article/details/103994779