ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
[TOC] ### 2.1.2 渲染层/视图层--View 视图层 View 框架的视图层由 WXML 与 WXSS 编写,由组件来进行展示。将逻辑层的数据反应成视图,同时将视图层的事件发送给逻辑层。 WXML(WeiXin Markup language) 用于描述页面的结构。 WXS(WeiXin Script) 是小程序的一套脚本语言,结合 WXML,可以构建出页面的结构。 WXSS(WeiXin Style Sheet) 用于描述页面的样式。 组件(Component)是视图的基本组成单元。 #### 2.1.2.1 WXML WXML(WeiXin Markup Language)是框架设计的一套标签语言,结合基础组件、事件系统,可以构建出页面的结构。 ##### 1. 数据绑定 WXML 中的动态数据均来自对应`*.js`文件中page 的 data。 数据绑定使用 Mustache 语法(双大括号)将变量包起来,可以作用于: * 内容 ~~~HTML <view> {{ message }} </view> ~~~ ~~~JavaScript Page({ data: { message: 'Hello MINA!' } }) ~~~ * 组件属性(需要在双引号之内) ~~~HTML <view id="item-{{id}}"> </view> ~~~ ~~~JavaScript Page({ data: { id: 0 } }) ~~~ * 控制属性(需要在双引号之内) ~~~HTML <view wx:if="{{condition}}"> </view> ~~~ ~~~JavaScript Page({ data: { condition: true } }) ~~~ * 关键字(需要在双引号之内) true:boolean 类型的 true,代表真值。 false: boolean 类型的 false,代表假值。 ~~~HTML <checkbox checked="{{false}}"> </checkbox> ~~~ >[danger]不要直接写 checked="false",其计算结果是一个字符串,转成 boolean 类型后代表真值。 * 三元运算 ~~~HTML <view hidden="{{flag ? true : false}}"> Hidden </view> ~~~ * 算数运算 ~~~HTML <view> {{a + b}} + {{c}} + d </view> ~~~ ~~~JavaScript Page({ data: { a: 1, b: 2, c: 3 } }) ~~~ view中的内容为 `3 + 3 + d`。 * 逻辑判断 ~~~HTML <view wx:if="{{length > 5}}"> </view> ~~~ * 字符串运算 ~~~HTML <view>{{"hello" + name}}</view> ~~~ ~~~JavaScript Page({ data:{ name: 'MINA' } }) ~~~ * 数据路径运算 ~~~HTML <view>{{object.key}} {{array[0]}}</view> ~~~ ~~~JavaScript Page({ data: { object: { key: 'Hello ' }, array: ['MINA'] } }) ~~~ * 组合 也可以在 Mustache 内直接进行组合,构成新的对象或者数组。 * 数组 ~~~HTML <view wx:for="{{[zero, 1, 2, 3, 4]}}"> {{item}} </view> ~~~ ~~~JavaScript Page({ data: { zero: 0 } }) ~~~ 最终组合成数组`[0, 1, 2, 3, 4]`。 * 对象 ~~~HTML <template is="objectCombine" data="{{for: a, bar: b}}"></template> ~~~ ~~~JavaScript Page({ data: { a: 1, b: 2 } }) ~~~ 最终组合成的对象是 `{for: 1, bar: 2}` 也可以用扩展运算符` ... `来将一个对象展开 ~~~HTML <template is="objectCombine" data="{{...obj1, ...obj2, e: 5}}"></template> ~~~ ~~~JavaScript Page({ data: { obj1: { a: 1, b: 2 }, obj2: { c: 3, d: 4 } } }) ~~~ 最终组合成的对象是 `{a: 1, b: 2, c: 3, d: 4, e: 5}`。 如果对象的 key 和 value 相同,也可以间接地表达。 ~~~HTML <template is="objectCombine" data="{{foo, bar}}"></template> ~~~ ~~~JavaScript Page({ data: { foo: 'my-foo', bar: 'my-bar' } }) ~~~ 最终组合成的对象是` {foo: 'my-foo', bar:'my-bar'}`。 >[warning] 上述方式可以随意组合,但是如有存在变量名相同的情况,后边的会覆盖前面 如: ~~~HTML <template is="objectCombine" data="{{...obj1, ...obj2, a, c: 6}}"></template> ~~~ ~~~JavaScript Page({ data: { obj1: { a: 1, b: 2 }, obj2: { b: 3, c: 4 }, a: 5 } }) ~~~ 最终组合成的对象是 `{a: 5, b: 3, c: 6}`。 >[warning] 花括号和引号之间如果有空格,将最终被解析成为字符串 ~~~HTML <view wx:for="{{[1,2,3]}} "> {{item}} </view> ~~~ 等同于 ~~~HTML <view wx:for="{{[1,2,3] + ' '}}"> {{item}} </view> ~~~ ##### 2. 列表渲染 * `wx:for` 在组件上使用`wx:for`控制属性绑定一个数组,即可使用数组中各项的数据重复渲染该组件。 默认数组的当前项的下标变量名默认为 `index`,数组当前项的变量名默认为 `item` ~~~HTML <view wx:for="{{array}}"> {{index}}: {{item.message}} </view> ~~~ ~~~JavaScript Page({ data: { array: [{ message: 'foo', }, { message: 'bar' }] } }) ~~~ 使用 `wx:for-item` 可以指定数组当前元素的变量名, 使用 `wx:for-index` 可以指定数组当前下标的变量名: ~~~HTML <view wx:for="{{array}}" wx:for-index="idx" wx:for-item="itemName"> {{idx}}: {{itemName.message}} </view> ~~~ `wx:for` 也可以嵌套,下边是一个九九乘法表 ~~~HTML <view wx:for="{{[1, 2, 3, 4, 5, 6, 7, 8, 9]}}" wx:for-item="i"> <view wx:for="{{[1, 2, 3, 4, 5, 6, 7, 8, 9]}}" wx:for-item="j"> <view wx:if="{{i <= j}}"> {{i}} * {{j}} = {{i * j}} </view> </view> </view> ~~~ * `block wx:for` 类似 `block wx:if`,也可以将 `wx:for` 用在`<block/>`标签上,以渲染一个包含多节点的结构块。例如: ~~~HTML <block wx:for="{{[1, 2, 3]}}"> <view> {{index}}: </view> <view> {{item}} </view> </block> ~~~ * `wx:key` 如果列表中项目的位置会动态改变或者有新的项目添加到列表中,并且希望列表中的项目保持自己的特征和状态(如 `<input/>` 中的输入内容,`<switch/>` 的选中状态),需要使用 `wx:key` 来指定列表中项目的唯一的标识符。 `wx:key` 的值以两种形式提供 **字符串**,代表在 for 循环的 array 中 item 的某个 property,该 property 的值需要是列表中唯一的字符串或数字,且不能动态改变。 **保留关键字 `*this`** 代表在 for 循环中的 item 本身,这种表示需要 item 本身是一个唯一的字符串或者数字。 当数据改变触发渲染层重新渲染的时候,会校正带有 key 的组件,框架会确保他们被重新排序,而不是重新创建,以确保使组件保持自身的状态,并且提高列表渲染时的效率。 >[warning] 如不提供 wx:key,会报一个 warning, 如果明确知道该列表是静态,或者不必关注其顺序,可以选择忽略。 >[warning] 当 wx:for 的值为字符串时,会将字符串解析成字符串数组 如: ~~~HTML <view wx:for="array"> {{item}} </view> ~~~ 等同于 ~~~HTML <view wx:for="{{['a','r','r','a','y']}}"> {{item}} </view> ~~~ >[warning] 花括号和引号之间如果有空格,将最终被解析成为字符串 如: ~~~HTML <view wx:for="{{[1,2,3]}} "> {{item}} </view> ~~~ 等同于 ~~~HTML <view wx:for="{{[1,2,3] + ' '}}" > {{item}} </view> ~~~ ##### 3. 条件渲染 * `wx:if` 在框架中,使用 `wx:if="{{condition}}"` 来判断是否需要渲染该代码块: ~~~HTML <view wx:if="{{condition}}"> True </view> ~~~ 也可以用 wx:elif 和 wx:else 来添加一个 else 块: ~~~HTML <view wx:if="{{length > 5}}"> 1 </view> <view wx:elif="{{length > 2}}"> 2 </view> <view wx:else> 3 </view> ~~~ * `block wx:if` 因为 `wx:if` 是一个控制属性,需要将它添加到一个标签上。如果要一次性判断多个组件标签,可以使用一个 `<block/>` 标签将多个组件包装起来,并在上边使用 `wx:if` 控制属性。 ~~~HTML <block wx:if="{{true}}"> <view> view1 </view> <view> view2 </view> </block> ~~~ >[warning] `<block/>` 并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性。 `wx:if` vs `hidden` 因为 `wx:if` 之中的模板也可能包含数据绑定,所以当 wx:if 的条件值切换时,框架有一个局部渲染的过程,因为它会确保条件块在切换时销毁或重新渲染。 同时 `wx:if` 也是惰性的,如果在初始渲染条件为 false,框架什么也不做,在条件第一次变成真的时候才开始局部渲染。 相比之下,hidden 就简单的多,组件始终会被渲染,只是简单的控制显示与隐藏。 一般来说,wx:if 有更高的切换消耗而 hidden 有更高的初始渲染消耗。因此, >[warning] 如果需要频繁切换的情景下,用 hidden 更好,如果在运行时条件不大可能改变则 wx:if 较好。 ##### 4. 模板 WXML提供模板(template),可以在模板中定义代码片段,然后在不同的地方调用。 * 定义模板 使用 `name` 属性,作为模板的名字。然后在`<template/>`内定义代码片段,如: ~~~HTML <!-- index: int msg: string time: string --> <template name="msgItem"> <view> <text> {{index}}: {{msg}} </text> <text> Time: {{time}} </text> </view> </template> ~~~ * 使用模板 使用 `is` 属性,声明需要的使用的模板,然后将模板所需要的 data 传入,如: ~~~HTML <template is="msgItem" data="{{...item}}"/> ~~~ ~~~JavaScript Page({ data: { item: { index: 0, msg: 'this is a template', time: '2016-09-15' } } }) ~~~ `is` 属性可以使用 Mustache 语法,来动态决定具体需要渲染哪个模板: ~~~HTML <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> ~~~ * 模板的作用域 模板拥有自己的作用域,只能使用 data 传入的数据以及模版定义文件中定义的 `<wxs />` 模块。 ##### 5. 事件 * **什么是事件** >[info] * 事件是视图层到逻辑层的通讯方式。 > * 事件可以将用户的行为反馈到逻辑层进行处理。 > * 事件可以绑定在组件上,当达到触发事件,就会执行逻辑层中对应的事件处理函数。 > * 事件对象可以携带额外信息,如 id, dataset, touches。 * **事件的使用方式** * 在组件中绑定一个事件处理函数。 如`bindtap`,当用户点击该组件的时候会在该页面对应的Page中找到相应的事件处理函数。 ~~~HTML <view id="tapTest" data-hi="WeChat" bindtap="tapName"> Click me! </view> ~~~ 在相应的Page定义中写上相应的事件处理函数,参数是`event`。 ~~~JavaScript Page({ tapName: function(event) { console.log(event) } }) ~~~ 可以看到log出来的信息大致如下: ~~~JavaScript { "type":"tap", "timeStamp":895, "target": { "id": "tapTest", "dataset": { "hi":"WeChat" } }, "currentTarget": { "id": "tapTest", "dataset": { "hi":"WeChat" } }, "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 }] } ~~~ * **事件分类** 事件分为冒泡事件和非冒泡事件: * 冒泡事件:当一个组件上的事件被触发后,该事件会向父节点传递。 * 非冒泡事件:当一个组件上的事件被触发后,该事件不会向父节点传递。 WXML的冒泡事件列表: | 类型 | 触发条件 | 最低版本 | | --- | --- | --- | | touchstart | 手指触摸动作开始| | touchmove | 手指触摸后移动| | touchcancel | 手指触摸动作被打断,如来电提醒,弹窗| | touchend | 手指触摸动作结束| | tap | 手指触摸后马上离开| | longpress | 手指触摸后,超过350ms再离开,如果指定了事件回调函数并触发了这个事件,tap事件将不被触发| 1.5.0 | | longtap | 手指触摸后,超过350ms再离开(推荐使用longpress事件代替)| | transitionend | 会在 WXSS transition 或 wx.createAnimation 动画结束后触发| | animationstart | 会在一个 WXSS animation 动画开始时触发| | animationiteration | 会在一个 WXSS animation 一次迭代结束时触发| | animationend | 会在一个 WXSS animation 动画完成时触发| | touchforcechange |在支持 3D Touch 的 iPhone 设备,重按时会触发| 1.9.90 | >[info] 除上表之外的其他组件自定义事件如无特殊声明都是非冒泡事件,如`<form/>`的`submit`事件,`<input/>`的`input`事件,`<scroll-view/>`的`scroll`事件 * 事件绑定和冒泡 事件绑定的写法同组件的属性,以 key、value 的形式。 >[info] * `key` 以`bind`或`catch`开头,然后跟上事件的类型,如bindtap、catchtouchstart。自基础库版本 1.5.0 起,bind和catch后可以紧跟一个冒号,其含义不变,如`bind:tap`、`catch:touchstart`。 > * `value` 是一个字符串,需要在对应的 Page 中定义同名的函数。不然当触发事件的时候会报错。 >[warning] `bind`事件绑定不会阻止冒泡事件向上冒泡,`catch`事件绑定可以阻止冒泡事件向上冒泡。 如在下边这个例子: ~~~HTML <view id="outer" bindtap="handleTap1"> outer view <view id="middle" catchtap="handleTap2"> middle view <view id="inner" bindtap="handleTap3"> inner view </view> </view> </view> ~~~ 点击` inner view` 会先后调用handleTap3和handleTap2(因为tap事件会冒泡到 `middle view`,而 `middle view` 阻止了 tap 事件冒泡,不再向父节点传递),点击 `middle view` 会触发handleTap2,点击 `outer view` 会触发handleTap1。 * 事件的捕获阶段 自基础库版本 1.5.0 起,触摸类事件支持捕获阶段。捕获阶段位于冒泡阶段之前,且在捕获阶段中,事件到达节点的顺序与冒泡阶段恰好相反。需要在捕获阶段监听事件时,可以采用`capture-bind`、`capture-catch`关键字,后者将中断捕获阶段和取消冒泡阶段。 在下面的代码中,点击 `inner view` 会先后调用handleTap2、handleTap4、handleTap3、handleTap1。 ~~~HTML <view id="outer" bind:touchstart="handleTap1" capture-bind:touchstart="handleTap2"> outer view <view id="inner" bind:touchstart="handleTap3" capture-bind:touchstart="handleTap4"> inner view </view> </view> ~~~ 如果将上面代码中的第一个capture-bind改为capture-catch,将只触发handleTap2。 ~~~HTML <view id="outer" bind:touchstart="handleTap1" capture-catch:touchstart="handleTap2"> outer view <view id="inner" bind:touchstart="handleTap3" capture-bind:touchstart="handleTap4"> inner view </view> </view> ~~~ * 事件对象 如无特殊说明,当组件触发事件时,逻辑层绑定该事件的处理函数会收到一个事件对象。 `BaseEvent` 基础事件对象属性列表: | 属性 | 类型 | 说明 | | --- | --- | --- | | type | String | 事件类型 | | timeStamp | Integer | 事件生成时的时间戳 | | target | Object | 触发事件的组件的一些属性值集合 | | currentTarget | Object | 当前组件的一些属性值集合 | `CustomEvent` 自定义事件对象属性列表(继承 BaseEvent): | 属性 | 类型 | 说明 | | --- | --- | --- | | detail | Object | 额外的信息 | `TouchEvent` 触摸事件对象属性列表(继承 BaseEvent): | 属性 | 类型 | 说明 | | --- | --- | --- | | touches | Array | 触摸事件,当前停留在屏幕中的触摸点信息的数组 | | changedTouches | Array | 触摸事件,当前变化的触摸点信息的数组 | 特殊事件: `<canvas/>` 中的触摸事件不可冒泡,所以没有 currentTarget。 `type`:代表事件的类型。 `timeStamp`:页面打开到触发事件所经过的毫秒数。 `target`:触发事件的源组件。 | 属性 | 类型 | 说明 | | --- | --- | --- | | id | String | 事件源组件的id | | tagName | String | 当前组件的类型 | | dataset | Object | 事件源组件上由data-开头的自定义属性组成的集合 | `currentTarget`:事件绑定的当前组件。 | 属性 | 类型 | 说明 | | --- | --- | --- | | id | String| 当前组件的id | | tagName | String | 当前组件的类型 | | dataset | Object | 当前组件上由data-开头的自定义属性组成的集合 | `dataset`:在组件中可以定义数据,这些数据将会通过事件传递给 SERVICE。 书写方式: 以data-开头,多个单词由连字符-链接,不能有大写(大写会自动转成小写)如`data-element-type`,最终在 event.currentTarget.dataset 中会将连字符转成驼峰`elementType`。 示例: ~~~HTML <view data-alpha-beta="1" data-alphaBeta="2" bindtap="bindViewTap"> DataSet Test </view> ~~~ ~~~JavaScript Page({ bindViewTap:function(event){ event.currentTarget.dataset.alphaBeta === 1 // - 会转为驼峰写法 event.currentTarget.dataset.alphabeta === 2 // 大写会转为小写 } }) ~~~ `touches`:touches 是一个数组,每个元素为一个 Touch 对象(canvas 触摸事件中携带的 touches 是 CanvasTouch 数组)。 表示当前停留在屏幕上的触摸点。 Touch 对象 | 属性 | 类型 | 说明 | | --- | --- | --- | | identifier | Number | 触摸点的标识符| | pageX, pageY | Number | 距离文档左上角的距离,文档的左上角为原点 ,横向为X轴,纵向为Y轴| | clientX, clientY | Number | 距离页面可显示区域(屏幕除去导航条)左上角距离,横向为X轴,纵向为Y轴| CanvasTouch 对象 | 属性 | 类型 | 说明 | | --- | --- | --- | | identifier | Number | 触摸点的标识符 | x, y | Number | 距离 Canvas 左上角的距离,Canvas 的左上角为原点 ,横向为X轴,纵向为Y轴 `changedTouches`:changedTouches 数据格式同 touches。 表示有变化的触摸点,如从无变有(touchstart),位置变化(touchmove),从有变无(touchend、touchcancel)。 `detail`:自定义事件所携带的数据,如表单组件的提交事件会携带用户的输入,媒体的错误事件会携带错误信息,详见组件定义中各个事件的定义。 点击事件的`detail `带有的 x, y 同 pageX, pageY 代表距离文档左上角的距离。 ##### 6. 引用 WXML 提供两种文件引用方式`import`和`include`。 * import:可以在该文件中使用目标文件定义的template 如: 在 item.wxml 中定义了一个叫item的template: ~~~HTML <!-- item.wxml --> <template name="item"> <text>{{text}}</text> </template> ~~~ 在 index.wxml 中引用了 item.wxml,就可以使用item模板: ~~~HTML <!-- index.wxml --> <import src="item.wxml"/> <template is="item" data="{{text: 'forbar'}}"/> ~~~ import 有作用域的概念,即只会 import 目标文件中定义的 template,而不会 import 目标文件 import 的 template。即是只会import本文件中import定义的文件。 如:C import B,B import A,在C中可以使用B定义的template,在B中可以使用A定义的template,但是C不能使用A定义的template。 ~~~HTML <!-- A.wxml --> <template name="A"> <text> A template </text> </template> ~~~ ~~~HTML <!-- B.wxml --> <import src="a.wxml"/> <template name="B"> <text> B template </text> </template> ~~~ ~~~HTML <!-- C.wxml --> <import src="b.wxml"/> <template is="A"/> <!-- Error! Can not use tempalte when not import A. --> <template is="B"/> ~~~ * include include 可以将目标文件除了` <template/>` `<wxs/>` 外的整个代码引入,相当于是拷贝到 include 位置,如: ~~~HTML <!-- index.wxml --> <include src="header.wxml"/> <view> body </view> <include src="footer.wxml"/> ~~~ ~~~HTML <!-- header.wxml --> <view> header </view> ~~~ ~~~HTML <!-- footer.wxml --> <view> footer </view> ~~~ #### 2.1.2.2 WXS WXS(WeiXin Script)是小程序的一套脚本语言,结合 WXML,可以构建出页面的结构。 [【官方文档】](https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxs/) >[info] * wxs 不依赖于运行时的基础库版本,可以在所有版本的小程序中运行。 >* wxs 与 javascript 是不同的语言,有自己的语法,并不和 javascript 一致。 >* wxs 的运行环境和其他 javascript 代码是隔离的,wxs 中不能调用其他 javascript 文件中定义的函数,也不能调用小程序提供的API。 >* wxs 函数不能作为组件的事件回调。 >* 由于运行环境的差异,在 iOS 设备上小程序内的 wxs 会比 javascript 代码快 2 ~ 20 倍。在 android 设备上二者运行效率无差异。 WXML+WXS类似HTML+JavaScript,可在WXML中调用WXS里定义的函数进行“页面渲染”和“数据处理”等。 ##### 1. 页面渲染 ~~~HTML <!--wxml--> <wxs module="m1"> var msg = "hello world"; module.exports.message = msg; </wxs> <view> {{m1.message}} </view> ~~~ 页面输出:"hello world" ##### 2. 数据处理 ~~~JavaScript // page.js Page({ data: { array: [1, 2, 3, 4, 5, 1, 2, 3, 4] } }) ~~~ ~~~HTML <!--wxml--> <!-- 下面的 getMax 函数,接受一个数组,且返回数组中最大的元素的值 --> <wxs module="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 #### 2.1.2.3 WXSS [【官方文档】](https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxss.html) WXSS(WeiXin Style Sheets)是一套样式语言,用于描述 WXML 的组件样式。 WXSS 用来决定 WXML 的组件应该怎么显示。 为了适应广大的前端开发者,WXSS 具有 CSS 大部分特性。同时为了更适合开发微信小程序,WXSS 对 CSS 进行了扩充以及修改。 与 CSS 相比,WXSS 扩展的特性有: ##### 1. 尺寸单位--rpx rpx(responsive pixel): 可以根据屏幕宽度进行自适应。规定屏幕宽为750rpx。如在 iPhone6 上,屏幕宽度为375px,共有750个物理像素,则750rpx = 375px = 750物理像素,1rpx = 0.5px = 1物理像素。 建议: 开发微信小程序时设计师可以用 iPhone6 作为视觉稿的标准(1rpx = 0.5px, 1px = 2rpx)。 注意: 在较小的屏幕上不可避免的会有一些毛刺,请在开发时尽量避免这种情况。 ##### 2. 样式导入 使用`@import`语句可以导入外联样式表,`@import`后跟需要导入的外联样式表的相对路径,用`;`表示语句结束。 示例代码: ~~~CSS /** common.wxss **/ .small-p { padding:5px; } ~~~ ~~~CSS /** app.wxss **/ @import "common.wxss"; .middle-p { padding:15px; } ~~~ ##### 3. 内联样式 框架组件上支持使用 style、class 属性来控制组件的样式。 `style`:静态的样式统一写到 class 中。style 接收动态的样式,在运行时会进行解析,请尽量避免将静态的样式写进 style 中,以免影响渲染速度。 ~~~HTML <view style="color:{{color}};" /> ~~~ `class`:用于指定样式规则,其属性值是样式规则中类选择器名(样式类名)的集合,样式类名不需要带上`.`,样式类名之间用空格分隔。 ~~~HTML <view class="normal_view" /> ~~~ ##### 4. 选择器 目前支持的选择器有: | 选择器 | 样例 | 样例描述 | | --- | --- | --- | | .class | `.intro` | 选择所有拥有 class="intro" 的组件 | | #id | `#firstname ` | 选择拥有 id="firstname" 的组件| | element | `view` | 选择所有 view 组件| | element, element | `view, checkbox` | 选择所有文档的 view 组件和所有的 checkbox 组件| | ::after | `view::after` | 在 view 组件后边插入内容| | ::before | `view::before` | 在 view 组件前边插入内容| ##### 5. 全局样式与局部样式 定义在 `app.wxss` 中的样式为全局样式,作用于每一个页面。在 page 的 `wxss` 文件中定义的样式为局部样式,只作用在对应的页面,并会覆盖 `app.wxss` 中相同的选择器。 #### 2.1.2.4 组件 框架为开发者提供了一系列基础组件,开发者可以通过组合这些基础组件进行快速开发。 [【官方文档】](https://developers.weixin.qq.com/miniprogram/dev/component/index.html) 什么是组件: >[info] * 组件是视图层的基本组成单元。 > * 组件自带一些功能与微信风格的样式。 > * 一个组件通常包括`开始标签`和`结束标签`,`属性`用来修饰这个组件,`内容`在两个标签之内。 > * 所有组件与属性都是小写,以连字符`-`连接 组件示例: ~~~HTML <tagname property="value"> Content goes here ... </tagname> ~~~ 基础组件分为以下七大类: ##### 1. 视图容器(View Container) | 组件名 | 说明 | | --- | --- | | view | 视图容器 | | scroll-view | 可滚动视图容器 | | swiper | 滑块视图容器 | ##### 2. 基础内容(Basic Content) | 组件名 | 说明 | | --- | --- | | icon | 图标 | | text | 文字 | | progress | 进度条 | ##### 3. 表单(Form) | 组件名 | 说明 | | --- | --- | | button | 按钮 | | form | 表单 | | input | 输入框 | | checkbox | 多项选择器 | | radio | 单项选择器 | | picker | 列表选择器 | | picker-view | 内嵌列表选择器 | | slider| 滚动选择器 | | switch | 开关选择器 | | label | 标签 | ##### 4. 导航(Navigation) | 组件名 | 说明 | | --- | --- | | navigator | 应用链接 | ##### 5. 多媒体(Media) | 组件名 | 说明 | | --- | --- | | audio | 音频 | | image | 图片| | video | 视频 | ##### 6. 地图(Map) | 组件名 | 说明 | | --- | --- | | map | 地图 | ##### 7. 画布(Canvas) | 组件名 | 说明 | | --- | --- | | canvas | 画布|