小程序开发——小程序的视图与渲染

 1.视图与渲染过程

 基本概念:

视图层由WXML页面文件和样式文件WXSS共同组成。事件是视图层和逻辑层沟通的纽带,用户操作触发事件后可通过同名的事件处理函数执行相应的逻辑,处理完成后,更新的数据又将再次渲染到页面上。

WXML页面:

WXML是框架设计的一套标签语言,结合基础组件和事件系统可构建出页面的结构。组件是视图的基本组成单元,组件的显示效果是由页面样式文件中定义的样式进行控制的。


  
    
    
      
       {{userInfo.nickName}} 
    
  
  
    {{motto}} 
  

 button组件简单使用案例

实现效果,如下图所示:

新建Chapter02项目与页面

小程序开发——小程序的视图与渲染_第1张图片

使用官方文档拷贝示例代码

进入微信官方小程序开发文档,其链接为:                  https://developers.weixin.qq.com/miniprogram/dev/framework/

 选择“组件”→“表单组件”→button一栏

小程序开发——小程序的视图与渲染_第2张图片 

由上图可以看到关于button组件所有可设置的属性,以及属性的可选值,还有一些使用的注意事项等。将页面拖动到底部可以看到微信官方的示例代码与演示效果

小程序开发——小程序的视图与渲染_第3张图片 

现在仅仅想要一个简单的按钮,将上述wxml里部分代码拷贝,如下述代码所示:



 去掉多余的关于loading以及plain等属性的设置,得到精简一点的代码段,并拷贝到刚才新建页面的button.wxml文件中,如下所示:



2.数据绑定

在WXML页面中可以用双花括号里面添加变量名的形式表示动态数据,这称为Mustache语法,形如:{{变量名}}。 WXML 中的动态数据均来自对应JS文件中Page的data属性,分别可以作用于wxml页面的内容、组件属性、控制属性等。除此之外,在双花括号内还可以支持简单的运算以及字符串的拼接等操作。

内容绑定

在上述案例中学习了button组件的基本使用,现在将button里面的文字内容进行简单的内容绑定,如下述代码所示:



{{content}}

上述代码花括号内部的btnText与content就是绑定的变量,需在页面的JS文件中进变量的初始化,在页面加载时便可将数据渲染到WXML中,如下所示:

//JS文件代码
Page({
  data: {
    btnText:"按钮文字",
    content:"这是要显示的内容"
  }
})

 组件属性绑定

组件的属性也可以使用动态数据,例如组件的id、class等属性值。例如在WXML文件里可添加如下代码:

 测试组件属性绑定

与简单绑定一样,需在当前页面对应的JS文件的data属性里添加名为id的变量才能实现正确的组件属性绑定,值得注意的是,组件属性数据最外层的单引号(双引号)不可省略。

控制属性绑定

控制属性也可以使用动态数据,但必须在引号内。如下代码所示:


测试控制属性绑定

在文件里添加变量condition,暂时初始化为true,如下面代码所示。

//JS文件代码
Page({
  data: {
    condition:true
  }
})

 当更改变量condition的值为false时,view组件将不再显示,可以自行测试

true和false关键字绑定

在双括号内部除了引用data里的变量名之外,还可以直接写入一些关键字进行运算,如布尔类型的关键字true和false。如下面代码所示:

关键字绑定测试false
关键字绑定测试true

 不可以去掉双花括号直接写成wx:if='false',此时false会被认为是一个字符串,并且转换为布尔值后表示true。

运算绑定

三元运算:三元运算的语法表达式为:条件表达式?表达式1:表达式2。其中问号前面的位置是判断的条件,判断结果为bool型,为true时调用表达式1,为false时调用表达式2。在小程序的页面中三元运算经常这样使用:



//JS文件代码
Page({
    data: {
      result : false
    }
})

算数运算:双花括号内部也支持基本的四则运算,如下面代码所示:


 {{a + b}} + {{c}} + d 
//JS文件代码
Page({
    data: {
      a : 3, b : 4, c : 5
    }
})
//上述代码最后运算结果为“7+5+d”。

 逻辑判断:逻辑判断也就是支持大于和小于号,形成一个最后值为true或false的表达式。逻辑判断同样可以用于控制组件的显示,代码如下:

当length的值大于3时该组件显示 

字符串运算:字符串运算会用到字符串连接符“+”,这应与算数运算中的+号运算符进行区别,如下面代码所示:


