微信小程序学习之路——页面结构文件(WXML)

WXML(WeiXin Markup Language)是框架设计的一套标准语言,用于渲染界面,WXML的渲染原理和React Native思路一致,通过一套标记语言,在不同平台被解析为不用端的渲染文件,如图:
微信小程序学习之路——页面结构文件(WXML)_第1张图片

使用微信开发者工具时,在WXML中编写一些HTML标签或自定义标签仍然会被正常解析,这会给开发者造成一种小程序能直接支持HTML标签的误解。这是因为微信开发者工具内核是浏览器内核,同时小程序框架并没对WXML中的标签和WXSS中的内容进行强验证,所以HTML和CSS能直接被解析,但这种不合法的WXML在手机端微信中是不能正常显示的。开发过程中我们异地杠幺拿真机进行测试,保证程序能正常运行。WXML具有数据绑定、列表渲染、条件渲染、模板、事件等能力。

1.数据绑定

小程序中页面渲染时,框架会将WXML文件同时对应Page的data进行绑定,在页面中我们可以直接使用data中的属性。小程序的数据绑定使用Mustache语法(双大括号{{}})将变量或简单的运算规则抱起来,主要由以下几种渲染方式:

1)简单绑定

简单绑定是指我们使用Mustache语法(双大括号{{}})将变量包起来,在模板中直接作为字符串输出使用,可作用于内容、组件属性、控制属性、关键字等输出,其中关键字输出是将JavaScript中的关键字按其真值输出。

示例代码如下:

{{content}}
作为属性渲染
作为属性渲染
{{2}}
Page({
  data: {
    border:'solid 1px #000',
    id:1,
    content:'内容',
    showContent:false 
  }
})

运行效果如下:

微信小程序学习之路——页面结构文件(WXML)_第2张图片

注意:组件属性为boolean类型时,不要直接写checked ="false",这样checked的值时一个false的字符串,转成boolean类型后代表为true,所以这种情况一定要使用关键字输出:checked="{{false}}"

2)运算

在{{}}内可以做一些简单的运算,支持的运算有三元运算、算术运算、逻辑判断、字符串运算,这些运算均符合JavaScript运算规则,示例如下:

Page({
  data: {
    showContent:false,
    num1:1,
    num2:2,
    num3:3,
    name:'weixin',
    myObject:{
      age:12
    },
    myArray:['arr1','arr2']
  }
});
{{showContent ?'显示文本':'不显示文本'}}
{{num1+num2}}+1+{{num3}}=?
{{"name:"+name}}
{{num3>0}}
{{myObject.age}}{{myArray[1]}}

执行结果如下:

微信小程序学习之路——页面结构文件(WXML)_第3张图片

3)组合

data中的数据可以在模板再次组合成新的数据结构,这种组合常常在数组或对象中使用,数组组合比较简单,可以直接将值放置到数组某个下标下:

{{[myValue,2,3,'stringtype']}}
Page(
  {
    data:{
      myValue:0
    }
  }
)

输出结果为:

对象组合有3种组合方式,这里我们以数据注入模板为例

第一种,直接将数据作为value值进行组合:

Page(
  {
    data: {
      myValue1: 'value1',
      myValue2: 'value2'
    }
  }
)

最终组合成的对象为:{name:'vaue1',age:'value2'}

第二种,通过“...”将一个对象展开,把key-value值拷贝到新的结构中:

Page({
    data:{
        myObj1:{
            key1:1,
            key2:2
            },
        myObj2:{
            key3:3,
            key4:4
        }
    }
});

最终组合成的对象为:{key1:1,key2:2,key5:5,key3:3,key4:4,key6:6}

第三种,如果对象key和value相同,可以只写key值:

Page({
    data:{
        key1:1,
        key2:2
}
});

最后的组合对象为:{key1:1,key2:2}

如果一个组合中有相同的属性名时,后面的属性将会覆盖前面的属性,如:


Page({
    data:{
        key1:1,
        key2:2
}
});

最后的组合对象为:{key1:3,key2:2}

2.条件渲染

1)wx:if

除了简单的数据绑定,我们常常会使用逻辑分支,这时候可以使用wx:if="{{判断条件}}"来进行条件渲染,当条件成立时渲染该块代码:

内容
Page({
  data:{
    showContent:true /*若未false则不显示Content*/
  }
});

执行结果如下:

 

和普通的编程语言一样,WML也支持wx:elif和wx:else,如:

1
2
3

2)block wx:if

wx:if是一个控制属性,可以添置在任何组件标签上,但如果我们需要包装多个组件,又不想影响布局,这时就需要使用标签将需要包装的组件放置在里面,通过wx:if做判断。不是一个组件,仅仅是一个包装元素,页面渲染过程中不做任何渲染,由属性控制,如下所示:


  view组件
  

3)wx:if与hidden

除了wx:if组件,也有了通过hidden属性控制组件是否显示,开发者难免有疑问,这两种方式该怎样取舍,这里我们整理了两种方式的区别:

  • wx:if控制是否渲染条件块内的模板,当其条件值切换时,会触发布局渲染以确保条件快在切换时销毁或重新渲染。wx:if是惰性的,如果在初始渲染条件为false时,框架将生命也不做,在条件第一次为真时才局部渲染
  • hidden控制组件是否显示,组件始终会被渲染,只是简单控制显示与隐藏,并不会触发重新渲染和销毁。

在频繁切换状态的场景中,会产生更大的消耗,这时尽量使用hidden;

在运行时条件变动不大的场景中我们使用wx:if,这样能保证页面有更高效的渲染,而不用把所有组件渲染出来。

3.列表渲染

1)wx:for

组件的wx:for控制属性用于遍历数组,重复渲染该组件,遍历过程中当前项的下标变量名默认为index,数组当前项变量名默认为item,如:


{{index}}:{{item}}
Page({
  data:{
    myArray:['value1','value2']
  }
});

执行结果如下:

2)wx:for-index和wx:for-item的变量名修改

index、item变量名可以通过wx:for-index、wx:for-item属性修改,如:


{{myIndex}}:{{myItem.name}}
Page({
  data:{
    myArray:[
      {name: 'value1'},
      {name: 'value2'}
    ]
  }
});

执行结果如下:微信小程序学习之路——页面结构文件(WXML)_第4张图片

普遍遍历中我们没必要修改index、item变量名,当wx:for嵌套使用时,就有必要设置变量名,避免变量名冲突,下面我们遍历一个二维数组:


{{subItem}}

Page({
  data:{
    myArray:[
     [1,2,3],
     [4,5,6],
     [7,8,9]
    ]
  }
});

执行结果如下:微信小程序学习之路——页面结构文件(WXML)_第5张图片

在本示例中,我们使用了标签,和block wx:if一样,wx:for可以直接在标签上使用,以渲染一个包含多个节点的结构快。

4.模板

在项目过程中,常常会遇到某些相同的结构在不同的地方反复出现,这时可以将相同的布局代码片段放置到一个模板中,在不同的地方传入到对应的数据进行渲染,这样能避免重复开发,提升开发效率。

1)定义模板

定义模板非常简单,在