Vue指南的要点笔记(四)

本篇要点:

  1. v-model基础用法
  2. 值绑定的用法
  3. 修饰符的用法

v-model基础用法

网页的表单元素主要有:checkbox radio select textarea input等,在Vue里面,表单元素的赋值与数据收集全部都使用v-model指令来完成。

v-model 会忽略所有表单元素的 value、checked、selected 特性的初始值而总是将 Vue 实例的数据作为数据来源。
v-model 在内部为不同的输入元素使用不同的属性并抛出不同的事件:
text 和 textarea 元素使用 value 属性和 input 事件;
checkbox 和 radio 使用 checked 属性和 change 事件;
select 字段将 value 作为 prop 并将 change 作为事件。

input和textarea

1
2
3
4
5
6
7
<input v-model="message" placeholder="edit me">
<p>Message is: {{ message }}</p>

<span>Multiline message is:</span>
<p style="white-space: pre-line;">{{ message }}</p>
<br>
<textarea v-model="message" placeholder="add multiple lines"></textarea>

checkbox

单个复选框,v-model要绑定为一个Boolean的数据:

1
2
3
4
5
6
7
8
9
10
11
<input type="checkbox" id="checkbox" v-model="checked">
<label for="checkbox">{{ checked }}</label>

<script type="text/javascript">
new Vue({
el: '...',
data: {
checked: false
}
})
</script>

多个复选框,v-model可以绑定到同一个数组,这个数组的元素通常是字符串值,因为它要与checkbox元素的value属性比较,checkbox元素的value属性通常是字符串值:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<div id='example-3'>
<input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
<label for="jack">Jack</label>
<input type="checkbox" id="john" value="John" v-model="checkedNames">
<label for="john">John</label>
<input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
<label for="mike">Mike</label>
<br>
<span>Checked names: {{ checkedNames }}</span>
</div>

<script type="text/javascript">
new Vue({
el: '#example-3',
data: {
checkedNames: []
}
})
</script>

注意:是同一个数组

radio

v-model通常绑定到一个字符串的数据上, 因为它是与radio元素的value属性要进行比较的,radio元素的value属性通常是字符串的值:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<div id="example-4">
<input type="radio" id="one" value="One" v-model="picked">
<label for="one">One</label>
<br>
<input type="radio" id="two" value="Two" v-model="picked">
<label for="two">Two</label>
<br>
<span>Picked: {{ picked }}</span>
</div>

<script type="text/javascript">
new Vue({
el: '#example-4',
data: {
picked: ''
}
})
</script>

select

单选时,v-model也是绑定到一个字符串的数据,因为select元素的option子元素的value属性通常是字符串的值:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<div id="example-5">
<select v-model="selected">
<option disabled value="">请选择</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
<span>Selected: {{ selected }}</span>
</div>

<script type="text/javascript">
new Vue({
el: '...',
data: {
selected: ''
}
})
</script>

如果 v-model 表达式的初始值未能匹配任何选项,<select> 元素将被渲染为“未选中”状态。在 iOS 中,这会使用户无法选择第一个选项。因为这样的情况下,iOS 不会触发 change 事件。因此,更推荐像上面这样提供一个值为空的禁用选项。

多选时,v-model通常绑定到一个字符串数组:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<div id="example-6">
<select v-model="selected" multiple style="width: 50px;">
<option>A</option>
<option>B</option>
<option>C</option>
</select>
<br>
<span>Selected: {{ selected }}</span>
</div>

<script type="text/javascript">
new Vue({
el: '#example-6',
data: {
selected: []
}
})
</script>

值绑定的用法

总结上面的基础用法,会发现v-model绑定的数据类型基本上这样的:

  1. input或textarea,绑定到字符串数据
  2. checkbox单选绑定到boolean
  3. checkbox多选、select多选,绑定到字符串数组
  4. radio、select单选绑定到字符串数据

