子组件
在定义组件时可以在组件内部注册子组件,这样在修改代码时只需要修改对应的子组件部分即可,不需要修改整体代码,影响整体的结构
定义子组件需要在组件内部使用components属性,一般父组件全局注册,父组件内部的子组件局部注册(避免与其它全局组件产出冲突)
实例
<body>
<div id="app">
<book-box></book-box>
</div>
<script type="text/javascript">
var bookTitle = {
props: ['item'],
template: '<h1>{{item.title}}</h1>'
}
var bookAuthor = {
props: ['item'],
template: '<h3>{{item.author}}</h3>'
}
var bookInfo = {
props: ['item'],
template: '<p>{{item.info}}</p>'
}
Vue.component('book-box', {
data: function() {
return {
item: {
title: '大道朝天',
author: '猫腻',
info: '做了人类想成仙,生在地上要上天——鲁迅。'
}
}
},
components: {
'book-title': bookTitle,
'book-author': bookAuthor,
'book-info': bookInfo
},
template: `
<div>
<book-title :item="item"></book-title>
<book-author :item="item"></book-author>
<book-info :item="item"></book-info>
</div>
`
})
new Vue({
el: '#app',
data: {}
})
</script>
</body>
插槽
基本插槽
基本组件是这样的
<blog-post></blog-post>
带有插槽的组件是这样的
<blog-post>
插槽内容
</blog-post>
实例:
<div id="app">
<blog-post message="插槽"></blog-post>
<blog-post message="插槽">
插槽内容在这里
</blog-post>
</div>
<script type="text/javascript">
Vue.component('blog-post',{
template:`
<div>
<p>{{message}}</p>
<slot></slot>
</div>
`,
props:['message']
})
new Vue({el:'#app'})
</script>
在组件标签内的内容,会在插槽位置显示。插槽可以理解为一个占位符。在上面的实例中,内容"插槽内容在这里",会替代<slot>标签的位置
为插槽设置默认值
<slot>默认内容</slot>
如果添加了插槽并设置了默认内容时,如果没有在标签内部添加内容,插槽位置会显示默认值;如果标签内部添加内容,插槽位置内容将会被替换
具名插槽
实例
<div id="app">
<blog-post>
<p slot="herader">我是具名插槽的头部</p>
<p>我是具名插槽的内容区</p>
<p slot="footer">我是具名插槽的尾部</p>
</blog-post>
</div>
<script type="text/javascript">
Vue.component('blog-post', {
template: `
<div>
<slot name="default"></slot>
<slot name="herader"></slot>
<slot name="footer"></slot>
</div>
`
})
new Vue({
el: '#app'
})
</script>
说明:
- 具名插槽就是给插槽添加一个name属性,根据name属性的值进行一一对应
- 内容的位置与模板中solt标签的位置有关
- name属性为default时表示默认值,name属性可以省略。这时所有没有表示的内容都会在这里显示
- 除了使用solt外也可以使用v-slot,v-slot可以简写为#(有参数时)
<p slot="herader">我是具名插槽的头部</p>
等价于
<p v-slot:herader>我是具名插槽的头部</p>
等价于
<p #herader>我是具名插槽的头部</p>
带有 slot-scope 属性的作用域插槽
该属性主要用于父组件通过props属性向子组件传参时使用
实例:
<div id="app">
<blog-post>
<template slot="default" slot-scope="userInfo">
<p>{{userInfo.name}}</p>
<p>{{userInfo.age}}</p>
{{userInfo}}
</template>
</blog-post>
</div>
<script type="text/javascript">
Vue.component('blog-post', {
template: `
<div>
<slot name="default"></slot>
</div>
`
})
new Vue({
el: '#app',
data: {
userInfo: {
name: '张三',
age: 18
}
}
})
</script>
注:新版本中推荐使用v-slot来代替slot和slot-scope。上面的可以写成这种形式
<template v-slot:default="userInfo"> //指定插槽名,绑定要使用的数据
<p>{{userInfo.name}}</p>
<p>{{userInfo.age}}</p>
{{userInfo}}
</template>
使用render渲染组件(了解)
格式:
render: function(createElements) {
return createElements(组件)
}
- createElements是一个方法,调用它可以将指定的组件模板渲染为html结构
- return的结果会替换页面中el指定的容器,原本容器中的东西也会被清除
实例
<div id="app"></div>
<script type="text/javascript">
var hh = {
template: '<h2>我是h2标签</h2>'
}
new Vue({
el: '#app',
render: function(createElements) {
return createElements(hh)
}
})
</script>