前言
- 组件( Component )是 Vue.js 最核心的功能,也是整个框架设计最精彩的地方,当然也是最难掌握的。
- 接下来会由浅入深地学习组件的全部内容,并通过几个案例练习熟练使用 Vue 组件。
- 正式讲解组件前,先看个场景,了解下为什么学习组件?
场景举例
- 有人会问:为什么学习组件,作用是什么?接下来看个场景
- 产品经理:现在需求升级了,这几个控件还有别的地方要用到。
- 程序员:没问题,复制粘贴呗。
- 产品经理:要求输入框要带数据验证,按钮的图标支持自定义
- 程序员:这样吧,用 JavaScript 封装后一起复制吧。
- … …等到项目快完结,后期项目交接前两天
- 产品经理:所有使用输入框的地方,都要改成支持回车键提交。
- 程序员:好吧,给我一天的时间,加班一个一个加上去。
- 上面的需求虽然有点变态,但却是业务中很常见的,那就是一些控件、 JavaScript 功能的复用。
- 没错, Vue.js的组件就是提高重用性的,让代码可复用,当学习完组件后,上面的问题就可以轻松搞定了,再也不用害怕产品经理的奇随需求。
组件注册
- 回顾下创建 Vue 实例的方法:

- 组件Component与之类似,需要注册后才可以使用。注册有全局注册和局部注册两种方式。
- ①全局组件:任何Vue 实例都可以使用
- ②局部组件:只有在该实例作用域下有效(对比全局与局部变量记忆)
组件注册-全局
全局注册组件语法:

- my-component就是注册的组件自定义标签名称,推荐使用小写加减号分割的形式命名(即kebab-case短横线分隔命名法,此外还有PascalCase首字母大写命名即大驼峰法)。
- 要在父实例中使用这个组件,必须要在实例创建前注册,之后就可以用<组件名></组件名>形式来使用组件了

- 此时打开页面还是空白的,因为注册的组件没有任何内容,在组件选项中添加 template(模板)就可以显示组件内容了。
- 示例代码如下

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>全局组件注册</title>
<script src="../js/vue-2.6.9.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<!--/3、通过自定义组件调用组件名 -->
<my-component></my-component>
<my-component2></my-component2>
<!-- HTML里面获取Vue大驼峰获取不到 会报错 -->
<!-- HTML对大小写不敏感 大写会自动转换为小写 -->
</div>
</body>
<script type="text/javascript">
/*全局注册组件时,需要在实例化之前,否则报错*/
/*组件注册-全局*/
/*全局注册的组件可以用在任何Vue 根实例 (new Vue) 的模板中*/
// 1、注册组件component并命名
Vue.component('my-component',{
/*字符串模板*/
//2、 添加模板tempalte内容
template:`
<div>
我是全局组件
<button>发送</button>
</div>`,
/*必须用div包裹,否则会报错*/
});
Vue.component('my-component2',{
/*字符串模板*/
//2、 添加模板tempalte内容
template:`
<div>
我是全局组件2
<button>发送</button>
</div>`,
/*必须用div包裹,否则会报错*/
});
/*实例化Vue*/
var app = new Vue({
el:'#app',
})
</script>
</html>
-
全局组件注册步骤小结:
-
①注册组件component并命名
-
②添加模板template内容
-
③通过自定义组件名调用组件
-
template模板语法要求:
-
template的 DOM 结构必须被一个元素包含, 如果直接写成 “这里是组件的内容”,不带
“<div></div>”等根元素是无法渲染的。

-
组件命名
-
定义组件名的方式有两种:kebab-case和PascalCase
-
(1)kebab-case短横线分隔命名

-
当使用 kebab-case (短横线分隔命名) 定义一个组件时,你也必须在引用/调用这个自定义元素时使用 kebab-case,例如
<my-component-name>。

-
(2)PascalCase首字母大写命名即大驼峰

-
当使用 PascalCase (首字母大写命名)
定义组件,在html文档里引用时必须使用kebab-case短横线分隔命名才生效,否则报错(原理:HTML对大小写不敏感、JS对大小写敏感)。 -
因此,文档引用时为

