11.表单输入绑定
v-model会忽略所有表单元素的value、checked、selectedattribute 的初始值而总是将 Vue 实例的数据作为数据来源。你应该通过 JavaScript 在组件的data选项中声明初始值。
v-model 在内部为不同的输入元素使用不同的 property 并抛出不同的事件:
- text 和 textarea 元素使用
valueproperty 和input事件; - checkbox 和 radio 使用
checkedproperty 和change事件; - select 字段将
value作为 prop 并将change作为事件。
修饰符
- .lazy 在
change事件_之后_进行同步 - .number 将用户的输入值转为数值类型
- .trim 自动过滤用户输入的首尾空白字符
12.组件基础
1.一个组件的 data 选项必须是一个函数
因此每个实例可以维护一份被返回对象的独立的拷贝:
1 | data: function () { |
2.组件的组织
全局注册
全局注册的行为必须在根 Vue 实例 (通过
new Vue) 创建之前发生1
2
3Vue.component('my-component-name', {
// ... options ...
}局部注册
1
2
3
4
5
6
7
8
9
10import ComponentA from './ComponentA'
import ComponentC from './ComponentC'
export default {
components: {
ComponentA,
ComponentC
},
// ...
}基础组件的自动化全局注册
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75import Vue from 'vue'
import upperFirst from 'lodash/upperFirst'
import camelCase from 'lodash/camelCase'
const requireComponent = require.context(
// 其组件目录的相对路径
'./components',
// 是否查询其子目录
false,
// 匹配基础组件文件名的正则表达式
/Base[A-Z]\w+\.(vue|js)$/
)
requireComponent.keys().forEach(fileName => {
// 获取组件配置
const componentConfig = requireComponent(fileName)
// 获取组件的 PascalCase 命名
const componentName = upperFirst(
camelCase(
// 获取和目录深度无关的文件名
fileName
.split('/')
.pop()
.replace(/\.\w+$/, '')
)
)
// 全局注册组件
Vue.component(
componentName,
// 如果这个组件选项是通过 `export default` 导出的,
// 那么就会优先使用 `.default`,
// 否则回退到使用模块的根。
componentConfig.default || componentConfig
)
})
//真实案例
// Globally register all base components for convenience, because they
// will be used very frequently. Components are registered using the
// PascalCased version of their file name.
import Vue from 'vue'
// https://webpack.js.org/guides/dependency-management/#require-context
const requireComponent = require.context(
// Look for files in the current directory
'.',
// Do not look in subdirectories
false,
// Only include "_base-" prefixed .vue files
/_base-[\w-]+\.vue$/
)
// For each matching file name...
requireComponent.keys().forEach((fileName) => {
// Get the component config
const componentConfig = requireComponent(fileName)
// Get the PascalCase version of the component name
const componentName = fileName
// Remove the "./_" from the beginning
.replace(/^\.\/_/, '')
// Remove the file extension from the end
.replace(/\.\w+$/, '')
// Split up kebabs
.split('-')
// Upper case
.map((kebab) => kebab.charAt(0).toUpperCase() + kebab.slice(1))
// Concatenated
.join('')
// Globally register the component
Vue.component(componentName, componentConfig.default || componentConfig)
})3.通过Prop向子组件传递数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16<blog-post
v-for="post in posts"
v-bind:key="post.id"
v-bind:post="post"
></blog-post>
Vue.component('blog-post', {
props: ['post'],
template: `
<div class="blog-post">
<h3>{{ post.title }}</h3>
<div v-html="post.content"></div>
</div>
`
})
4.监听子组件事件
使用事件抛出一个值
1
2
3
4
5
6
7
8
9
10
11
12
13
14<button v-on:click="$emit('enlarge-text', 0.1)">
Enlarge text
</button>
<blog-post
...
v-on:enlarge-text="onEnlargeText"
></blog-post>
methods: {
onEnlargeText: function (enlargeAmount) {
this.postFontSize += enlargeAmount
}
}在组件上使用v-model
为了让它正常工作,这个组件内的
<input>必须:- 将其
valueattribute 绑定到一个名叫value的 prop 上 - 在其
input事件被触发时,将新的值通过自定义的input事件抛出
1
2
3
4
5
6
7
8
9
10Vue.component('custom-input', {
props: ['value'],
template: `
<input
v-bind:value="value"
v-on:input="$emit('input', $event.target.value)"
>
`
})
<custom-input v-model="searchText"></custom-input>- 将其