小程序开发小程序的视与渲染视区别,微信小程序开发过程中页面渲染的方式有哪些
终极管理员 知识笔记 46阅读
1.视图与渲染过程
基本概念

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

WXML是框架设计的一套标签语言结合基础组件和事件系统可构建出页面的结构。组件是视图的基本组成单元组件的显示效果是由页面样式文件中定义的样式进行控制的。
<view classcontainer> <view classuserinfo> <button {{!hasUserInfo &&canIUse}} open-typegetUserInfo bindgetuserinfogetUserInfo>获取头像昵称</button> <block wx:else> <image bindtapbindViewTap src{{userInfo.avatarUrl}} ></image> <text classuserinfo-nickname> {{userInfo.nickName}} </text> </block> </view> <view classusermotto> <text classuser-motto>{{motto}} </text> </view></view>
button组件简单使用案例
实现效果如下图所示
新建Chapter02项目与页面
使用官方文档拷贝示例代码
进入微信官方小程序开发文档其链接为
选择“组件”→“表单组件”→button一栏
由上图可以看到关于button组件所有可设置的属性以及属性的可选值还有一些使用的注意事项等。将页面拖动到底部可以看到微信官方的示例代码与演示效果
现在仅仅想要一个简单的按钮将上述wxml里部分代码拷贝如下述代码所示
<button typedefault size{{defaultSize}} loading{{loading}} plain{{plain}} disabled{{disabled}} bindtapdefault hover-classother-button-hover> default </button><button typeprimary size{{primarySize}} loading{{loading}} plain{{plain}} disabled{{disabled}} bindtapprimary> primary </button>
去掉多余的关于loading以及plain等属性的设置得到精简一点的代码段并拷贝到刚才新建页面的button.wxml文件中如下所示
<button typedefault>default</button><button typeprimary>primary</button>
2.数据绑定 在WXML页面中可以用双花括号里面添加变量名的形式表示动态数据这称为Mustache语法形如{{变量名}}。 WXML 中的动态数据均来自对应JS文件中Page的data属性分别可以作用于wxml页面的内容、组件属性、控制属性等。除此之外在双花括号内还可以支持简单的运算以及字符串的拼接等操作。
内容绑定
在上述案例中学习了button组件的基本使用现在将button里面的文字内容进行简单的内容绑定如下述代码所示
<!-- WXML页面代码 --><button typeprimary>{{btnText}}</button><text>{{content}}</text>
上述代码花括号内部的btnText与content就是绑定的变量需在页面的JS文件中进变量的初始化在页面加载时便可将数据渲染到WXML中如下所示
//JS文件代码Page({ data: { btnText:按钮文字, content:这是要显示的内容 }})
组件属性绑定
组件的属性也可以使用动态数据例如组件的id、class等属性值。例如在WXML文件里可添加如下代码
<view id{{id}}> 测试组件属性绑定</view>
与简单绑定一样需在当前页面对应的JS文件的data属性里添加名为id的变量才能实现正确的组件属性绑定值得注意的是组件属性数据最外层的单引号双引号不可省略。
控制属性绑定
控制属性也可以使用动态数据但必须在引号内。如下代码所示
<!--WXML页面代码--><view wx:if{{condition}}>测试控制属性绑定</view>
在文件里添加变量condition暂时初始化为true如下面代码所示。
//JS文件代码Page({ data: { condition:true }})
当更改变量condition的值为false时view组件将不再显示可以自行测试
true和false关键字绑定
在双括号内部除了引用data里的变量名之外还可以直接写入一些关键字进行运算如布尔类型的关键字true和false。如下面代码所示
<view wx:if{{false}}>关键字绑定测试false</view><view wx:if{{true}}>关键字绑定测试true</view>
不可以去掉双花括号直接写成wx:iffalse此时false会被认为是一个字符串并且转换为布尔值后表示true。
运算绑定
三元运算三元运算的语法表达式为条件表达式?表达式1:表达式2。其中问号前面的位置是判断的条件判断结果为bool型为true时调用表达式1为false时调用表达式2。在小程序的页面中三元运算经常这样使用
<!--WXML页面代码--><view hidden{{result ? true : false}}>该组件将被隐藏</view>//JS文件代码Page({ data: { result : false }})
算数运算双花括号内部也支持基本的四则运算如下面代码所示
<!--WXML页面代码--><view> {{a b}} {{c}} d </view>//JS文件代码Page({ data: { a : 3, b : 4, c : 5 }})//上述代码最后运算结果为“75d”。
逻辑判断逻辑判断也就是支持大于和小于号形成一个最后值为true或false的表达式。逻辑判断同样可以用于控制组件的显示代码如下
<view wx:if{{length >3}}>当length的值大于3时该组件显示 </view>
字符串运算字符串运算会用到字符串连接符“”这应与算数运算中的号运算符进行区别如下面代码所示
<!--WXML页面代码--><view>{{Hello, name}}</view><view>{{msg name}}</view>//JS文件代码Page({ data: { name:Toky, msg: Hi, }})
在双花括号内部若号两边都是数值则进行加运算。若号两边的变量有任意一个是双引号引起来的字符串则看作字符串连接符。
数据路径运算数据路径运算即针对这些变量对json对象只需要用“.”运算符即可取到其下一层的属性。而数组变量的书写和其他语言的语法基本一致采用一对中括号的形式下标从0开始,如下述代码所示
<!--WXML页面代码--><view>{{object.key2}} {{array[1]}}</view>//JS文件代码Page({ data: { object: { key1: Hello , key2:Hi }, array: [Toky,Bob,Nike] }})//上述代码可在WXML页面显示“Hi Bob”。
组合绑定
数组组合在双花括号内还可以直接进行变量和值的组合构成新的对象或者数组如下面代码所示
<!--WXML页面代码--><view wx:for{{[1,2,x,4]}}>{{item}}</view>//JS文件代码Page({ data: { x : 3 }})
上述代码最终组合成数组[1,2,3,4]。wx:for与wx:if都是渲染标签wx:for用于循环一个数组或列表这个用于循环的数组元素值将默认赋值给item因此上述代码可在页面依次显示该数组的元素值。值得注意的是当花括号和引号之间如果有空格将最终被解析成为字符串如下述代码所示
<view wx:for{{[1,2,3]}} >{{item}}</view><view wx:for{{[1,2,3] }}>{{item}}</view>
在WXML调试面板可看到最终渲染的WXML代码如图
对象的组合与展开对象的组合是指在双花括号内部通过key:变量名的形式可以将data里的数据组合到页面中。如下述代码所示
<!--WXML页面代码--><template istest data{{username: value1, password: value2}}></template>//JS文件代码Page({ data: { value1 : Toky, value2 : 123456 }})//最终组合成的对象是{username:Toky,password:123456}
对象的拆分可利用拓展运算符“…”三个点完成示例代码如下
<!--WXML页面代码--><template isobjectCombine data{{...obj1, ...obj2, e: 5}}></template>//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中的变量名相同的情况后边的变量会覆 盖前面的。
数据绑定综合案例
关于数据绑定的综合案例主要用于测试内容绑定、组件属性绑定、控制属性绑定、关键字绑定与运算绑定并给按钮绑定了简单的点击事件以实现内容的更新。
页面WXML代码:案例综合数据绑定测试多种属性的绑定并给按钮组件添加了点击事件。在JS逻辑代码中重新渲染了页面的变量其WXML代码如下
<!--pages/demo2-2/dataBind.wxml--><view classcontainer> <view classpage-body> <text classh1>数据绑定综合案例</text> <view classdemo-box> <view classtitle>1、内容绑定</view> <button typeprimary bindtapbtnClick>{{btnText}}</button> <text>{{content}}</text> </view> <view classdemo-box> <view classtitle>2、组件属性绑定</view> <view id{{id}}>这是带有id的view1</view> </view><view classdemo-box> <view classtitle>3、控制属性与关键字绑定</view> <text classcontent>当condition初始化为false时view不显示</text> <view wx:if{{condition}}>view2</view> <view wx:if{{false}}>关键字绑定测试false</view> <view wx:if{{true}}>关键字绑定测试true</view> </view> <view classdemo-box> <view classtitle>4、运算绑定</view> <view hidden{{result ? true : false}}>三元运算:result为真时显示</view> <view>算术运算 {{a b}} {{c}} d </view> <view wx:if{{length >3}}>逻辑判断:当length的值大于3时该组件显示 </view> <view>字符串运算: {{Hello, name}}</view> <view>字符串运算: {{msg name}}</view> <view>数据路径运算: {{object.key2}} {{array[1]}}</view> </view> </view></view>
页面数据:页面数据在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.jsPage({ 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属性 代码如下所示
<!--WXML页面代码--><view classcontent hidden{{flag ? true : false}}></view>//JS文件代码Page({ data: { flag:false }})
在上面的代码中当flag变量的值为true时view组件及其包含的子组件将不会渲染当flag变量的值为false时将view组件渲染输出到页面。
wx:if在微信小程序的wxml文件中提供了另一种方式来进行类似的条件渲染。就是使用wx:if来控制是否渲染当前组件其实在上一节的数据绑定中已经使用过具体代码如下
<view wx: if ({condition}) > True </view>
在上面的代码中当condition变量的值为true时view组件将渲染输出当condition 变量的值为falseview组件将不渲染。 值得注意的是不能在双括号与引号直接留空格。如下面代码段会导致True恒显示代码如下
<view wx:if{{condition}} > True </view>
看起来wx:if属性与组件的hidden类似不同的是控制是否渲染的逻辑变量值刚好相反。wx:if可以更方便地控制还可以使用wx:elif、wx:else来添加多个分支块当控制表达式的值为true时渲染一个分支控制表达式的值为false时渲染另一个分支。如下代码所示
<!--WXML页面代码--><view wx:if{{length >10}}> case1 </view><view wx:elif{{length > 5}}>case2 </view><view wx:else>case3</view>//JS文件代码Page({ data: { length:6 }})
以上代码中当length的值大于10时在界面中渲染输出的是case1字样,当length 的值大于5且小于10时在界面中渲染输岀的是case2字样,而当length的值小于等于5或是其他情况时, 在界面中渲染输岀的是case3。
block wx:if 当需要通过一个表达式去控制多个组件时一种方式是为每个组件都添加一个wx:if控制属性。但更好的方式是使用<block>标签将一个包含多节点的结构块包装起来然后在<block>标签中添加一个wx:if控制属性即可。如下面代码所示
<!--WXML页面代码--><block wx:if{{condition}}><view> view1</view><view> view2 </view></block>//JS文件代码Page({ data: { condition:true }})
列表渲染
常用的控制结构还有循环微信小程序使用wxfor提供循环渲染的控制属性。
wx:for 简单列表渲染
循环对象数组在组件上使用 wx:for 控制属性绑定一个数组即可使用数组中各项的数据重复渲染该组件。默认数组的当前项的下标变量名为 index数组当前项的变量名默认为 item。如下列代码所示:
<!--WXML页面代码--><view wx:for{{array}}>{{index}}: {{item.message}}</view>//JS文件代码Page({ data: { array: [{ message: mes1 }, { message: mes2 }, { message: mes3 }, { message: mes4 }] }, }})
从下图中可看出默认数组的当前项的下标index从0开始并依次循环输出数组的条目item且item也可以是json对象利用上一节提到的“.”运算符取到下一级的属性。
wx:for-item与wx:for-index在使用wx:for时也可以将数组当前下标和当前元素变量进行重命名使用 wx:for-item可以指定数组当前元素的变量名使用wx:for-index可以指定数组当前下标的变量名。如下面代码所示
<!--WXML页面代码--><view><view wx:for{{users}} wx:for-indexmyindex wx:for-itemuser><text>{{myindex}}-{{user.name}}-{{user.age}}</text></view></view>//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页面定义模板的代码如下
<!--pages/demo2-4/testTemplate.wxml--> <template nameuserTemplate> <!----定义模板--> <view> <view>姓名{{item.name}}</view> <view>年龄{{item.age}}</view> </view> </template><!-- 定义结束 -->
在未使用该模板时上面定义模板的WXML代码不会显示任何元素使用该模板的代码如下所示
<!--pages/demo2-4/testTemplate.wxml--><view><block wx:for{{users}}><template isuserTemplate data{{item}}/> <!-- 调用模板传入对象数据--></block></view>Page({ data: { users: [{ name: Toky, age: 21 }, { name: Nike, age: 19 }, { name: Lisa, age: 20 }], }})
引用其他位置的模板
在进行模板template的定义时也可以写在单独的一个WXML文件里这时在其他页面进行引用时不是用关键字include而是import二者的作用域不同。import只会引入目标文件中定义的 template而不会引入目标文件里面再引入的其他template即不能进行链式引用。
定义模板
在Chapter02项目目录下新建commons目录再新建templates.wxml如图
在templates.wxml中定义两个模板如下述代码所示
<!-- Chapter02/pages/commons/templates.wxml --><template nametemplate1> <text>{{text}}</text></template><template nametemplate2> <text>{{text}}</text></template>
引用
在其他文件中进行引用时首先需要利用import关键字将模板拷贝到当前页面再进行如上一小节中讲解的模板使用方法利用is关键字指明模板。代码如下所示
<!--pages/demo2-4/testTemplate.wxml--> <import src../commons/templates /> <template istemplate1 data{{text: 这是传入模板的需要显示的内容}} />
引用wxml代码段
模板针对于有数据需要传入的情况实际上若是只想引用静态的WXML片段直接使用include关键字即可引用wxml代码段步骤如下
在commons目录下新建文件footer.wxml并在footer.wxml中添加如下内容
<!-- Chapter02/pages/commons/footer.wxml --><view><text>这是许多页面底部需要显示的内容</text></view>
在其他需要该footer作为尾部的页面利用关键字include进行引用。include 可以将目标文件除了<template/>外的整个代码引入相当于拷贝到 include 所在的位置。在2.4.1节创建的testTemplate.wxml的底部加上如下代码段
<!--pages/demo2-4/testTemplate.wxml--><include src../commons/footer />
上述代码第二行的include标签是一个单独的闭合标签与在使用模板时用的template闭合标签是一样的注意不能将末尾的反斜杠丢掉。
5.九九乘法表案例讲解代码详情
九九乘法表WXML代码如下
<!-- MultiplicationTable/pages/index/index.wxml --><view classjiu-box> <view wx:for{{arr}} wx:for-itemi classaa> <view wx:for{{arr}} wx:for-itemj classjiu> <view wx:if{{i > j}} classjiu-item> {{j}}X{{i}}{{j*i}} </view> <view wx:else hidden{{true}}></view> </view> </view></view>
九九乘法表WXSS样式代码如下
/* MultiplicationTable/pages/index/index.wxss */.aa { line-height: 32px;}.jiu-box { width: 720rpx; margin: auto; padding: 28rpx 0;}.jiu { display: inline-block;}.jiu-item { width: 73rpx; height: 32rpx;line-height: 32rpx; text-align: center; border: 1px solid #abcdef; font-size: 19rpx; margin-right: 4rpx;}.jiu-none { display: none;}one { display: inline-block; margin-right: 4rpx; width: 70rpx; height: 32rpx; font-size: 14rpx; text-align: center; border: 1rpx solid #1296db;}
实现效果
6.小结