可以看到,除了checkbox单选的模式下,其它场景都绑定的都是字符串相关类型数据。 这种使用方式不一定是能满足实际需求的,举个例子说,现在有一个select用来展示一个教室列表,教室数据是从后台返回的一个数组,需求是当教室选择以后,根据教室的最大人数限制,来控制页面上另外几个组件的显示和隐藏,一般的做法是在后台数据拿到后缓存起来,当select选中某个值后,根据option的value,通常是教室的id,然后到缓存的教室数据中,查找出教室的最大人数值,再继续后面的逻辑;更方便的做法是,当select选中某个值后,自动就拿到这个教室的完整的从后台返回的数据,然后直接进行后面的逻辑。为了支持类似的更多场景,Vue支持对checkbox radio select的值进行动态绑定,可以绑定到任意类型的数据,v-model绑定的数据属性,也会与它们的值保持一致的类型。

checkbox

先看checkbox单选的情况,默认情况下,checkbox单选模式,如果选中,则v-model的数据会赋值为true,如果取消选中,v-model的数据会赋值为false。 有的时候,true、false值不是我们需要的,比如我们可能需要的是1或2,则可以这么干:

1
2
3
4
5
6
7
8
9
10
11
12
13
<div id="vue">
<input type="checkbox" v-model="agreement" :true-value="1" :false-value="2">
<p>{{agreement}}/{{typeof agreement}}</p>
</div>

<script type="text/javascript">
let vue = new Vue({
el: '#vue',
data: {
agreement: 2
}
});
</script>

上面这个示例,将单选的checkbox绑定的数据,从boolean更换为了number值。

再看checkbox多选的情况,默认情况下它是绑定到一个字符串数组,但是只要value属性动态绑定到一个非字符串的类型的值,那么v-model就可以绑定为一个同类型的数组:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<div id="vue">
<label v-for="item of paymethods" :key="'pm_' + item.code">
<input type="checkbox" v-model="selected" :value="item">
{{item.name}}
</label>
<p>{{selected}}</p>
</div>

<script type="text/javascript">
let vue = new Vue({
el: '#vue',
data: {
selected: [],
paymethods: [
{code: 'wechat', name: '微信支付', fee: '0.006'},
{code: 'alipay', name: '支付宝支付', fee: '0.005'}
]
}
});
</script>

这个示例中,v-model绑定的selected最后收集到的数据,就是从paymethods数组中选中的数据,是object类型的,而不是字符串的;因为input[type=”checkbox”]的元素的value属性动态绑定到了一个object数据。

radio

跟checkbox多选的模式同理,radio元素,如果不想绑定为字符串的值,可以把value属性动态绑定为一个任意类型的值,然后v-model就可以收集到一个跟value值类型一致的值。

select

它的动态绑定不是作用于自身,而是在子元素option身上,它的单选模式动态绑定同radio类似,多选模式同checkbox类似。这是单选的示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<div id="vue">
<select v-model="selected">
<option disabled="">请选择</option>
<option v-for="item of rooms" :key="'room_' + item.id" :value="item">{{item.name}}</option>
</select>
</label>
<p v-if="selected">max_user_limit: {{selected.max_user_limit}}</p>
</div>

<script type="text/javascript">
let vue = new Vue({
el: '#vue',
data: {
selected: null,
rooms: [
{id: 1, name: 'B教室', max_user_limit: 12},
{id: 2, name: 'C教室', max_user_limit: 10}
]
}
});
</script>

这是多选示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
```html
<div id="vue">
<select v-model="selected" multiple>
<option disabled="">请选择</option>
<option v-for="item of paymethods" :key="'pm_' + item.code" :value="item">{{item.name}}</option>
</select>
</label>
<p>{{selected}}</p>
</div>

<script type="text/javascript">
let vue = new Vue({
el: '#vue',
data: {
selected: [],
paymethods: [
{code: 'wechat', name: '微信支付', fee: '0.006'},
{code: 'alipay', name: '支付宝支付', fee: '0.005'}
]
}
});
</script>

修饰符的用法

v-model指令支持三个修饰符:

  1. .lazy 将数据绑定底层使用的input事件改为change事件
  2. .number 自动将输入的值转换为number类型,如果这个值无法被 parseFloat() 解析,则会返回原始的值
  3. .trim 自动过滤用户输入的首尾空白字符