组件注册-局部
- 在Vue 实例中,使用 components选项可以局部注册组件,注册后的组件只有在该实例作用域下有效。
- 组件中也可以使用components 选项来注册组件,使组件可以嵌套。

- ①直接绑定
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>局部组件注册</title>
<script src="../js/vue-2.6.9.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="demo">
<my-component></my-component>
<my-last></my-last>
</div>
</body>
<script type="text/javascript">
/*组件components添加模板component有两种方式*/
/*注意:局部组件只有在当前实例作用域下有效*/
/*1、组件注册-局部 (直接绑定)*/
var app = new Vue({
el:'#demo',
components:{
'my-component':{
template:`<div style='color:red'>我是局部组件</div>`
},
'my-last':{
template:`<div style='color:red'>我是局部组件2</div>`
}
}
})
</script>
</html>
- ②指向模板对象
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>局部组件注册</title>
<script src="../js/vue-2.6.9.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="arr">
<my-component></my-component>
</div>
</body>
<script type="text/javascript">
/*组件components添加模板component有两种方式*/
/*注意:局部组件只有在当前实例作用域下有效*/
/*2、组件注册-局部 (指向模板对象) 不推荐使用*/
var array = {
template:`<div style='color:green'>我是局部组件</div>`
}
var app = new Vue({
el:'#arr',
components:{
'my-component':array
}
})
</script>
</html>
由上例可以看出,组件components添加模板component有两种方式

全局VS局部
- 全局注册组件通过Vue.component语法,全局注册的组件可以用在任何Vue 根实例 (new Vue) 的模板中。

- 全局注册有时是不够理想,例如即便你已经不再使用一个组件了,它仍然会被包含在最终的构建结果中,影响性能。
- 注意:局部组件只有在当前实例作用域下有效

- 局部组件也可以同时注册多个,引用时一一对应即可

组件嵌套

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>全局组件注册</title>
<script src="../js/vue-2.6.9.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<!-- 块级类文本标签可以嵌套块级类文本标签 -->
<div id="app">
<!--/3、通过自定义组件调用组件名 -->
<my-component></my-component>
<!-- HTML里面获取Vue大驼峰获取不到 会报错 -->
<!-- HTML对大小写不敏感 大写会自动转换为小写 -->
</div>
</body>
<script type="text/javascript">
/*全局注册组件时,需要在实例化之前,否则报错*/
/*组件注册-全局*/
/*全局注册的组件可以用在任何Vue 根实例 (new Vue) 的模板中*/
// 1、注册组件component并命名
Vue.component('my-component',{
/*字符串模板*/
//2、 添加模板tempalte内容
template:`
<p>
<my-component2></my-component2>
</p>`,
/*必须用div包裹,否则会报错*/
});
Vue.component('my-component2',{
/*字符串模板*/
//2、 添加模板tempalte内容
template:`
<p>
我是全局组件2
<button>发送</button>
</p>`,
/*必须用div包裹,否则会报错*/
});
/*实例化Vue*/
var app = new Vue({
el:'#app',
})
</script>
</html>
(1)注册引用步骤
- ①全局组件:在创建实例前注册,注册后即可直接引用

- ②局部组件:在components选项内注册

(2)作用域 - 全局组件:全局都可以直接引用
- 局部组件:只有在当前实例作用域下有效
HTML文档限制||DOM解析限制
问题:
- Vue组件模板在某些情况下会受到 HTML
的限制,比如内规定只允许是、、 等表格元素,所以内直接使用组件是无效的