{{"Hello, " + name}}
{{msg + name}}
//JS文件代码
Page({
  data: {
    name:"Toky",
    msg: "Hi, "
  }
})

在双花括号内部,若+号两边都是数值,则进行加运算。若+号两边的变量有任意一个是双引号引起来的字符串,则看作字符串连接符。

数据路径运算:数据路径运算即针对这些变量,对json对象,只需要用“.”运算符即可取到其下一层的属性。而数组变量的书写和其他语言的语法基本一致,采用一对中括号的形式,下标从0开始,如下述代码所示:


{{object.key2}} {{array[1]}}
//JS文件代码
Page({
  data: {
    object: { key1: 'Hello ', key2:'Hi' },
    array: ['Toky','Bob','Nike']
  }
})
//上述代码可在WXML页面显示“Hi Bob”。

 组合绑定

数组组合:在双花括号内还可以直接进行变量和值的组合,构成新的对象或者数组,如下面代码所示:


{{item}}
//JS文件代码
Page({
    data: { x : 3 }
})

 上述代码最终组合成数组[1,2,3,4]。wx:for与wx:if都是渲染标签,wx:for用于循环一个数组或列表,这个用于循环的数组元素值将默认赋值给item,因此上述代码可在页面依次显示该数组的元素值。值得注意的是,当花括号和引号之间如果有空格,将最终被解析成为字符串,如下述代码所示:

{{item}}
{{item}}

在WXML调试面板可看到最终渲染的WXML代码如图:

小程序开发——小程序的视图与渲染_第4张图片 

对象的组合与展开:对象的组合是指在双花括号内部通过key:变量名的形式可以将data里的数据组合到页面中。如下述代码所示:



//JS文件代码
Page({
    data: {
      value1 : 'Toky',
      value2 : '123456'
    }
})
//最终组合成的对象是{username:Toky,password:123456}

 对象的拆分可利用拓展运算符“…”三个点完成,示例代码如下:



//JS文件代码
Page({
  data: {
    obj1: { a: 1,  b: 2 },
    obj2: { c: 3,  d: 4 }
  }
})

最终组合成的对象是 {a: 1, b: 2, c: 3, d: 4, e: 5}。 在展开时,若obj2中的变量与obj1中的变量名相同的情况,后边的变量会覆 盖前面的。

数据绑定综合案例

关于数据绑定的综合案例主要用于测试内容绑定、组件属性绑定、控制属性绑定、关键字绑定与运算绑定,并给按钮绑定了简单的点击事件以实现内容的更新。

小程序开发——小程序的视图与渲染_第5张图片 页面WXML代码:案例综合数据绑定,测试多种属性的绑定,并给按钮组件添加了点击事件。在JS逻辑代码中重新渲染了页面的变量,其WXML代码如下:



  
    数据绑定综合案例
    
      1、内容绑定
      
      {{content}}
    
    
      2、组件属性绑定
      这是带有id的view1
    

      3、控制属性与关键字绑定
      当condition初始化为false时,view不显示
      view2
      关键字绑定测试false
      关键字绑定测试true
    
    
      4、运算绑定
      
      算术运算: {{a + b}} + {{c}} + d 
      逻辑判断:当length的值大于3时该组件显示 
      字符串运算: {{"Hello, " + name}}
      字符串运算: {{msg + name}}
      数据路径运算: {{object.key2}} {{array[1]}}  

 页面数据:页面数据在JS文件的data属性中进行初始化,全部变量如下所示:

data: {
    btnText: "按钮文字",
    content: "该按钮已经绑定btnClick事件",
    condition: false,
    a: 3, b: 4, c: 5,
    object: {
      key1: 'Hello ', key2: 'Hi'
    },
    array: ['Toky', 'Bob', 'Nike'],
    message1: "这是简单绑定的数据",
    id: 'testpage02View',
    msg: "Hi, ",
    name: "Toky",
    result: false
  },

页面点击事件处理函数:按钮点击后需要相应的处理函数执行逻辑代码,其完整代码如下:

// pages/demo2-2/dataBind.js
Page({
  data: { 
    content: "该按钮已经绑定btnClick事件",
    //省略其他变量
  },
  // 按钮点击事件处理函数
  btnClick: function() {
    console.log("按钮被点击")
    this.setData({
      content: "这是更新后的内容..."
    })
  },
})

 上述代码第8行的this指代page函数,page函数中固有的setData方法用于更新data域中的页面数据。由第9行可以看出,setData里同样是传入一个json对象作为参数,该对象里可以填上多个data中已定义或未定义的变量名,这里的未定义的意思是:当在data属性里未对变量定义和初始化时,该方法依旧可以动态地往data属性里面添加数据。另外,所有的页面数据的值都可以在调试器的AppData面板观察到。

