Vant weapp 是微信小程序开发中常用的UI组件库,在使用中,有时候也会遇到一些”难题”, 就比如向今天一位学员提到的:“怎么才能定制Vant中Field组件的label颜色,而且是根据不同的情况动态的显示不同的颜色呢?”,今天就来教大家怎么解决这个问题?同时,也想通过这个例子,让大家体会Vue中slot的用法。

问题描述

假设我们有一个小程序的页面,名字叫: forms, 对应的文件是:

1
2
3
4
5
6
pages
+ forms
forms.js
forms.json
forms.wxml
forms.wxss

在forms.wxml文件中,我们放置了两个field和一个button

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<van-cell-group>
<van-field
value="{{ username }}"
clearable
required
icon="question-o"
label="用户名"
placeholder="请输入用户名"
bind:click-icon="onClickIcon"
>
</van-field>

<van-field
value="{{ password }}"
type="password"
label="密码"
placeholder="请输入密码"
required
border="{{ false }}"
/>
</van-cell-group>
<van-button size="small" type="primary" bind:click="onChangeColor">改变颜色</van-button>

界面上显示的效果如下图:

接下来,我们要想办法让“用户名”的颜色动态变化。当然,作为示例程序,为简单起见,我们使用按钮来触发颜色的变化,颜色也只是在红(red)和蓝(blue)之间切换。

解决思路

在小程序中,当出现要动态改变页面的样式(包括颜色,字体,背景等等)时,我们首先应该想到的就是通过改变元素对应的CSS来实现,思路是没错,但当我们查看Vant对应的文档时,发现没有单独对label的颜色进行设置的属性,因此这条路走通。继续查找,我们发现Field组件有几个slot属性,通过这些slot属性,我们可以对Field组件进行比较好的扩展。

  1. label (slot): 自定义输入框标签,如果设置了label属性则不生效
  2. left-icon (slot): 自定义输入框头部图标
  3. right-icon, icon (slot): 自定义输入框尾部图标
  4. button (slot): 自定义输入框尾部按钮

解决步骤

首先,改变forms.wxml文件,去掉标签中的label属性,加入slot

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<van-cell-group>
<van-field
value="{{ username }}"
clearable
required
icon="question-o"
placeholder="请输入用户名"
bind:click-icon="onClickIcon"
>
<view style="color: {{nameColor}}" slot="label">用户名称</view>
</van-field>

<van-field
value="{{ password }}"
type="password"
label="密码"
placeholder="请输入密码"
required
border="{{ false }}"
/>
</van-cell-group>
<van-button size="small" type="primary" bind:click="onChangeColor">改变颜色</van-button>

注意: 在这里我们使用了命名的slot, 并标明view的 slot属性为label, 同时加上了 style, 在style中设置color的值绑定变量 - nameColor。

然后,改变forms.js文件,加入nameColor属性和onChangeColor方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// pages/forms/forms.js
Page({

/**
* 页面的初始数据
*/
data: {
red: true,
nameColor: 'red'
},

onChangeColor: function() {

let color = "red"

if (this.data.red) {
color = "blue"
} else {
color = "red"
}
this.setData({
nameColor: color,
red: !this.data.red
})
}

})

在onChangeColor方法中,我们改变了nameColor的值,而nameColor是和wxml文件中的view的style绑定的,所以当我们按下按钮的时候,就可以看到label在红色和蓝色间切换了。

改变Field的图标(扩展)

通用的,在Field中,我们也可以通过slot来改变(使用)本地的图标文件,比如我们有一个图标文件放在images目录中:

1
2
3
4
5
6
7
8
images
+ field_delete_icon.png
pages
+ forms
forms.js
forms.json
forms.wxml
forms.wxss

我们就可以通过使用field的icon,left-icon或者是right-icon来改变显示的图标,改动forms.xml文件如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<van-cell-group>
<van-field
value="{{ username }}"
clearable
required
placeholder="请输入用户名"
bind:click-icon="onClickIcon"
>
<view style="color: {{nameColor}}" slot="label">用户名称</view>
<image slot="icon" src="../../images/field_delete_icon.png" style="width: 16px; height: 16px"></image>
</van-field>

<van-field
value="{{ password }}"
type="password"
label="密码"
placeholder="请输入密码"
required
border="{{ false }}"
/>
</van-cell-group>
<van-button size="small" type="primary" bind:click="onChangeColor">改变颜色</van-button>

注意: 增加了一个image标签,并且加入了slot属性,效果如下图: