组件 (Component) 是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码。在较高层面上,组件是自定义元素,Vue.js 的编译器为它添加特殊功能。在有些情况下,组件也可以表现为用 is
特性进行了扩展的原生 HTML 元素。
所有的 Vue 组件同时也都是 Vue 的实例,所以可接受相同的选项对象 (除了一些根级特有的选项) 并提供相同的生命周期钩子。
举个例子
<html> <head> <title>Vue组件</title> <script src="vue.js"></script> <style type="text/css"> </style> </head> <body> <div id="example"> <my-greet></my-greet> <my-greet></my-greet> <my-greet></my-greet> </div> <script> // 编写组件 Vue.component("my-greet", { template:"<p>你好啊!欢迎你来看我的博客</p>" }) new Vue({ el:"#example" }) </script> </body> </html>
my-greet就是vue组件扩展出来的HTML元素,当我需要打招呼我就可以多次执行<my-greet></my-greet>而不是一遍遍的写它这就是封装可重用的代码
使用组件
我们已经知道,可以通过以下方式创建一个 Vue 实例:
new Vue({
el:"#example"
})
要注册一个全局组件,可以使用 Vue.component(tagName, options)
。例如
// 编写组件 Vue.component("my-greet", { template:"<p>你好啊!欢迎你来看我的博客</p>" })
tagName就是你的组件名称如greet组件
options就是你的选项
请注意,对于自定义标签的命名 Vue.js 不强制遵循 W3C 规则 (小写,并且包含一个短杠),尽管这被认为是最佳实践。
组件在注册之后,便可以作为自定义元素 <my-greet></my-greet>
在一个实例的模板中使用。注意确保在初始化根实例之前注册组件:
1 <div id="example"> 2 <my-greet></my-greet> 3 <my-greet></my-greet> 4 <my-greet></my-greet> 5 </div>
1 <script> 2 // 编写组件 3 Vue.component("my-greet", { 4 template:"<p>你好啊!欢迎你来看我的博客</p>" 5 }) 6 new Vue({ 7 el:"#example" 8 }) 9 </script>
渲染为:
1 <div id="example"> 2 <p>你好啊!欢迎你来看我的博客</p> 3 <p>你好啊!欢迎你来看我的博客</p> 4 <p>你好啊!欢迎你来看我的博客</p> 5 </div>
局部注册
1 你不必把每个组件都注册到全局。你可以通过某个 Vue 实例/组件的实例选项 components 注册仅在其作用域中可用的组件:
1 <div id="example-1"> 2 <greet></greet> 3 <greet></greet> 4 <child></child> 5 </div> 6 <div id="example-2"> 7 <p>------------------</p> 8 <greet></greet> 9 <child></child> 10 <child></child> 11 </div>
1 var child = { 2 template:"<p>Hello Vue.js</p>" 3 4 }
// 全局组件 5 Vue.component("greet", { 6 template:"<p>你好啊Vue</p>" 7 8 }) 9 10 new Vue({ 11 el:"#example-1", 12 }) 13 14 new Vue({ 15 el:"#example-2", 16 // 局部组件 17 components:{ 18 'child':child 19 } 20 })
浏览器打开显示:
局部组件挂载到了example-2中所以只能在example-2中使用,在example-1是不起作用的
而全局组件在两者内都可以使用
DOM 模板解析注意事项
当使用 DOM 作为模板时 (例如,使用 el
选项来把 Vue 实例挂载到一个已有内容的元素上),你会受到 HTML 本身的一些限制,因为 Vue 只有在浏览器解析、规范化模板之后才能获取其内容。尤其要注意,像 <ul>
、<ol>
、<table>
、<select>
这样的元素里允许包含的元素有限制,而另一些像 <option>
这样的元素只能出现在某些特定元素的内部。
在自定义组件中使用这些受限制的元素时会导致一些问题,例如:
<table>
|
自定义组件 <my-row>
会被当作无效的内容,因此会导致错误的渲染结果。变通的方案是使用特殊的 is
特性:
<table> <tr is="my-row"></tr> </table>
以上的意思大概就是
html标签结构是有一定的规范的,打个不恰当的比方,就好像抽屉,一般是放书文件的,往里面放土种花。是不是觉得很奇怪呢?文档里面说的是一些结构标签例如: <ul> <li></li> ... </ul> 这个是ul的标准结构,ul下面是li,不要写成: <ul> <my-li></my-li> </ul> 因为这样不符合html规范,在文档里面提到的一些标签,在里面写自定义标签,会不能显示,或显示错误的情况,应该写成: <ul> <li is="my-li"></li> </ul> 这个是标签的结构规范。
应当注意,如果使用来自以下来源之一的字符串模板,则没有这些限制:
<script type="text/x-template">
- JavaScript 内联模板字符串
.vue
组件
因此,请尽可能使用字符串模板。
这句话意思是:
这样不可以
<body>
<div id="app">
<select>
<optioncomp></optioncomp>
</select>
</div>
<script src="lib/vue.js"></script>
<script>
new Vue({
el: '#app',
components:{
'optioncomp':{
template: '<option >a</option>'
}
}
})
</script>
</body>
但是用is特殊属性可以:
<body>
<div id="app">
<select>
<option is="optioncomp"></option>
</select>
</div>
<script src="lib/vue.js"></script>
<script>
new Vue({
el: '#app',
components:{
'optioncomp':{
template: '<option >a</option>'
}
}
})
</script>
</body>
或者temp模板标签也可以
<body>
<div id="app">
<select>
<option is="optioncomp"></option>
</select>
<!--模板内容存放区域-->
<script type="x-template" id="optioncompTemp">
或者内联模板字符串也行
<body>
<div id="app">
<selectcomp></selectcomp>
</div>
<script src="lib/vue.js"></script>
<script>
Vue.component('optioncomp',{
template: '<option >a</option>'
});
new Vue({
el: '#app',
components:{
'selectcomp':{
template: ' <select> <optioncomp></optioncomp></select>'
}
}
})
</script>
</body>
当然了,单页应用的组件文件xxx.vue更是没问题了,就不演示了