(1) 组件能够扩大 HTML 元素,外部封装了能够复用的 HTML、CSS、JS 代码片段。(2) 因为组件是可复用的 Vue 实例,所以它们与 new Vue 接管雷同的选项,例如 data、computed、watch、methods 以及生命周期钩子等。仅有的例外是像 el 这样根实例特有的选项。(3) 组件相似于 vue 实例,组件外部有 template 属性,用于指定模板。vue 实例外部有 el 属性,用于指定模板。
(1) 组件能够进行任意次数的复用
(2) 组件的 data 必须是一个函数,确保每个实例能够保护一份被返回对象的独立的拷贝,也就是任何一个组件的扭转不会影响到其余组件。
let component = {data() {
return {
// 返回对象值的惟一拷贝,保障复用的组件外部数据不会相互影响
msg: "我是组件的数据"
}
},
template: `
<div>
<p> 我是组件 </p>
<h1>{{msg}}</h1>
</div>
`
}
(1) 全局注册的组件,能够在任意 vue 实例或者组件外部应用
(2) 部分注册的组件,只能在以后注册的实例或者组件外部应用
(3) 相似于 js 中的全局变量、局部变量
1、全局注册
Vue.component('my-com', component);
如果一个组件被多个其余组件调用,用全局注册较好。2、部分注册
如果一个组件在一个实例或者组件外部被屡次调用,用部分注册较好。new Vue({
el: "#app",
data: {},
components: {"my-com": component}
})
(1) 父组件向子组件传参
父组件应用 prop 属性,向子组件传参。<div id="app">
<my-com :title="title" msg="hello"></my-com>
</div>
动静传参
没有:传递的常量字符串
有:传递 boolean, number, 对象, 数组, 变量
子组件接管参数
let component = {props: ["title", "msg"]
}
props 校验
let component = {
props: {
title: {
type: String, // 验证数据类型
required: true, // 该参数必须传递的参数
// 根本数据类型间接写在 default 前面
default: "你好", // 以后参数的默认值
// 援用数据类型,应用工厂函数的模式返回一个对象或者数组
default(){return {}
}
validator(val){
// 自定义的验证器
return val.lenth > 3 ;
}
}
}
}
(2) 子组件向父组件传参
<div id="app">
<my-com @son-handler="fatherHandler" msg="hello"></my-com>
</div>
let component = {data(){
return {comMsg: "我是子组件数据"}
},
template:`
<div>
<button @click="clickHandler"> 发送事件 </button>
</div>
`,
methods: {clickHandler(){clickHandler(){this.$emit("son-handler", this.comMsg)
}
}
}
}
new Vue({
el: '#app',
data: {fatherDate: ''},
methods: {fatherHandler(val){
//val 就是子组件发送事件时,携带的参数 this.comMsg
this.fatherDate = val
}
},
components: {myCom: component}
})
(3) 单向数据流
父级的 prop 数据的更新,会向下流动到子组件中,反过来不行
父组件可能批改子组件中的数据,而子组件不能间接批改父组件中的数据
作用:避免子组件意外变更状态,会影响父组件中的状态或者数据。
(1) 一般插槽
<my-com> hello vue </my-com>
let com = {
template: `
<div>
<slot></slot> // 默认插槽
</div>
`
}
(2) 具名插槽
<my-com>
<template v-slot:header>
我是头部内容
</template>
<template v-slot:default>
<p> 你好组件插槽 </p>
</template>
<template v-slot:footer>
我是脚步内容
</template>
</my-com>
let com = {
template: `
<div>
<header><slot name="header"></slot></header> // 具名插槽
<main> <slot name="default"></slot > </main> // 匿名插槽
<footer> <slot name="footer"> </slot> // 具名插槽 </footer>
</div>
`
}
(3) 作用域插槽
<my-com>
<template v-slot:header="scope">
{{scope.msg}} //scope 是作用域对象,外部封装了子组件传递上来的 msg 数据,能够应用对象的解构
我是头部内容
</template>
<template v-slot:default>
<h3> 你好组件插槽 </h3>
</template>
<template v-slot:footer> 我是脚步内容
</template>
</my-com>
let com = {data(){
return {msg: "我是组件数据"}
},
template: `
<div>
<header><slot name="header" :msg="msg"></header>
</div>
`
}
(1) 动态组件
<component is="my-com1"><component>
(2) 动静组件
<component :is="current"></component>