Vue.js 组件
组件(Component)是 Vue.js 最强大的功能之一。
组件可以扩展 HTML 元素,封装可重用的代码。
组件系统让我们可以用独立可复用的小组件来构建大型应用,几乎任意类型的应用的界面都可以抽象为一个组件树:
注册一个全局组件语法格式如下:
Vue.component(tagName, options)
tagName 为组件名,options 为配置选项。注册后,我们可以使用以下方式来调用组件:
<tagName></tagName>
全局组件
所有实例都能用全局组件。
注册一个简单的全局组件 runoob,并使用它:
<div id="app">
<runoob></runoob>
</div>
<script>
// 注册
Vue.component('runoob', {
template: '<h1>自定义组件!</h1>'
})
// 创建根实例
new Vue({
el: '#app'
})
</script>
局部组件
注册一个简单的局部组件 runoob,并使用它:
<div id="app">
<runoob></runoob>
</div>
<script>
var Child = {
template: '<h1>自定义组件!</h1>'
}
// 创建根实例
new Vue({
el: '#app',
components: {
// <runoob> 将只在父模板可用
'runoob': Child
}
})
</script>
Prop
prop 是子组件用来接受父组件传递过来的数据的一个自定义属性。
父组件的数据需要通过 props 把数据传给子组件,子组件需要显式地用 props 选项声明 “prop”:
<div id="app">
<child message="hello!"></child>
</div>
<script>
// 注册
Vue.component('child', {
// 声明 props
props: ['message'],
// 同样也可以在 vm 实例中像 "this.message" 这样使用
template: '<span>{{ message }}</span>'
})
// 创建根实例
new Vue({
el: '#app'
})
</script>
动态 Prop
类似于用 v-bind 绑定 HTML 特性到一个表达式,也可以用 v-bind 动态绑定 props 的值到父组件的数据中。每当父组件的数据变化时,该变化也会传导给子组件:
<div id="app">
<div>
<input v-model="parentMsg">
<br>
<child v-bind:message="parentMsg"></child>
</div>
</div>
<script>
// 注册
Vue.component('child', {
// 声明 props
props: ['message'],
// 同样也可以在 vm 实例中像 "this.message" 这样使用
template: '<span>{{ message }}</span>'
})
// 创建根实例
new Vue({
el: '#app',
data: {
parentMsg: '父组件内容'
}
})
</script>
以下使用 v-bind 指令将 todo 传到每一个重复的组件中:
<div id="app">
<ol>
<todo-item v-for="item in sites" v-bind:todo="item"></todo-item>
</ol>
</div>
<script>
Vue.component('todo-item', {
props: ['todo'],
template: '<li>{{ todo.text }}</li>'
})
new Vue({
el: '#app',
data: {
sites: [
{ text: 'Runoob' },
{ text: 'Google' },
{ text: 'Taobao' }
]
}
})
</script>
注意: prop 是单向绑定的:当父组件的属性变化时,将传导给子组件,但是不会反过来。
Prop 验证
组件可以为 props 指定验证要求。
为了定制 prop 的验证方式,你可以为 props 中的值提供一个带有验证需求的对象,而不是一个字符串数组。例如:
Vue.component('my-component', {
props: {
// 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
propA: Number,
// 多个可能的类型
propB: [String, Number],
// 必填的字符串
propC: {
type: String,
required: true
},
// 带有默认值的数字
propD: {
type: Number,
default: 100
},
// 带有默认值的对象
propE: {
type: Object,
// 对象或数组默认值必须从一个工厂函数获取
default: function () {
return { message: 'hello' }
}
},
// 自定义验证函数
propF: {
validator: function (value) {
// 这个值必须匹配下列字符串中的一个
return ['success', 'warning', 'danger'].indexOf(value) !== -1
}
}
}
})
当 prop 验证失败的时候,(开发环境构建版本的) Vue 将会产生一个控制台的警告。
type 可以是下面原生构造器:
String
Number
Boolean
Array
Object
Date
Function
Symbol
type 也可以是一个自定义构造器,使用 instanceof 检测。
父组件给子组件传值的时候,如果想传入一个变量,写法如下:
// 注册
Vue.component('child', {
// 声明 props
props: ['message'],
// 同样也可以在 vm 实例中像 "this.message" 这样使用
template: '<span>{{ message }}</span>'
})
// 创建根实例
new Vue({
el: '#app',
data:{
message:"hello",
}
})
子组件通过 $emit 触发父组件的方法时,如果需要传递参数,可在方法名后面加可选参数,参数以逗号隔开。
比如 $emit("FunctionName") 当要传递参数时 :$emit("FunctionName",[arg1,arg2...])。
methods: {
incrementHandler: function (v) {
if(v==1){
this.counter -= 1
this.$emit('increment',1)
}else{
this.counter += 1
this.$emit('increment',2)
}
}
}
拓展-如何通过调整组件属性,实现修改组件的显示等内部属性。
使用 Props(全局)
全局定义组件
Vue.component('example1', {
props: ['value'],
template: '<button v-on:click="incrementHanlder">{{value}}</button>',
// data: function () {
// return {
// count: 0
// }
// },
methods: {
incrementHanlder: function () {
// this.count += 1
this.$emit('incretment')
}
}
})
new Vue({
el: '#div_col',
data: {
total: 0
},
methods: {
incretmentTotal: function () {
this.total += 1
}
}
})
props 验证补充代码:注意 替换 vue.min.js 为 vue.js,验证结果可以到浏览器 console 查看,自定义验证函数尚未尝试出来
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.js"></script>
<div id="app">
<example
:propa="'asda'"
:propb = "'aasasa'"
:propc="'sdf'"
:prope="{a:'a'}"
:propf="100"
></example>
</div>
<script type="text/javascript">
Vue.component('example', {
props: {
// 基础类型检测 (`null` 意思是任何类型都可以)
propa: Number,
// 多种类型
propb: [String, Number],
// 必传且是字符串
propc: {
type: String,
required: true
},
// 数字,有默认值
propd: {
type: Number,
default: 1000
},
// 数组/对象的默认值应当由一个工厂函数返回
prope: {
type: Object,
default: function () {
return { message: 'hello' }
}
},
// 自定义验证函数
propf: {
type: Number,
validator: function (value) {
// 这个值必须匹配下列字符串中的一个
return value>0? -1:1
},
defalut:12
}
},
template: `
<table border="1px">
<tr>
<th>propA</th>
<th>propB</th>
<th>propC</th>
<th>propD</th>
<th>propE</th>
<th>propF</th>
</tr>
<tr>
<td>{{ propa }}</td>
<td>{{ propb }}</td>
<td>{{ propc }}</td>
<td>{{ propd }}</td>
<td>{{ prope }}</td>
<td>{{ propf }}</td>
</tr>
</table>`
})
new Vue({
el: "#app"
});
</script>