一、什么是组件
对于组件系统,官方的解释是:组件系统是vue.js中一个重要的概念,它提供了一种抽象,让我们可以使用独立可复用的小组件来构建大型应用,任意类型的应用界面都可以抽象为一个组件树。通俗点讲,组件就是一个可扩充的HTML元素,或者可以理解我我们自己定义的HTML元素,通过组件的一些选项我们可以定义一个符合我们需要的新的HTML元素。
二、组件的创建和注册
1、基本步骤
Vue中的组件使用有三个步骤
(1)创建组件的构造器,创建的方法是通过Vue的extend方法来创建。
Vue.extend({
template:''
})
这里面的template属性定义了组件要渲染的HTML元素,也就是要将组件渲染成什么。
(2)注册组件,通过Vue.component()方法。
Vue.component("component",constructor),方法中的两个参数,第一个是我们创建的组件的名称,第二个是组件的构造器,也可以将
注册和创建构造器写在一起,我们称之为语法糖:
Vue.component("my-component",{
template:'<div>hello</div>'
})
在这里将创建组件构造器的过程写在了参数列表中。这里有一个细节,规定渲染的HTML元素时,可能会添加一些属性,注意单引号和双引
号的使用。
(3)将组件挂载在某个Vue实例下。完成了创建构造器和注册自后,我们就可以规定在哪个Vue实例里面使用组件了:
Vue.component("my-component",{
template:'<div>hello</div>'
});
new Vue({
el:"#app"
});
这样我们就可以在id为app的HTML元素中使用我们的组件了。
2、局部注册和全局注册
在组件注册的过程中,使用component方法注册的组件是全局组件,在所有的Vue实例中都可以使用,但是有的时候我们并不需要一个全局的
组件,那么就可以通过components选项来注册一个局部组件:
new Vue({
el:"#app",
components:{
'my-component':{
template:'<div>hello world</div>'
}
}
});
这样我们注册的组件就一个局部组建,只能在#app中使用。
三、父组件和子组件
我们在定义了一个组件之后,在这个组件中,通过component来注册另外一个组件,并在template中使用,这样两个组件之间就构成了父子关系,
要注意的是,子组件只能被父组件使用 template:'<parent><child></child></parent>'这里如果将child写在parent外面,浏览器就会报错。
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> <script src="./vue.js"></script> </head> <body> <div id="app"> <father></father> </div> </body> <script> Vue.component('father',{ template:'<div>this is father<child></child></div>', components:{ 'child':{ template:'<div>this is child</div>' } } }); new Vue({ el:"#app" }) </script> </html>
四、将HTML和JavaScript分离
在明白了组件的注册和使用方法之后,我们要解决另外一个问题,那就是代码耦合的问题,我们可以发现,在template中我们书写了一段HTML代码,
这段代码是组件渲染的结果,但是这样就造成了HTML代码和JavaScript的高耦合性,在开发中我们提倡低耦合高内聚,所以我们要向JavaScript和HTML分离
Vue为我们提供了两个标签来解决这个问题。
1.script
将要写在template中的内容写在一个script标签中,要注意的是script的type值要改为:text/x-template,这样浏览器就不会把这段script中
的内容解析为JavaScript脚本,而是直接忽略他。
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> <script src="./vue.js"></script> </head> <body> <div id="app"> <hello></hello> </div> <script type="text/x-template" id="script"> <div>this is script</div> </script> </body> <script> Vue.component('hello',{ template:"#script" }); new Vue({ el:"#app" }) </script> </html>
2.template
跟上面的用法相似
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> <script src="./vue.js"></script> </head> <body> <div id="app"> <hello></hello> </div> <template id="template"> <div>this is template</div> </template> </body> <script> Vue.component('hello',{ template:"#template" }); new Vue({ el:"#app" }) </script> </html>
五、data选项
data选项是Vue中常用的一个选项,data中的数据会渲染到Vue实例中,但是在注册组件时要注意,data要写成函数的形式。
data:function(){
......
}
六、子组件和父组件之间的信息传递
props
我们知道,在Vue实例中,组件的作用域是孤立的,但是这并不意味之着组件与组件之间不能传递信息。在父子组件中,我们可以通过props将父组件的
数据传递给子组件。
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> <script src="./vue.js"></script> </head> <body> <div id="app"> <child v-bind:parent-message="message"></child> </div> </body> <script> new Vue({ el:"#app", data:{ message:"hello world" }, components:{ 'child':{ template:'<div>{{parentMessage}}</div>', props:['parentMessage'] } } }) </script> </html>
要注意的是,定义了props之后,在子组件中使用时一定要使用v-bind进行绑定,否则最后得到的结果就是我们赋值的字符串,而不是parent中的数据了。
props默认的绑定形式是单向绑定,也就是说父元素数据改变会影响子元素,但是子元素不能通过props改变父元素的值,但是我们可以手动的修改这一设定:
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> <script src="http://apps.bdimg.com/libs/vue/1.0.14/vue.js"></script> </head> <body> <div id="app"> <h1>父元素数据</h1> <label for="">Name</label> <div>{{name}}</div> <input type="text" v-model="name"/><br> <label for="">Age</label> <div>{{age}}</div> <input type="text" v-model="age"/> <hr> <child v-bind:my-name.sync="name" :my-age.sync="age"></child> </div> <template id="child"> <div class="child-data"> <div class="child-data-name"> <h1>子元素数据</h1> <label for="">Name</label> <div>{{myName}}</div> <input type="text" v-model="myName"/> </div> <div class="child-data-age"> <label for="">Age</label> <div>{{myAge}}</div> <input type="text" v-model="myAge"/> </div> </div> </template> </body> <script> new Vue({ el:"#app", data:{ name:'hello', age:'20' }, components:{ 'child':{ template:"#child", props:['myName','myAge'] } } }) </script> </html>
我们可以使用sync来手动的更改绑定的方式,将单项绑定改为双向绑定,但是要注意sync这个方法在Vue2.0版本中被移除了,在2.3.0+中才重新添加回来,所以使用时要注意自己的Vue.js的版本。