组件使用的3个步骤:
1.创建组件构造器(调用Vue.extend()方法)
const cpnC = Vue.extend({
template:`
<div>
<h2>我是标题</h2>
<p>我是内容</p>
</div>
`
})
2.注册组件(调用Vue.component()方法)
Vue.component('cpn',cpnC) //全局组件
const app=new Vue({
el:'#app',
data:{
message:'Hello'
},
components:{ //局部组件
cpn:cpnC
}
})
3.使用组件(在Vue实例的作用范围内使用组件)
全局组件(通过调用Vue.component()注册的组件):组件可以在任意Vue实例下使用
局部组件(挂载在某个实例中):只能在此实例中使用
注册组件语法糖
省去Vue.extend()步骤,直接使用一个对象来代替。
组件模板抽离的写法
<!--1.script标签,类型必须是text/x-template-->
<script type="text/x-template" id="cpn">
<div>
<h2>我是标题</h2>
<p>我是内容</p>
</div>
</script>
Vue.component('cpn',{
template:'#cpn'
})
<!--2.template标签-->
<template id="cpn">
<div>
<h2>我是标题</h2>
<p>我是内容</p>
</div>
</template>
Vue.component('cpn',{
template:'#cpn'
})
组件中的数据存放:
组件对象也有data,methods属性,data属性必须是一个函数,而且这个函数返回一个对象,对象内部保存着数据。
Vue.component('cpn',{
template:'#cpn',
data(){
return{
title:'abc'
}
}
})
父子组件的通信
- 通过props向子组件传递数据
- 通过事件向父组件发送消息(自定义事件)
真实开发中,Vue实例和子组件的通信和父组件和子组件的通信过程是一样的
(1)props基本用法
在组件中,使用选项props来声明需要从父级接收到的数据。
props的值有两种方式:
方式一:字符串数组 ,数组中的字符串就是传递的名称。
方式二:对象,对象可以设置传递时的类型,也可以设置默认值等。
类型验证支持的数据类型:
string,number,boolean,array,object,date,function,symbol
(2)子级向父级传递:自定义事件
自定义事件的流程:
在子组件中,通过$emit()来触发事件;在父组件中,通过v-on来监听子组件事件。
父子组件访问:
父组件访问子组件:使用$children或$refs (reference引用)
子组件访问父组件:使用$parent
子组件访问根组件:使用$root
组件插槽slot
目的:对组件的扩展,通过slot插槽向组件内部指定位置传递内容
封装方式:将共性抽取到组件中,将不同暴露为插槽。
<!--
1.插槽的基本使用 <slot></slot>
2.插槽的默认值 <slot><button>按钮</button></slot>
3.如果有多个值同时放入到组件进行替换时,一起作为替换元素
-->
具名插槽
组件中有多个命名的slot 插槽时,可以实现父组件对子组件的指定位置显示内容或传参
<cpn><span slot="center">插槽</span></cpn>
<template id="cpn">
<div>
<slot name="left"><span>左边</span></slot>
<slot name="center"><span>中间</span></slot>
<slot name="right"><span>右边</span></slot>
</div>
</template>
编译作用域
父组件模板的所有东西都会在父级作用域内编译;子组件模板的所有东西都会在子级作用域内编译。
作用域插槽
父组件替换插槽的标签,但是内容由子组件来提供。