组件的理解
组件的概念?
- 组件是可复用的 Vue 实例
- 组件是一个html、css、js、image等外链资源,这些部分组成的一个聚合体
- 组件的表现形式就类似一个标签
- 组件至少得有模板
- 组件应该拥有的特性:可组合,可重用,可测试,可维护
组件的优点?
- 优点:代码复用,便于维护
划分组件的原则
- 复用率高的,独立性强的
为什么组件使用必须注册
- vue.js文件中暴露出一个Vue的构造器函数, 这个函数的作用,是用来实例化出来一个实例, 那么这个实例也是一个组件, 我们称之为 ‘根实例’
- 我们从vue detools中我们发现这个实例的表现形式是一个标签
- Vue为了扩展功能, 给了一个方法 , 这个方法叫 extend
- 我们对比 Vue vs Vue.extend() 我们发现这两个方法输出结果都是两个构造器函数, 并且很相似
- 那么我们进一步得到一个结果: 使用方法一致吗?
- new Vue.extend() 报错 不需要进行实例化 , 它希望组件的表现形式应该是标签
- 要想像标签一样使用, 必须准守 h5 的标准 , 也就是说组件必须合法 , 要想合法, 必须注册(登记)
- 组件使用前必须注册
组件琐碎的知识点
-
Vue.js通过Vue.extend() 方法来扩展 组件的 使用
-
Vue.extend( options ) 里面的options参数和 Vue(options) 的options参数几乎是一致的
-
new Vue出来的 ViewModel( 视图模型 ) 也是一个组件,我们称之为 ‘根实例组件’ ,叫 ‘Root’ 组件
-
Vue中组件的表现形式是类似于标签的,要想像标签一样使用,就必须得符合 h5 的规则,也就是必须要进行组件的注册
-
组件的注册有两种形式
全局注册
格式: Vue.component(组件的名称,组件的配置项)
组件的命名规则
举例:
1. Father Hello
2. my-button
局部注册
格式:
写在组件内注册
举例:
new Vue({
componens: {
组件名: 组件配置项
}
}) -
组件必须先注册在使用
-
组件中的模板需要使用一个叫做template的配置项表示
-
组件的配置项可以简写,不需要使用 Vue.extend(options),可以直接将options写在组件的注册中
-
template组件中有且仅有一个根元素
-
组件使用时有规则的:
比如特殊的一些标签: ul li ol li table tr td dl dt dd select option …这类型标签,是规定了它们的直接子元素,当我们将组件写入这类型标签的时候,就会发现有问题
解决: 在直接子元素身上,通过 is 属性来 绑定 一个组件
举例:<table> <tr> <td>1</td> <td>2</td> <td>3</td> </tr> <!-- <Hello></Hello> 这么写有问题--> <tr is = "Hello"></tr> </table>
-
组件嵌套
全局注册:
要将子组件的组件名写在父组件的template中
局部注册
组件的注册
全局的注册
- 全局注册的书写形式
<div id="app">
<!-- 注意标签不能大写,最好是组件名大写,标签是小写加横杠 -->
<my-component></my-component>
</div>
<div id='app1'>
<my-component></my-component>
</div>
- 组件的构造器的书写(组件的配置项)
Vue.extend({
template: 模板,
data(){},
mthods: {},
watch: {},
computed:{}
})
//组件的构造器,完成组件的配置
var HelloComponent= Vue.extend({
template :'<div>全局注册组件</div>',//模板,必须有
data(){
return {
msg:000,
}
}//可以不写,data在这里是一个函数,有return值
//此处省略好几处配置项
})
//组件的注册 Vue.component(组件名,组件的配置项) // 名字可以取一样的
Vue.component('MyComponent',HelloComponent)
new Vue({
el:'#app',
})
new Vue({
el:'#app1',
})
- 全局注册的简写形式
<div id="app">
<!-- 注意标签不能大写,最好是组件名大写,标签是小写加横杠 -->
<my-component></my-component>
</div>
<div id="app1">
<my-component></my-component>
</div>
//组件的注册 Vue.component(组件名,组件的配置项) // 名字可以取一样的
Vue.component('MyComponent',{
template :'<div>全局注册组件</div>' //Vue会自动的将此对象给Vue.extend
})
new Vue({
el:'#app',
})
new Vue({
el:'#app1',
})
局部的注册
- 局部注册的书写形式
<div id="app">
<my-component></my-component>
</div>
<div id="app1">
<!-- 无结果显示 -->
<my-component></my-component>
</div>
var HelloComponent= Vue.extend({
template :'<div>局部注册组件</div>',//模板,必须有
})
new Vue({
el:'#app',
components:{
'MyComponent':HelloComponent
}
})
new Vue({
el:'#app1',
})
- 局部注册的简写形式
<div id="app">
<my-component></my-component>
</div>
new Vue({
el:'#app',
components:{
'MyComponent':{
template :'<div>局部注册组件</div>',//模板,必须有
}
}
})
组件命名的建议的两种形式
使用 kebab-case
举例
Vue.component('header-title',{})
使用 PascalCase
举例:
Vue.component('MyComponentName', { /* ... */ })
解释: 为什么要是上面两种写法 ? 为了区别html的原生标签
组件的嵌套
组件的全局嵌套
- 组件的全局嵌套的一种形式
<div id="app">
<father></father>
</div>
Vue.component('Father',{
template:'<div>父组件<son></son></div>'
})
Vue.component('Son',{
template:'<div>子组件</div>'
})
new Vue({
el:'#app',
})
- 组件的全局嵌套的另外一种形式(template的模板形式)
<div id="app">
<father></father>
</div>
<template id="father">
<div>
<h3>这是父组件</h3>
<son></son>
</div>
</template>
<template id="son">
<div>
<h4>这是子组件</h4>
</div>
</template>
Vue.component('Father',{
template:'#father'
})
Vue.component('Son',{
template:'#son'
})
new Vue({
el:'#app',
})
组件的局部嵌套(子组件必须在父组件中注册之后才能在父组件的模板中使用)
- 组件的局部嵌套的一种形式
<div id="app">
<father></father>
</div>
new Vue({
el:'#app',
components:{
Father:{
template: '<p>这是父组件 <son></son></p>',
components:{
Son:{
template:'<p>这是子组件</p>'
}
}
}
}
})
- 组件的局部嵌套的另一种形式(template模板)
<div id="app">
<father></father>
</div>
<template id="father">
<div>
这是父组件(template)
<son></son>
</div>
</template>
<template id="son">
<div>
这是子组件(template)
</div>
</template>
new Vue({
el:'#app',
components:{
Father:{
template: '#father',
components:{
Son:{
template:'#son'
}
}
}
}
})
组件的template
- 组件的template如果body里面的话,一定记住要放在 #app 的div外
- 组件的template在body中使用的话, 是不会解析的, 但是组件内的template是会解析的
- 组件的模板中的直接子元素必须有一个, 如果你要有多个, 必须使用v-if v-else-if
- 有唯一根元素
<div id="app">
<Hello></Hello>
</div>
<template id="Hello">
<div>
<div> 这是hello 组件的template </div>
<div> 这是hello 组件的template </div>
<div> 这是hello 组件的template </div>
<div> 这是hello 组件的template </div>
</div>
</template>
Vue.component('Hello',{
template: '#Hello'
})
new Vue({
el: '#app',
})
组件的使用规则(is的使用)
- 比如特殊的一些标签: ul li ol li table tr td dl dt dd select option …这类型标签,是规定了它们的直接子元素,当我们将组件写入这类型标签的时候,就会发现有问题
- 解决: 在直接子元素身上,通过 is 属性来 绑定 一个组件
- 问题代码
<div id="app">
<ul>
<li>1</li>
<li>2</li>
<hellois></hellois>
</ul>
</div>
<template id="li">
<li>
3
<p>组件里面的li</p>
</li>
</template>
new Vue({
el:'#app',
components:{
helloIs:{
template:'#li'
}
}
})
- 解决的代码
<div id="app">
<ul>
<li>1</li>
<li>2</li>
<li is='hello-is'></li>
</ul>
</div>
<template id="li">
<li>
3
<p>组件里面的li</p>
</li>
</template>
new Vue({
el:'#app',
components:{
helloIs:{
template:'#li'
}
}
})
:is的使用(补充不完整)
- 这个是在动态组件上面表示的,组件身上可以绑定一个is属性, 用来表示某一个组件
组件中data的使用
- 根实例中的data选项是一个对象, 但是组件中的data选项是一个函数, why?
- 解释:
函数的作用:- 函数有独立作用域
- 函数可以有return 返回值 ,
- 组件的data选项必须有return 返回值, 并且返回值是一个对象
- 组件的数据在组件的模板中使用
<div id="app">
<hello-component></hello-component>
</div>
<template id="helloComponent">
<div>
{{msg}}
</div>
</template>
new Vue({
el:'#app',
components:{
helloComponent:{
template:'#helloComponent',
data(){
return {
msg:'这是组件里面的数据'
}
}
}
}
})