3.渲染标签

条件渲染

指根据绑定表达式的逻辑值来判断是否渲染当前组件。view组件拥有控制是否显示的hidden属性, 代码如下所示:



//JS文件代码
Page({
    data: {  
     flag:false
     }
})

在上面的代码中,当flag变量的值为true时,view组件及其包含的子组件将不会渲染,当flag变量的值为false时,将view组件渲染输出到页面。

wx:if:在微信小程序的wxml文件中,提供了另一种方式来进行类似的条件渲染。就是使用wx:if来控制是否渲染当前组件,其实在上一节的数据绑定中已经使用过,具体代码如下:

 True 

 在上面的代码中,当condition变量的值为true时,view组件将渲染输出,当condition 变量的值为false,view组件将不渲染。 值得注意的是,不能在双括号与引号直接留空格。如下面代码段会导致True恒显示,代码如下:

 True 

 看起来wx:if属性与组件的hidden类似,不同的是,控制是否渲染的逻辑变量值刚好相反。wx:if可以更方便地控制,还可以使用wx:elif、wx:else来添加多个分支块,当控制表达式的值为true时渲染一个分支,控制表达式的值为false时渲染另一个分支。如下代码所示:


 case1 
case2 
case3
//JS文件代码
Page({
    data: {
      length:6
    }
})

以上代码中,当length的值大于10时,在界面中渲染输出的是case1字样,当length 的值大于5且小于10时,在界面中渲染输岀的是case2字样,而当length的值小于等于5或是其他情况时, 在界面中渲染输岀的是case3。

block wx:if  当需要通过一个表达式去控制多个组件时,一种方式是为每个组件都添加一个wx:if控制属性。但更好的方式是使用标签将一个包含多节点的结构块包装起来,然后在标签中添加一个wx:if控制属性即可。如下面代码所示:



 view1
 view2 

//JS文件代码
Page({
    data: {
      condition:true
    }
})

 列表渲染

常用的控制结构还有循环,微信小程序使用wx:for提供循环渲染的控制属性。

wx:for 简单列表渲染

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



{{index}}: {{item.message}}

//JS文件代码
Page({
    data: {
      array: [{ "message": "mes1" }, { "message": "mes2" }, 
            { "message": "mes3" }, { "message": "mes4" }]
        },
    }
})

从下图中可看出,默认数组的当前项的下标index从0开始,并依次循环输出数组的条目item,且item也可以是json对象,利用上一节提到的“.”运算符取到下一级的属性。

小程序开发——小程序的视图与渲染_第6张图片 

wx:for-item与wx:for-index:在使用wx:for时也可以将数组当前下标和当前元素变量进行重命名,使用 wx:for-item可以指定数组当前元素的变量名,使用wx:for-index可以指定数组当前下标的变量名。如下面代码所示:




{{myindex}}-{{user.name}}-{{user.age}}


//JS文件代码
Page({
    data: {
      users: [{ name: "Toky", age: 21 }, 
            { name: "Nike", age: 19 }, 
            { name: "Lisa", age: 20 }],}})

 

4.模板与引用

在微信小程序的WXML文件中,如果某些WXML代码需要在多个地方反复使用,这时,可以考虑将这些代码定义为一个模板,然后就可在其他WXML文件中利用关键字直接使用该模板。此外,引用与模板皆针对于WXML文件,在1.4.4节关于WXSS文件的介绍中曾使用import关键字导入公共样式文件。相似的道理,针对JS文件,则可在utils.js或其他JS文件夹中编写公共的业务逻辑,最后利用exports关键字进行导出,如下代码所示:

module.exports = {
  dateTimePicker: dateTimePicker,
  getMonthDay: getMonthDay
}

以上js代码用于一些公共类的导出,在其他js逻辑文件里可利用require关键字引入,如下述代码所示:

var dateTimePicker = require('../../../utils/dateTimePicker');

   引用本页面模板

模板可定义在当前页面,也可将项目使用到的所有模板定义到一个统一的WXML文件中,在本页面使用模板的步骤如下:

在Chapter02项目中新建testTemplate页面,定义模板的代码如下:


      

 在未使用该模板时,上面定义模板的WXML代码不会显示任何元素,使用该模板的代码如下所示: