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":
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 的值到父组件的数据中。每当父组件的数据变化时,该变化也会传导给子组件:
Prop 实例
<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 传到每一个重复的组件中:
Prop 实例
<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 可以是下面原生构造器:
StringNumberBooleanArrayObjectDateFunctionSymbol
type 也可以是一个自定义构造器,使用 instanceof 检测。
树上的鱼
ggq***7618@163.com
父组件给子组件传值的时候,如果想传入一个变量,写法如下:
// 注册 Vue.component('child', { // 声明 props props: ['message'], // 同样也可以在 vm 实例中像 "this.message" 这样使用 template: '<span>{{ message }}</span>' }) // 创建根实例 new Vue({ el: '#app', data:{ message:"hello", } })尝试一下 »
树上的鱼
ggq***7618@163.com
阿卡坤
404***770@qq.com
子组件通过 $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) } } }尝试一下 »
阿卡坤
404***770@qq.com
关关长语
324***7890@qq.com
拓展-如何通过调整组件属性,实现修改组件的显示等内部属性。
使用 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 } } })尝试一下 »
关关长语
324***7890@qq.com
holiday
597***772@qq.com
你可能在找的系统点击事件的例子。
<div id="app"> <p>点击元素输出元素内容:</p> <ol> <todo-item v-for="item in sites" v-bind:todo="item" @click.native="alert(item.text)"></todo-item> </ol> </div>尝试一下 »
holiday
597***772@qq.com
naivewood
zjx***tchi@163.com
<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>尝试一下 »
naivewood
zjx***tchi@163.com
zac
417***302@qq.com
参考地址
这个例子的执行过程注解:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title> <script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script> </head> <body> <div id="app"> <div id="counter-event-example"> // 6. 页面上更新total的值 <p>{{ total }}</p> // 4. 这里的自定义事件再次触发局域方法incrementTotal <button-counter v-on:increment="incrementTotal"></button-counter> <button-counter v-on:increment="incrementTotal"></button-counter> </div> </div> <script> // 1. 注册全局组件 Vue.component('button-counter', { // 2. button绑定点击事件incrementHandler template: '<button v-on:click="incrementHandler">{{ counter }}</button>', data: function () { return { counter: 0 } }, methods: { // 3. 点击事件触发后,再次触发自定义事件increment incrementHandler: function () { this.counter += 1 this.$emit('increment') } }, }) new Vue({ el: '#counter-event-example', data: { total: 0 }, methods: { // 5. 局域方法执行了total+1 incrementTotal: function () { this.total += 1 } } }) </script> </body> </html>zac
417***302@qq.com
参考地址