方案:可以使用特殊的is属性来挂载组件。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>全局组件注册</title>
<script src="../js/vue-2.6.9.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<!-- 块级类文本标签可以嵌套块级类文本标签 -->
<div id="app">
<table border="" cellspacing="" cellpadding="">
<tbody is='my-component'></tbody>
</table>
<my-component></my-component>
</div>
</body>
<script type="text/javascript">
Vue.component('my-component', {
template: `
<p>
<my-component2></my-component2>
</p>`,
});
/*实例化Vue*/
var app = new Vue({
el: '#app',
})
</script>
</html>
解析 DOM 模板时的注意事项
- 需要注意的是如果从以下来源使用模板的话,HTML文档限制是不存在的:
- ①组件字符串模板 (例如:template:
...) - ②单文件组件 (.vue),后序课程工程化讲解
- ③
<script type="text/x-template">,关于字符串模板,下节做介绍。
- ①组件字符串模板 (例如:template:
组件选项-data数据项
- 除了 template 模板选项外,组件中还可以像 Vue 实例那样使用其他的选项,比如 computed、methods 等。
- 但是在使用 data 和实例稍有区别, 组件的data必须是函数,且必须将数据 return出去。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>全局组件注册</title>
<script src="../js/vue-2.6.9.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<my-component></my-component>
</div>
</body>
<script type="text/javascript">
Vue.component('my-component', {
template: `
<div @click="show">
{{info}}
</div>`,
data: function() {
return {
info: '组件内容'
}
},
methods: {
show() {
alert(56465465546)
}
}
});
/*实例化Vue*/
var app = new Vue({
el: '#app',
})
</script>
</html>
组件选项-数据选项与复用
- JS对象是引用关系,所以如果return出的对象引用了外部的一个对象,那这个对象就是共享的,任何一方修改都会同步,如下所示。
- (引用关系,会产生浅拷贝,互相影响)

- 组件使用了3次,但是点击任意, 3个的按钮的数字都会+1 ,这是因为组件 data引用的是外部的对象。
- 这肯定不是我们期望的效果,所以接下来给组件返回一个新的data 对象来独立

这样,点击每个按钮就互不影响了,完全达到复用的目的。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>全局组件注册</title>
<script src="../js/vue-2.6.9.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<my-component></my-component>
<my-component></my-component>
<my-component></my-component>
<my-component></my-component>
<my-component></my-component>
</div>
</body>
<script type="text/javascript">
Vue.component('my-component', {
template: `
<button @click="count++">
点击{{count}}
</button>`,
data: function() {
return {
count: 0
}
},
methods: {
show() {
alert(56465465546)
}
}
});
/*实例化Vue*/
var app = new Vue({
el: '#app',
})
</script>
</html>
- 当点击按钮时,每个组件都会各自独立维护它的 count。因为每用一次组件,就会有一个它的新实例被创建。
总结
- 总结:
- (1)注册位置:全局组件必须在实例化之前注册,局部组件需要在components选项内注册。
- (2)作用域:全局组件:全局都可以直接引用;局部组件:只有在当前实例作用域下有效。
- (3)HTML文档限制:组件模板在某些情况下会受到 HTML 的限制,使用特殊的is属性来挂载组件。
- (4)除了 template 模板选项外,组件中还可以像 Vue 实例那样使用其他的选项,比如 computed、methods
等。但是在使用 data 和实例稍有区别, 组件的data必须是函数,且必须将数据 return出去。 - (5)组件复用:可以将组件进行任意次数的复用。
- (6)data选项再次强调:组件的data 并不是像原来一样直接提供一个对象,取而代之的是,一个组件的 data
选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝 - (7)因为组件是可复用的 Vue 实例,所以它们与 new Vue 接收相同的选项,例如
data、computed、watch、methods 以及生命周期钩子等。仅有的例外是像 el 这样根实例特有的选项。
以上就是小编对VUE之组件(基础、分类、命名)的见解,如有疑问请随时联系小编!

本文深入探讨Vue.js的组件系统,包括组件的基础知识、全局与局部注册、命名规范以及HTML文档限制。组件是Vue.js的核心,提高了代码的复用性和可维护性。文章详细介绍了如何注册全局和局部组件,组件命名的kebab-case和PascalCase两种方式,以及组件嵌套和数据独立性的重要性。最后,总结了组件注册的位置、作用域、HTML限制和数据选项的使用要点。
877

被折叠的 条评论
为什么被折叠?



