这里的下半部分包括:
1、组件中使用v-model
2、插槽的简单用法
3、访问slot
4、动态组件的使用
组件相关的上半部分博客可以点击查看:
1、组件中使用v-model
需求:通过子组件的加号按钮来给父组件传递数据
直接看例子吧
<btn-comp v-model="total"><btn-comp>
data:{
total:0
},
components:{
'btn-comp':{
template:'<div><button v-on:click="increase">+1000</button></div>',
data:function(){
return {
count: 0
}
},
methods:{
increase:function(){
this.count = this.count + 1000
this.$emit('input',this.count)
}
}
}
}
这里的v-model能绑定是因为v-model本身就是一个语法糖,每次使用v-model时都进行了两步操作:
1、先使用v-bind绑定一个value属性,这里就是先绑定了total的属性
2、再使用v-on给当前元素绑定input事件,这里就是给btn-comp绑定了一个input事件
有上面两步操作后,下面的 this.$emit(‘input’,this.count) 会自动生效
2、插槽的简单用法
用处:让父组件和子组件组合使用,弥补视图上的不足
用法:vue中实现了一个内容分发api,使用特殊的slot元素作为原始内容的插槽,slot写在子组件的template中
2.1、单个插槽
<!-- 这里绑定的isShow也是父组件的作用域,如果要子组件绑定的话直接在template里面写上,这里直接写的话不管写什么都是父组件的作用域 -->
<alone-comp v-show="isShow">
<p>我是父组件插入的内容<p>
</alone-comp>
data:{
isShow:true
},
components:{
'alone-comp':{
template: '<div><slot>如果父组件中没有插入内容,我就作为默认内容出现</slot></div>',
data:function(){
return {
isShow: false
}
}
}
}
//因为作用域的问题,这里还是会显示上面<p>标签内的文本内容
2.2、具名插槽
用法:给每个要插入的文本内容先设置要一个slot值,这些文本就可以根据slot值插到不同的地方去
<name-component>
<h4 slot="header">我是小标题</h4>
<p slot="main">我是文本的内容</p>
<p slot="footer">我是底部信息</p>
</name-component>
data:{},
components:{
'name-component': {
template: '<div>\
<div class="header">\
<slot name="header"></slot>\
</div>\
<div class="main">\
<slot name="main"></slot>\
</div>\
<div class="footer">\
<slot name="footer"></slot>\
</div>\
</div>\ '
}
}
2.3、作用域插槽
用途:从子组件中获取数据,是一个特殊的slot值,定义的时候要写上slot-scope="",里面随便写,可以写key,也可以写prop
原理:使用一个可以复用的模板来替换已经渲染的元素,这里也可以在p标签上写,2.5.0版本后可以在任意标签上写slot了
<area-component>
<template slot="area" slot-scope="key">
{{ key.text }}
</template>
</area-component>
data:{},
components:{
'area-component': {
template: '<div>\
<slot text="我是作用域插槽拿到的来自子组件的数据" name="area"></slot>\
</div>\ '
}
}
3、访问slot
方法:用 this.$slots. 后面接要访问的插槽名字
<name-component>
<h4 slot="header">我是小标题</h4>
<p slot="main">我是文本的内容</p>
<p slot="footer">我是底部信息</p>
</name-component>
data: {},
components: {
'name-component': {
template: '<div>\
<div class="header">\
<slot name="header"></slot>\
</div>\
<div class="main">\
<slot name="main"></slot>\
</div>\
<div class="footer">\
<slot name="footer"></slot>\
</div>\
</div>\ ',
//实例挂载结束后就执行这个mounted方法
mounted: function () {
//访问插槽,就是拿插槽的数据,用
var header = this.$slots.header
console.log(header)
var html = header[0].elm.innerHTML
console.log(html)
var text = header[0].elm.innerText
console.log(text)
}
}
}
4、动态组件的使用
作用:vue给我们提供了一个元素component,用来动态的挂载不同的组件
原理:通过is特性来实现的
需求:通过点击不同的按钮切换不同的视图
如果需要切换三种视图的话,就需要先定义好三个子组件
<button v-on:click="changeView('A')">A组件</button>
<button v-on:click="changeView('B')">B组件</button>
<button v-on:click="changeView('C')">C组件</button>
<!-- 这里是父作用域,所以绑定的是父组件的data,绑定is属性的时候记得用v-bind -->
<component v-bind:is="thisView"></component>
data: {
//默认当前视图是A
thisView: 'compA'
},
components: {
'compA': {
template: '<div>我是A组件</div>'
},
'compB': {
template: '<div>我是B组件</div>'
},
'compC': {
template: '<div>我是C组件</div>'
}
},
methods: {
changeView: function (tag) {
this.thisView = 'comp' + tag
}
}