第八节:视图层

一:理解视图层
    类似于“视图引擎模板”(jsp,freemaker,velocity,thymeleaf等)
    框架的视图层由 WXML 与 WXSS 编写,由组件来进行展示
    将逻辑层的数据反应成视图,同时将视图层的事件发送给逻辑层
    那么wxml,wxss以及组件是什么鬼?
        WXML(WeiXin Markup language) 用于描述页面的结构。
        WXSS(WeiXin Style Sheet) 用于描述页面的样式。
        组件(Component)是视图的基本组成单元。
        另:
        WXS(WeiXin Script) 是小程序的一套脚本语言,结合 WXML,可以构建出页面的结构。
二:WXML
    WXML(WeiXin Markup Language)是框架设计的一套标签语言,结合基础组件、事件系统,可以构建出页面的结构。
    WXML 具有什么能力:数据绑定、列表渲染、条件渲染、模板、事件、引用
    1.数据绑定(WXML 中的动态数据均来自对应 Page 的 data)
        数据绑定使用 Mustache 语法(双大括号将变量包起来)
        注意: 花括号和引号之间如果有空格,将被解析成为字符串
        1)简单绑定_内容绑定
             {{ message }}
            Page({ data: { message:'Hello MINA!'}})
        2)简单绑定_组件属性(需要在双引号之内)
            
            Page({ data: { id:0}})
        3)简单绑定_控制属性(需要在双引号之内)
            
            Page({ data: { condition:true}})
        4)简单绑定_关键字(需要在双引号之内)
            true:boolean 类型的 true,代表真值。
            false: boolean 类型的 false,代表假值。
            
            特别注意:不要直接写 checked="false",其计算结果是一个字符串,
                                转成 boolean 类型后代表真值。
        可以在 {{}} 内进行简单的运算
        5)绑定_运算_三元运算
            
        6)绑定_运算_算数运算
             {{a + b}} + {{c}} + d
            Page({ data: { a:1, b:2, c:3}})
            view中的内容为 3 + 3 + d
        7)绑定_运算_逻辑判断
            
        8)绑定_运算_字符串运算
            {{"hello" + name}}
            Page({ data:{ name:'MINA'}})
        9)绑定_运算_数据路径运算
            {{object.key}} {{array[0]}}    
            Page({ data: { object: { key:'Hello '}, array: ['MINA'] }})
        也可以在 Mustache 内直接进行组合,构成新的对象或者数组。
        10)绑定_组合_数组
             {{item}}
            age({ data: { zero:0}})
            最终组合成数组[0, 1, 2, 3, 4]
        11)绑定_组合_对象1
            
            Page({ data: { a:1, b:2}})
            最终组合成的对象是 {for: 1, bar: 2}
        12)绑定_组合_对象2
            如果对象的 key 和 value 相同,也可以间接地表达。
            
            Page({ data: { foo:'my-foo', bar:'my-bar'}})
            最终组合成的对象是 {foo: 'my-foo', bar:'my-bar'}
        13)绑定_组合_对象3
            也可以用扩展运算符 ... 来将一个对象展开
            < template is="objectCombine" data="{{...obj1, ...obj2, e: 5}}">< /template>
            Page({ data: { obj1: { a:1, b:2}, obj2: { c:3, d:4} }})
            最终组合成的对象是 {a: 1, b: 2, c: 3, d: 4, e: 5}
        14)绑定_组合_对象4
            上述方式可以随意组合,但是如有存在变量名相同的情况,后边的会覆盖前面
            
            Page({ data: { obj1: { a:1, b:2}, obj2: { b:3, c:4}, a:5}
            最终组合成的对象是 {a: 5, b: 3, c: 6}
    2.列表渲染
        1) wx:for
            在组件上使用 wx:for 控制属性绑定一个数组,即可使用数组中各项的数据重复渲染该组件
            1>默认数组的当前项的下标变量名默认为 index,数组当前项的变量名默认为 item
                
                    {{index}}: {{item.message}}
               

                Page({ data: { array: [{ message:'foo'}, { message:'bar'}] }})
            2>指定变量名
                使用 wx:for-item 可以指定数组当前元素的变量名
                使用 wx:for-index 可以指定数组当前下标的变量名
                
                     {{idx}}: {{itemName.message}}
                

            3>wx:for 也可以嵌套,下边是一个九九乘法表
                
                    
                        
                            {{i}} * {{j}} = {{i * j}}
                        

                    

                

            4>循环中出现警告
                warning: Now you can provide attr "wx:key" for a "wx:for" to improve performance. 
                如果列表中项目的位置会动态改变或者有新的项目添加到列表
                希望列表中的项目保持自己的特征和状态
                如中的输入内容,的选中状态
                需要使用 wx:key 来指定列表中项目的唯一的标识符
                目的:
                    当数据改变触发渲染层重新渲染的时候,会校正带有 key 的组件
                    框架会确保他们被重新排序,而不是重新创建
                    以确保使组件保持自身的状态,并且提高列表渲染时的效率。
                wx:key 的值以两种形式提供:
                    1.字符串,代表在 for 循环的 array 中 item 的某个 property,
                         该 property 的值需要是列表中唯一的字符串或数字,且不能动态改变,
                        所以使用{{index}}是不错的选择,肯定是一个不重复的数字
                    2.保留关键字 *this 代表在 for 循环中的 item 本身
                        使用*this需要 item 本身是一个唯一的字符串或者数字,来确保Key是唯一的。
                        即如果数据数组是字符串或数字,且每项都是唯一的,则可以使用wx:key="*this"
                      wx:key="{{idx}}" >
               如果明确知道该列表是静态,或者不必关注其顺序,可以选择忽略不使用wx:key的警告。
        2)block wx:for
            可以将 wx:for 用在标签上,以渲染一个包含多节点的结构块。
            
                 {{index}}:
                 {{item}}
            

    3.条件渲染
        wx:if 
        1>在框架中,使用 wx:if="{{condition}}" 来判断是否需要渲染该代码块
                True
        2>也可以用 wx:elif 和 wx:else 来添加一个 else 块
                 1
                 2
                 3
        3>block wx:if
            因为 wx:if 是一个控制属性,需要将它添加到一个标签上。
            如果要一次性判断多个组件标签,可以使用一个  标签将多个组件包装起来,
            并在上边使用 wx:if 控制属性。
            
                 view1
                 view2
            

            注意: 不是一个组件,仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性。
        4>wx:if vs hidden
            因为 wx:if 之中的模板也可能包含数据绑定,所有当 wx:if 的条件值切换时,框架有一个局部渲染的过程,因为它会确保条件块在切换时销毁或重新渲染。
            同时 wx:if 也是惰性的,如果在初始渲染条件为 false,框架什么也不做,在条件第一次变成真的时候才开始局部渲染。
            相比之下,hidden 就简单的多,组件始终会被渲染,只是简单的控制显示与隐藏。
            一般来说,wx:if 有更高的切换消耗而 hidden 有更高的初始渲染消耗。因此,如果需要频繁切换的情景下,用 hidden 更好,如果在运行时条件不大可能改变则 wx:if 较好。    
    4.模板
        WXML提供模板(template),可以在模板中定义代码片段,然后在不同的地方调用
        模板的作用域:只能使用 data 传入的数据以及模版定义文件中定义的  模块
        模板应用场景:可以做母板页
        1>定义模板(使用 name 属性,作为模板的名字。然后在内定义代码片段)
            
            模板中定义名称=msgItem,且定义了使用模板时需要传入的3个data数据
        2>使用模板(使用 is 属性,声明需要的使用的模板,然后将模板所需要的 data 传入)