vue.js之组件
Vue.component 注册全局组件
基本步骤
Vue.js的组件的使用有3个步骤:创建组件构造器、注册组件和使用组件。
下面的代码演示了这3个步骤:
<div id="app">
<!-- 3. #app是Vue实例挂载的元素,应该在挂载元素范围内使用组件-->
<my-test></my-test>
</div>
<script>
// 1.创建一个组件构造器
var mytest = Vue.extend({
template:'<p>this is test1</p>'
})
// 2.注册组件,并指定组件的标签,组件的HTML标签为<my-test>
Vue.component('my-test', mytest)
//创建根实例
new Vue({
el: '#app'
})
</script>
渲染为:
我们用以下几个步骤来理解组件的创建和注册:
- Vue.extend()是Vue构造器的扩展,调用Vue.extend()创建的是一个组件构造器。
- Vue.extend()构造器有一个选项对象,选项对象的template属性用于定义组件要渲染的HTML。
- 使用Vue.component()注册组件时,需要提供2个参数,第1个参数时组件的标签,第2个参数是组件构造器。
- 组件应该挂载到某个Vue实例下,否则它不会生效。
以上组件注册的方式有些繁琐,Vue.js为了简化这个过程,提供了注册语法糖。
使用Vue.component()直接创建和注册组件:
<div id="app">
<my-test></my-test>
</div>
<script>
// 1.全局注册
Vue.component('my-test',{
template:'<p>this is test1</p>'
})
// 2.组件在注册之后必须创建根实例
new Vue({
el:'#app'
})
<script>
Vue.component()的第1个参数是标签名称,第2个参数是一个选项对象,使用选项对象的template属性定义组件模板。
使用这种方式,Vue在背后会自动地调用Vue.extend()。
必须先注册自定义组件再初始化根实例(顺序不能反,否则无效)
渲染效果与上一样~
components 注册局部组件
components 注册的组件仅在其作用域中可用
new Vue({
el:'#app',
components: {
'my-test':{
template:'<p>this is test1</p>'
}
}
})
渲染效果与上图一样
注:当使用 DOM 作为模板时 (例如,使用 el 选项来把 Vue 实例挂载到一个已有内容的元素上),你会受到 HTML 本身的一些限制,因为 Vue 只有在浏览器解析、规范化模板之后才能获取其内容。尤其要注意,像 <ul>、<ol>、<table>、<select>
这样的元素里允许包含的元素有限制,而另一些像 <option>
这样的元素只能出现在某些特定元素的内部。
例如下面代码就不会在页面渲染
<table id="app">
<test></test>
</table>
这种情况应该用 is='test'
,如下:
<table id="app">
<tr is='test'></tr>
</table>
使用script或template标签
尽管语法糖简化了组件注册,但在template选项中拼接HTML元素比较麻烦,这也导致了HTML和JavaScript的高耦合性。
庆幸的是,Vue.js提供了两种方式将定义在JavaScript中的HTML模板分离出来。
1.使用
<script>
标签
<div id="app">
<my-test></my-test>
</div>
<script type="text/x-template" id="myTest">
<p>this is test2</p>
</script>
<script>
Vue.component('my-test',{
template:'#myTest'
})
new Vue({
el: '#app'
})
</script>
template选项现在不再是HTML元素,而是一个id,Vue.js根据这个id查找对应的元素,然后将这个元素内的HTML作为模板进行编译。
注:使用<script>
标签时,type指定为text/x-template,意在告诉浏览器这不是一段js脚本,浏览器在解析HTML文档时会忽略<script>
标签内定义的内容。
2.使用
<template>
标签
如果使用<template>
标签,则不需要指定type属性。
<div id="app">
<my-test></my-test>
</div>
<template id="myTest">
<p>this is test3</p>
</template>
<script>
Vue.component('my-test',{
template:'#myTest'
})
new Vue({
el: '#app'
})
</script>
在理解了组件的创建和注册过程后,我建议使用<script>
或<template>
标签来定义组件的HTML模板。
这使得HTML代码和JavaScript代码是分离的,便于阅读和维护。
$mount()手动挂载
当Vue实例没有el属性时,则该实例尚没有挂载到某个dom中;
将vue的实例化对象通过$mount手动挂载到指定id上
<div id="app">
<my-test id="mount-point"></my-test>
</div>
<script>
// 创建构造器
var Profile = Vue.extend({
template: '<p>this is test4</p>'
})
// 创建 Profile 实例,并挂载到一个元素上。
new Profile().$mount('#mount-point')
</script>
可手动调用vm.$mount()方法来延迟挂载。例如:
<div id="mount-point">
{{a}}
</div>
<button onclick="test()">挂载</button>
<script>
var obj = {a: 1}
var vm = new Vue({
data: obj
})
function test() {
vm.$mount("#mount-point");
}
组件的el和data选项
传入Vue构造器的多数选项也可以用在 Vue.extend() 或Vue.component()中,不过有两个特例: data 和el。
Vue.js规定:在定义组件的选项时,data和el选项必须使用函数。
下面的代码在执行时,浏览器会报错
Vue.component('my-test',{
template:'#myTest',
data:{
a:'test'
}
})
另外,如果data选项指向某个对象,这意味着所有的组件实例共用一个data。
我们应当使用一个函数作为 data 选项,让这个函数返回一个新对象:
Vue.component('my-test',{
template:'#myTest',
data(){
return {
a:'test'
}
}
})