文章目录
🌟前言
**哈喽小伙伴们,上一期为大家讲解了一下小程序的架构之【逻辑层】篇。今天接着上篇,给大家结合官方文档讲解一下小程序的架构之【视图层】;今天的文章有点长,很多知识点也是官方文档给我们提供的;也是想告诉大家,
总有一天我们进入职场后,会甩开我们的拐棍或者离开我们的靠山独自去面对困难
; 所以养成阅读官方文档的好习惯对我们日后工作也有很大的好处。好了,让我们一起来看看吧🤘**
🌟小程序架构
小程序开发框架的目标是通过尽可能简单、高效的方式让开发者可以在微信中开发具有原生 APP 体验的服务。
**整个小程序框架系统分为两部分:
逻辑层(App Service)
和
视图层(View)
。小程序提供了自己的视图层描述语言
WXML
和
WXSS
,以及基于
JavaScript
的逻辑层框架,并在视图层与逻辑层间提供了数据传输和事件系统,让开发者能够专注于数据与逻辑。**
**
View
层用来渲染页面结构,
AppService
层用来逻辑处理、数据请求、接口调用。**
它们在两个线程里运行。
**视图层和逻辑层通过系统层的
JSBridage
进行通信,逻辑层把数据变化通知到视图层,触发视图层页面更新,视图层把触发的事件通知到逻辑层进行业务处理**
- 视图层使用
WebView
渲染,iOS
中使用自带WKWebView
,在Android
使用腾讯的 x5内核
(基于 Blink)运行。 - 逻辑层使用在
iOS
中使用自带的JSCore
运行,在Android
中使用腾讯的 x5 内核
(基于 Blink)运行。 开发工具
使用nw.js
同时提供了视图层和逻辑层的运行环境。
🌟视图层 View
框架的视图层由 WXML 与 WXSS 编写,由组件来进行展示。
将逻辑层的数据反映成视图,同时将视图层的事件发送给逻辑层。
- WXML(WeiXin Markup language) 用于描述页面的结构。
- WXS(WeiXin Script) 是小程序的一套脚本语言,结合 WXML,可以构建出页面的结构。
- WXSS(WeiXin Style Sheet) 用于描述页面的样式。
- 组件(Component)是视图的基本组成单元。
🌟WXML
WXML(WeiXin Markup Language)是框架设计的一套标签语言,结合基础组件、事件系统,可以构建出页面的结构。
要完整了解 WXML 语法,请参考WXML 语法参考。
用以下一些简单的例子来看看 WXML 具有什么能力:
🌟数据绑定
<!--wxml--><view>{{message}}</view>// page.jsPage({data:{message:'Hello MINA!'}})
🌟列表渲染
<!--wxml--><viewwx:for="{{array}}"> {{item}} </view>
// page.js
Page({
data: {
array: [1, 2, 3, 4, 5]
}
})
🌟条件渲染
<!--wxml--><viewwx:if="{{view == 'WEBVIEW'}}"> WEBVIEW </view><viewwx:elif="{{view == 'APP'}}"> APP </view><viewwx:else="{{view == 'MINA'}}"> MINA </view>
// page.js
Page({
data: {
view: 'MINA'
}
})
🌟模板
<!--wxml--><templatename="staffName"><view>
FirstName: {{firstName}}, LastName: {{lastName}}
</view></template><templateis="staffName"data="{{...staffA}}"></template><templateis="staffName"data="{{...staffB}}"></template><templateis="staffName"data="{{...staffC}}"></template>
// page.js
Page({
data: {
staffA: {firstName: 'Hulk', lastName: 'Hu'},
staffB: {firstName: 'Shang', lastName: 'You'},
staffC: {firstName: 'Gideon', lastName: 'Lin'}
}
})
🌟WXSS
WXSS (WeiXin Style Sheets)是一套样式语言,用于描述 WXML 的组件样式。
WXSS 用来决定 WXML 的组件应该怎么显示。 为了适应广大的前端开发者,WXSS 具有 CSS 大部分特性。同时为了更适合开发微信小程序,WXSS 对 CSS 进行了扩充以及修改。
与 CSS 相比,WXSS 扩展的特性有:
- 尺寸单位
- 样式导入
🌟尺寸单位
rpx(responsive pixel): 可以根据屏幕宽度进行自适应。规定屏幕宽为750rpx。
如在 iPhone6 上,屏幕宽度为375px,共有750个物理像素,则750rpx = 375px = 750物理像素,1rpx = 0.5px =1物理像素;
设备rpx换算px (屏幕宽度/750)px换算rpx (750/屏幕宽度)iPhone51rpx = 0.42px1px = 2.34rpxiPhone61rpx = 0.5px1px = 2rpxiPhone6 Plus1rpx = 0.552px1px = 1.81rpx
建议: 开发微信小程序时设计师可以用 iPhone6 作为视觉稿的标准。
注意: 在较小的屏幕上不可避免的会有一些毛刺,请在开发时尽量避免这种情况。
🌟样式导入
使用@import语句可以导入外联样式表,@import后跟需要导入的外联样式表的相对路径,用;表示语句结束。
示例代码:
/** common.wxss **/.small-p{padding:5px;}/** app.wxss **/@import"common.wxss";.middle-p{padding:15px;}
🌟内联样式
框架组件上支持使用 style、class 属性来控制组件的样式。
- style:静态的样式统一写到 class 中。style 接收动态的样式,在运行时会进行解析,请尽量避免将静态的样式写进 style 中,以免影响渲染速度。
- class:用于指定样式规则,其属性值是样式规则中类选择器名(样式类名)的集合,样式类名不需要带上.,样式类名之间用空格分隔。
<view class="normal_view" />
🌟选择器
目前支持的选择器有:
选择器样例样例描述.class.intro选择所有拥有 class=“intro” 的组件#id#firstname选择拥有 id=“firstname” 的组件element选择所有 view 组件element, elementview, checkbox选择所有文档的 view 组件和所有的 checkbox 组件::afterview::after在 view 组件后边插入内容::beforeview::before在 view 组件前边插入内容
🌟全局样式与局部样式
定义在 app.wxss 中的样式为全局样式,作用于每一个页面。在 page 的 wxss 文件中定义的样式为局部样式,只作用在对应的页面,并会覆盖 app.wxss 中相同的选择器。
🌟WXS
WXS(WeiXin Script)是小程序的一套脚本语言,结合 WXML,可以构建出页面的结构。
注意事项
- WXS 不依赖于运行时的基础库版本,可以在所有版本的小程序中运行。
- WXS 与 JavaScript 是不同的语言,有自己的语法,并不和 JavaScript 一致。
- WXS 的运行环境和其他 JavaScript 代码是隔离的,WXS 中不能调用其他 JavaScript 文件中定义的函数,也不能调用小程序提供的API。
- 由于运行环境的差异,在 iOS 设备上小程序内的 WXS 会比 JavaScript 代码快 2 ~ 20 倍。在 android 设备上二者运行效率无差异。
以下是一些使用 WXS 的简单示例,要完整了解 WXS 语法,请参考WXS 语法参考。
🌟页面渲染
<!--wxml--><wxsmodule="m1">
var msg = "hello world";
module.exports.message = msg;
</wxs><view> {{m1.message}} </view>
页面输出:
hello world
数据处理:
// page.jsPage({data:{array:[1,2,3,4,5,1,2,3,4]}})
<!--wxml--><!-- 下面的 getMax 函数,接受一个数组,且返回数组中最大的元素的值 --><wxsmodule="m1">
var getMax = function(array) {
var max = undefined;
for (var i = 0; i < array.length; ++i) {
max = max === undefined ?
array[i] :
(max >= array[i] ? max : array[i]);
}
return max;
}
module.exports.getMax = getMax;
</wxs><!-- 调用 wxs 里面的 getMax 函数,参数为 page.js 里面的 array --><view> {{m1.getMax(array)}} </view>
页面输出:
5
🌟事件
🌟什么是事件
- 事件是视图层到逻辑层的通讯方式。
- 事件可以将用户的行为反馈到逻辑层进行处理。
- 事件可以绑定在组件上,当达到触发事件,就会执行逻辑层中对应的事件处理函数。
- 事件对象可以携带额外信息,如 id, dataset, touches。
🌟事件的使用方式
- 在组件中绑定一个事件处理函数。 如bindtap,当用户点击该组件的时候会在该页面对应的Page中找到相应的事件处理函数。
<viewid="tapTest"data-hi="Weixin"bindtap="tapName"> Click me! </view>
- 在相应的Page定义中写上相应的事件处理函数,参数是event。
Page({tapName:function(event){
console.log(event)}})
- 可以看到log出来的信息大致如下:
{"type":"tap","timeStamp":895,"target":{"id":"tapTest","dataset":{"hi":"Weixin"}},"currentTarget":{"id":"tapTest","dataset":{"hi":"Weixin"}},"detail":{"x":53,"y":14},"touches":[{"identifier":0,"pageX":53,"pageY":14,"clientX":53,"clientY":14}],"changedTouches":[{"identifier":0,"pageX":53,"pageY":14,"clientX":53,"clientY":14}]}
🌟使用WXS函数响应事件
从基础库版本2.4.4开始,支持使用WXS函数绑定事件,WXS函数接受2个参数,第一个是event,在原有的event的基础上加了event.instance对象,第二个参数是ownerInstance,和event.instance一样是一个ComponentDescriptor对象。具体使用如下:
- 在组件中绑定和注册事件处理的WXS函数。
<wxsmodule="wxs"src="./test.wxs"></wxs><viewid="tapTest"data-hi="Weixin"bindtap="{{wxs.tapName}}"> Click me! </view>
注:绑定的WXS函数必须用{{}}括起来
- test.wxs文件实现tapName函数
functiontapName(event, ownerInstance){
console.log('tap Weixin',JSON.stringify(event))}
module.exports ={tapName: tapName
}
ownerInstance包含了一些方法,可以设置组件的样式和class,具体包含的方法以及为什么要用WXS函数响应事件,请点击查看详情。
🌟事件详解
🌟事件分类
事件分为冒泡事件和非冒泡事件:
- 冒泡事件:当一个组件上的事件被触发后,该事件会向父节点传递。
- 非冒泡事件:当一个组件上的事件被触发后,该事件不会向父节点传递。
WXML的冒泡事件列表:
类型触发条件最低版本touchstart手指触摸动作开始touchmove手指触摸后移动touchcancel手指触摸动作被打断,如来电提醒,弹窗touchend手指触摸动作结束tap手指触摸后马上离开longpress手指触摸后,超过350ms再离开,如果指定了事件回调函数并触发了这个事件,tap事件将不被触发1.5.0longtap手指触摸后,超过350ms再离开(推荐使用longpress事件代替)transitionend会在 WXSS transition 或 wx.createAnimation 动画结束后触发animationstart会在一个 WXSS animation 动画开始时触发animationiteration会在一个 WXSS animation 一次迭代结束时触发animationend会在一个 WXSS animation 动画完成时触发touchforcechange在支持 3D Touch 的 iPhone 设备,重按时会触发1.9.90
注:除上表之外的其他组件自定义事件如无特殊声明都是非冒泡事件,如 form 的submit事件,input 的input事件,scroll-view 的scroll事件,(详见各个组件)
🌟普通事件绑定
事件绑定的写法类似于组件的属性,如:
<viewbindtap="handleTap">
Click here!
</view>
如果用户点击这个 view ,则页面的 handleTap 会被调用。
事件绑定函数可以是一个数据绑定,如:
<viewbindtap="{{ handlerName }}">
Click here!
</view>
此时,页面的 this.data.handlerName 必须是一个字符串,指定事件处理函数名;如果它是个空字符串,则这个绑定会失效(可以利用这个特性来暂时禁用一些事件)。
自基础库版本 1.5.0 起,在大多数组件和自定义组件中, bind 后可以紧跟一个冒号,其含义不变,如 bind:tap 。基础库版本 2.8.1 起,在所有组件中开始提供这个支持。
🌟绑定并阻止事件冒泡
除 bind 外,也可以用 catch 来绑定事件。与 bind 不同, catch 会阻止事件向上冒泡。
例如在下边这个例子中,点击 inner view 会先后调用handleTap3和handleTap2(因为tap事件会冒泡到 middle view,而 middle view 阻止了 tap 事件冒泡,不再向父节点传递),点击 middle view 会触发handleTap2,点击 outer view 会触发handleTap1。
<viewid="outer"bindtap="handleTap1">
outer view
<viewid="middle"catchtap="handleTap2">
middle view
<viewid="inner"bindtap="handleTap3">
inner view
</view></view></view>
🌟互斥事件绑定
自基础库版本 2.8.2 起,除 bind 和 catch 外,还可以使用 mut-bind 来绑定事件。一个 mut-bind 触发后,如果事件冒泡到其他节点上,其他节点上的 mut-bind 绑定函数不会被触发,但 bind 绑定函数和 catch 绑定函数依旧会被触发。
换而言之,所有 mut-bind 是“互斥”的,只会有其中一个绑定函数被触发。同时,它完全不影响 bind 和 catch 的绑定效果。
例如在下边这个例子中,点击 inner view 会先后调用 handleTap3 和 handleTap2 ,点击 middle view 会调用 handleTap2 和 handleTap1 。
<viewid="outer"mut-bind:tap="handleTap1">
outer view
<viewid="middle"bindtap="handleTap2">
middle view
<viewid="inner"mut-bind:tap="handleTap3">
inner view
</view></view></view>
🌟事件的捕获阶段
自基础库版本 1.5.0 起,触摸类事件支持捕获阶段。捕获阶段位于冒泡阶段之前,且在捕获阶段中,事件到达节点的顺序与冒泡阶段恰好相反。需要在捕获阶段监听事件时,可以采用capture-bind、capture-catch关键字,后者将中断捕获阶段和取消冒泡阶段。
在下面的代码中,点击 inner view 会先后调用handleTap2、handleTap4、handleTap3、handleTap1。
<viewid="outer"bind:touchstart="handleTap1"capture-bind:touchstart="handleTap2">
outer view
<viewid="inner"bind:touchstart="handleTap3"capture-bind:touchstart="handleTap4">
inner view
</view></view>
如果将上面代码中的第一个capture-bind改为capture-catch,将只触发handleTap2。
<viewid="outer"bind:touchstart="handleTap1"capture-catch:touchstart="handleTap2">
outer view
<viewid="inner"bind:touchstart="handleTap3"capture-bind:touchstart="handleTap4">
inner view
</view></view>
🌟事件对象
如无特殊说明,当组件触发事件时,逻辑层绑定该事件的处理函数会收到一个事件对象。
🌟BaseEvent 基础事件对象属性列表:
属性类型说明基础库版本typeString事件类型timeStampInteger事件生成时的时间戳targetObject触发事件的组件的一些属性值集合currentTargetObject当前组件的一些属性值集合markObject事件标记数据2.7.1
🌟CustomEvent 自定义事件对象属性列表(继承 BaseEvent):
属性类型说明detailObject额外的信息
🌟TouchEvent触摸事件对象属性列表(继承 BaseEvent):
属性类型说明touchesArray触摸事件,当前停留在屏幕中的触摸点信息的数组changedTouchesArray触摸事件,当前变化的触摸点信息的数组特殊事件: canvas 中的触摸事件不可冒泡,所以没有 currentTarget。
🌟type
代表事件的类型。
timeStamp
页面打开到触发事件所经过的毫秒数。
🌟target
触发事件的源组件。
属性类型说明idString事件源组件的iddatasetObject事件源组件上由data-开头的自定义属性组成的集合
🌟currentTarget
事件绑定的当前组件。
属性类型说明idString当前组件的iddatasetObject当前组件上由data-开头的自定义属性组成的集合
说明: target 和 currentTarget 可以参考上例中,点击 inner view 时,handleTap3 收到的事件对象 target 和 currentTarget 都是 inner,而 handleTap2 收到的事件对象 target 就是 inner,currentTarget 就是 middle。
🌟dataset
在组件节点中可以附加一些自定义数据。这样,在事件中可以获取这些自定义的节点数据,用于事件的逻辑处理。
在 WXML 中,这些自定义数据以 data- 开头,多个单词由连字符 - 连接。这种写法中,连字符写法会转换成驼峰写法,而大写字符会自动转成小写字符。如:
- data-element-type ,最终会呈现为 event.currentTarget.dataset.elementType ;
- data-elementType ,最终会呈现为 event.currentTarget.dataset.elementtype 。
示例:
<viewdata-alpha-beta="1"data-alphaBeta="2"bindtap="bindViewTap"> DataSet Test </view>
Page({
bindViewTap:function(event){
event.currentTarget.dataset.alphaBeta === 1 // - 会转为驼峰写法
event.currentTarget.dataset.alphabeta === 2 // 大写会转为小写
}
})
🌟mark
在基础库版本 2.7.1 以上,可以使用 mark 来识别具体触发事件的 target 节点。此外, mark 还可以用于承载一些自定义数据(类似于 dataset )。
当事件触发时,事件冒泡路径上所有的 mark 会被合并,并返回给事件回调函数。(即使事件不是冒泡事件,也会 mark 。)
代码示例:
<viewmark:myMark="last"bindtap="bindViewTap"><buttonmark:anotherMark="leaf"bindtap="bindButtonTap">按钮</button></view>
在上述 WXML 中,如果按钮被点击,将触发 bindViewTap 和 bindButtonTap 两个事件,事件携带的 event.mark 将包含 myMark 和 anotherMark 两项。
Page({bindViewTap:function(e){
e.mark.myMark ==="last"// true
e.mark.anotherMark ==="leaf"// true}})
mark 和 dataset 很相似,主要区别在于: mark 会包含从触发事件的节点到根节点上所有的 mark: 属性值;而 dataset 仅包含一个节点的 data- 属性值。
细节注意事项:
- 如果存在同名的 mark ,父节点的 mark 会被子节点覆盖。
- 在自定义组件中接收事件时, mark 不包含自定义组件外的节点的 mark 。
- 不同于 dataset ,节点的 mark 不会做连字符和大小写转换。
🌟touches
touches 是一个数组,每个元素为一个 Touch 对象(canvas 触摸事件中携带的 touches 是 CanvasTouch 数组)。 表示当前停留在屏幕上的触摸点。
🌟Touch 对象
属性类型说明identifierNumber触摸点的标识符pageX, pageYNumber距离文档左上角的距离,文档的左上角为原点 ,横向为X轴,纵向为Y轴clientX, clientYNumber距离页面可显示区域(屏幕除去导航条)左上角距离,横向为X轴,纵向为Y轴
🌟CanvasTouch 对象
属性类型说明identifierNumber触摸点的标识符x, yNumber距离 Canvas 左上角的距离,Canvas 的左上角为原点 ,横向为X轴,纵向为Y轴
🌟CanvasTouch changedTouches
changedTouches 数据格式同 touches。 表示有变化的触摸点,如从无变有(touchstart),位置变化(touchmove),从有变无(touchend、touchcancel)。
🌟detail
自定义事件所携带的数据,如表单组件的提交事件会携带用户的输入,媒体的错误事件会携带错误信息,详见组件定义中各个事件的定义。
点击事件的detail 带有的 x, y 同 pageX, pageY 代表距离文档左上角的距离。
🌟WXS响应事件
🌟背景
有频繁用户交互的效果在小程序上表现是比较卡顿的,例如页面有 2 个元素 A 和 B,用户在 A 上做 touchmove 手势,要求 B 也跟随移动,movable-view 就是一个典型的例子。一次 touchmove 事件的响应过程为:
- a、touchmove 事件从视图层(Webview)抛到逻辑层(App Service)
- b、逻辑层(App Service)处理 touchmove 事件,再通过 setData 来改变 B 的位置
一次 touchmove 的响应需要经过 2 次的逻辑层和渲染层的通信以及一次渲染,通信的耗时比较大。此外 setData 渲染也会阻塞其它脚本执行,导致了整个用户交互的动画过程会有延迟。
🌟实现方案
本方案基本的思路是减少通信的次数,让事件在视图层(Webview)响应。小程序的框架分为视图层(Webview)和逻辑层(App Service),这样分层的目的是管控,开发者的代码只能运行在逻辑层(App
Service),而这个思路就必须要让开发者的代码运行在视图层(Webview),如下图所示的流程:
使用 WXS 函数用来响应小程序事件,目前只能响应内置组件的事件,不支持自定义组件事件。WXS 函数的除了纯逻辑的运算,还可以通过封装好的ComponentDescriptor 实例来访问以及设置组件的 class 和样式,对于交互动画,设置 style 和 class 足够了。WXS 函数的例子如下:
varwxsFunction=function(event, ownerInstance){var instance = ownerInstance.selectComponent('.classSelector')// 返回组件的实例
instance.setStyle({"font-size":"14px"// 支持rpx})
instance.getDataset()
instance.setClass(className)// ...returnfalse// 不往上冒泡,相当于调用了同时调用了stopPropagation和preventDefault}
其中入参 event 是小程序事件对象基础上多了 event.instance 来表示触发事件的组件的 ComponentDescriptor 实例。ownerInstance 表示的是触发事件的组件所在的组件的
ComponentDescriptor 实例,如果触发事件的组件是在页面内的,ownerInstance 表示的是页面实例。
ComponentDescriptor的定义如下:
方法参数描述最低版本selectComponentselector对象返回组件的 ComponentDescriptor 实例。selectAllComponentsselector对象数组返回组件的 ComponentDescriptor 实例数组。setStyleObject/string设置组件样式,支持rpx。设置的样式优先级比组件 wxml 里面定义的样式高。不能设置最顶层页面的样式。addClass/removeClass/hasClassstring设置组件的 class。设置的 class 优先级比组件 wxml 里面定义的 class 高。不能设置最顶层页面的 class。getDataset无返回当前组件/页面的 dataset 对象callMethod(funcName:string, args:object)调用当前组件/页面在逻辑层(App Service)定义的函数。funcName表示函数名称,args表示函数的参数。requestAnimationFrameFunction和原生 requestAnimationFrame 一样。用于设置动画。getState无返回一个object对象,当有局部变量需要存储起来后续使用的时候用这个方法。triggerEvent(eventName, detail)和组件的triggerEvent一致。getComputedStyleArray.
<string>
参数与 SelectorQuery 的 computedStyle 一致。2.11.2setTimeout(Function, Number)与原生 setTimeout 一致。用于创建定时器。2.14.2clearTimeoutNumber与原生 clearTimeout 一致。用于清除定时器。2.14.2getBoundingClientRect无返回值与 SelectorQuery 的 boundingClientRect 一致。2.14.2
WXS 运行在视图层(Webview),里面的逻辑毕竟能做的事件比较少,需要有一个机制和逻辑层(App Service)开发者的代码通信,上面的 callMethod 是 WXS 里面调用逻辑层(App Service)开发者的代码的方法,而 WxsPropObserver 是逻辑层(App Service)开发者的代码调用 WXS 逻辑的机制。
🌟使用方法
- WXML定义事件:
<wxsmodule="test"src="./test.wxs"></wxs><viewchange:prop="{{test.propObserver}}"prop="{{propValue}}"bindtouchmove="{{test.touchmove}}"class="movable"></view>
上面的change:prop(属性前面带change:前缀)是在 prop 属性被设置的时候触发 WXS 函数,值必须用{{}}括起来。类似 Component 定义的 properties 里面的 observer 属性,在setData({propValue: newValue})调用之后会触发。
注意:WXS函数必须用{{}}括起来。当 prop 的值被设置 WXS 函数就会触发,而不只是值发生改变,所以在页面初始化的时候会调用一次WxsPropObserver的函数。
WXS文件test.wxs里面定义并导出事件处理函数和属性改变触发的函数:
module.exports ={touchmove:function(event, instance){
console.log('log event',JSON.stringify(event))},propObserver:function(newValue, oldValue, ownerInstance, instance){
console.log('prop observer', newValue, oldValue)}}
- 目前还不支持原生组件的事件、input和textarea组件的 bindinput 事件
- 1.02.1901170及以后版本的开发者工具上支持交互动画,最低版本基础库是2.4.4
- 目前在WXS函数里面仅支持console.log方式打日志定位问题,注意连续的重复日志会被过滤掉。
🌟简易双向绑定
基础库 2.9.3 开始支持,低版本需做兼容处理。
🌟双向绑定语法
在 WXML 中,普通的属性的绑定是单向的。例如:
<inputvalue="{{value}}"/>
如果使用 this.setData({ value: ‘leaf’ }) 来更新 value ,this.data.value 和输入框的中显示的值都会被更新为 leaf ;但如果用户修改了输入框里的值,却不会同时改变 this.data.value 。
如果需要在用户输入的同时改变 this.data.value ,需要借助简易双向绑定机制。此时,可以在对应项目之前加入 model: 前缀:
<inputmodel:value="{{value}}"/>
这样,如果输入框的值被改变了, this.data.value 也会同时改变。同时, WXML 中所有绑定了 value 的位置也会被一同更新, 数据监听器 也会被正常触发。
用于双向绑定的表达式有如下限制:
- 只能是一个单一字段的绑定,如
<inputmodel:value="值为 {{value}}"/><inputmodel:value="{{ a + b }}"/>
都是非法的;
- 目前,尚不能 data 路径,如
<inputmodel:value="{{ a.b }}"/>
这样的表达式目前暂不支持。
🌟在自定义组件中传递双向绑定
双向绑定同样可以使用在自定义组件上。如下的自定义组件:
// custom-component.jsComponent({properties:{myValue: String
}})
<!-- custom-component.wxml --><inputmodel:value="{{myValue}}"/>
这个自定义组件将自身的 myValue 属性双向绑定到了组件内输入框的 value 属性上。这样,如果页面这样使用这个组件:
<custom-componentmodel:my-value="{{pageValue}}"/>
当输入框的值变更时,自定义组件的 myValue 属性会同时变更,这样,页面的 this.data.pageValue 也会同时变更,页面 WXML 中所有绑定了 pageValue 的位置也会被一同更新。
🌟在自定义组件中触发双向绑定更新
自定义组件还可以自己触发双向绑定更新,做法就是:使用 setData 设置自身的属性。例如:
// custom-component.jsComponent({properties:{myValue: String
},methods:{update:function(){// 更新 myValuethis.setData({myValue:'leaf'})}}})
如果页面这样使用这个组件:
<custom-componentmodel:my-value="{{pageValue}}"/>
当组件使用 setData 更新 myValue 时,页面的 this.data.pageValue 也会同时变更,页面 WXML 中所有绑定了 pageValue 的位置也会被一同更新。
🌟基础组件
框架为开发者提供了一系列基础组件,开发者可以通过组合这些基础组件进行快速开发。详细介绍请参考组件文档。
🌟什么是组件:
- 组件是视图层的基本组成单元。
- 组件自带一些功能与微信风格一致的样式。
- 一个组件通常包括 开始标签 和 结束标签,属性 用来修饰这个组件,内容 在两个标签之内。
<tagnameproperty="value">
Content goes here ...
</tagname>
注意:所有组件与属性都是小写,以连字符-连接
🌟属性类型
类型描述注解Boolean布尔值组件写上该属性,不管是什么值都被当作 true;只有组件上没有该属性时,属性值才为false。如果属性值为变量,变量的值会被转换为Boolean类型Number数字1, 2.5String字符串“string”Array数组[ 1, “string” ]Object对象{ key: value }EventHandler事件处理函数名
"handlerName"
是 Page 中定义的事件处理函数名Any任意属性
🌟公共属性
所有组件都有以下属性:
属性名类型描述注解idString组件的唯一标示保持整个页面唯一classString组件的样式类在对应的 WXSS 中定义的样式类styleString组件的内联样式可以动态设置的内联样式hiddenBoolean组件是否显示所有组件默认显示data-Any自定义属性组件上触发的事件时,会发送给事件处理函数bind / catch*EventHandler组件的事件详见事件
🌟特殊属性
几乎所有组件都有各自定义的属性,可以对该组件的功能或样式进行修饰,请参考各个组件的定义。
🌟结语
这篇为小伙伴们讲解小程序的架构之【视图层】的知识;水滴石穿,积少成多。各位小伙伴让我们 let’s be prepared at all times!
✨原创不易,还希望各位大佬支持一下!
👍 点赞,你的认可是我创作的动力!
⭐️ 收藏,你的青睐是我努力的方向!
✏️ 评论,你的意见是我进步的财富!
版权归原作者 忆凡_ 所有, 如有侵权,请联系我们删除。