组件可以扩展HTML元素,封装可重用的HTML代码,我们可以将组件看作自定义的HTML元素。组件系统提供了一种抽象,让我们可以使用独立可复用的小组件来构建大型应用。
一个简单组件例子(全局注册)
<!DOCTYPE html> <html><body><div id="app"><!-- 3. #app是Vue实例挂载的元素,应该在挂载元素范围内使用组件--><the-component></the-component></div></body><script src="js/vue.js"></script><script>// 1.创建一个组件构造器var myComponent = Vue.extend({template: '<div> my first component!</div>'})// 2.注册组件,并指定组件的标签,组件的HTML标签为<the-component> Vue.component('the-component', myComponent)new Vue({el: '#app'});</script> </html>
运行结果:
分析:
1.Vue.extent() 是Vue构造器的扩展,调用Vue.extend()创建的是一个组件构造器,而不是一个具体的组件实例。它里面的选项对象的template属性用于定义组件要渲染的HTML。
2.Vue.component() 注册组件时,需要提供2个参数,第一个参数是组件的标签,第二个是组件构造器。它调用了组件构造器myComponent,创建一个组件实例。
3.组件应该挂载在某个Vue实例下,
new Vue({el: '#app' });
这段代码必须要有,表示挂载在#app元素上,否则不会生效。
局部注册:
<script>// 1.创建一个组件构造器var myComponent = Vue.extend({template: '<div> my first2 component!</div>'})new Vue({el: '#app',components: {// 2. 将myComponent组件注册到Vue实例下'the-component' : myComponent}});</script>
父组件和子组件
可以在组件中定义并使用其他组件,构成父子组件关系。
例子:(注意版本用vue.js 1.0的,2.0版本,button都出现不了)
<!DOCTYPE html> <html><head><meta charset="utf-8"></head><body><!-- 子组件模板 --><template id="child-template"><input v-model="msg"><button v-on:click="notify">Dispatch Event</button></template><!-- 父组件模板 --><div id="events-example"><p>Messages: {{ messages | json }}</p><child></child></div></body><script src="http://cdn.bootcss.com/vue/1.0.0-csp/vue.js"></script><script>// 注册子组件// 将当前消息派发出去 Vue.component('child', {template: '#child-template',data: function () {return { msg: 'hello' }},methods: {notify: function () {if (this.msg.trim()) {this.$dispatch('child-msg', this.msg)this.msg = ''}}}})// 初始化父组件// 将收到消息时将事件推入一个数组var parent = new Vue({el: '#events-example',data: {messages: []},// 在创建实例时 `events` 选项简单地调用 `$on` events: {'child-msg': function (msg) {// 事件回调内的 `this` 自动绑定到注册它的实例上this.messages.push(msg)}}})</script> </html>
运行结果:
props示例
<!DOCTYPE html> <html><head><meta charset="utf-8"></head><body><template id="myComponent"><table><tr><th colspan="2">子组件数据</th></tr><tr><td>myname</td><td v-text="myName"></td></tr><tr><td>myage</td><td v-text="myAge"></td></tr></table></template><div id="app"><my-component v-bind:my-name="name" v-bind:my-age="age"></my-component></div></body><script src="http://cdn.bootcss.com/vue/1.0.0-csp/vue.js"></script><script>var vm = new Vue({el: '#app',data: {name: 'wangjuan',age: 24},components: {'my-component': {template: '#myComponent',props: ['myName', 'myAge']}}});</script> </html>
结果为:
prop双向绑定
<!DOCTYPE html> <html><head><meta charset="utf-8"></head><body><template id="myComponent"><table><tr><th colspan="3">子组件数据</th></tr><tr><td>myname:</td><td v-text="myName"></td><td><input type="text" v-model="myName" /></td></tr><tr><td>myage:</td><td v-text="myAge"></td><td><input type="text" v-model="myAge" /></td></tr></table></template><div id="app"><table><tr><th colspan="3">父组件数据</th></tr><tr><td>name:</td><td>{{ name }}</td><td><input type="text" v-model="name" /></td></tr><tr><td>age:</td><td>{{ age }}</td><td><input type="text" v-model="age" /></td></tr></table><my-component v-bind:my-name="name" v-bind:my-age="age"></my-component></div></body><script src="http://cdn.bootcss.com/vue/2.0.0-rc.8/vue.js"></script><script>var vm = new Vue({el: '#app',data: {name: 'wangjuan',age: 24},components: {'my-component': {template: '#myComponent',props: ['myName', 'myAge']}}});</script> </html>
结果:
prop默认是单向绑定,不过这里我感觉默认是双向绑定,不知道哪里出问题了。。。
使用.sync或.once 绑定修饰符显式地强制双向或单次绑定。
子组件可以用this.$parent访问它的父组件。根实例的后代可以用this.$root访问它。父组件有一个数组this.$children,包含它所有的子元素。