前言:这次的笔记主要记下组件的父子通信
父子组件的通信
我们知道,子组件是不能引用父组件或者vue实例里的数据的。但是,在开发中,如果我们从服务器上请求了很多的数据,且想要一部分数据在子组件里进行展示,这个时候,并不会让子组件再发送一个请求到服务器,而是直接让大组件(父组件)将数据传递给小组件(子组件)。所以vue给我们提供了父子组件之间数据传递的方法。
一、父组件向子组件传递数据
通过 props 向子组件传递数据。
在组件中,使用props选项来声明需要从父级接收到的数据
(关键:在使用时用v-bind传值)
- 方法一:字符串数组,数组中的字符串是传递时的名称
- 方法二:对象,对象可以设置传递时的类型,也可以设置默认值等
<div id="app">
<!-- 这里使用v-bind相当于把父组件和子组件搭了个桥梁-->
<cpn v-bind:myballs="balls" :mymessage="message"></cpn>
</div>
<template id="mycpn">
<div>
{
{myballs}}
{
{mymessage}}
</div>
</template>
<script>
//创建一个组件 父传子:props
const cpn ={
template:"#mycpn",
//这里使用了字符串数组的方式
props:['myballs','mymessage'] //这里的myballs和mymessage是变量
//第二种方式:使用对象,可以设置类型
props:{
myballs:Array, //一定要写类型,不然会报错
mymessage:{
//也可以这样写,提供一个默认值
type:String,
default:"好好学习"//默认值在没有被v-bind绑定时会显示
required:true //必传值,就是要使用v-bind,会与默认值产生矛盾
}
}
}
//创建一个vue实例
const app = new Vue({
el:"#app",
data:{
message:"我爱学习",
balls:['篮球','羽毛球','排球','台球']
}
components:{
cpn //对象的增强写法,注册组件
}
})
</script>
二、props数据验证
props有两种写法,数组和对象。但当我们需要对props进行类型等验证时,就需要对象的写法。
验证支持以下的数据类型(type后面可以跟着的):
String | Object |
---|---|
Number | Date |
Boolean | Function |
Array | Symbol |
Vue.component('my-component', {
props: {
// 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
propA: Number,
// 多个可能的类型
propB: [String, Number],
// 必填的字符串
propC: {
type: String,
required: true
},
// 带有默认值的数字
propD: {
type: Number,
default: 100
},
// 带有默认值的对象
propE: {
type: Object,
// 对象或数组默认值必须是一个函数,要有返回值
default: function () {
return { message: 'hello' }
}
},
// 自定义验证函数,自己写的一个验证
propF: {
validator: function (value) {
// 这个值必须是下列字符串中的一个,否则就报错
return ['success', 'warning', 'danger'].indexOf(value) !== -1
}
}
}
})
props驼峰标识
驼峰即在变量的命名时出现大写字母。当出现驼峰标识时,再使用props就可能找不到要找的变量。故要尽量避免。
如果非要使用驼峰标识,那么必须在v-bind绑定时添加“-”,并且把大写字母化为小写字母。
myMessage ----> my-message
三、子组件向父组件传递数据
当子组件需要向父组件传递数据时,要用到自定义事件。v-on不仅可以用于监听DOM事件,也可以用来监听组件间的自定义事件。
自定义事件的流程:
- 在子组件中,通过$emit()来触发事件
- 在父组件中,通过v-on来监听子组件事件
<!--父组件模板-->
<div id = "app">
<!--cpnclick是在父组件里监听的,故要在父组件里定义-->
<cpn @itemclick = "cpnclick"></cpn>
</div>
<!--子组件模板-->
<template id="cpn">
<div>
<!--遍历列表,监听用户点击。btnclick要在子组件里定义-->
<button v-for = "item in liebiao" @click="btnclick(item)">
{
{item.name}}
</button>
</div>
</template>
<script>
//子组件
const cpn = {
template:"#cpn",
data(){
return{
liebiao:[
{
id:'aa',name:"小花"},
{
id:'bb',name:"大喜"},
{
id:'cc',name:"佳哥"},
{
id:'dd',name:"静姐"},
]
}
},
methods:{
btnclick(item){
//发射事件
this.$emit('itemclick',item)
//这里的itemclick就是传给父组件监听的变量名
}
}
}
//父组件(vue实例)
const app = new Vue({
el:"#app",
data:{
message:"好好学习"
},
methods:{
cpnclick(item){
consolo.log("cpnclick");
}
}
})
</script>
具体步骤:
- 在子组件里给定数据,定义方法准备用$emit向父组件发送数据
- 在父组件模板里监听发过来的数据
- 在父组件模板里监听的数据要在父组件里定义方法,以便接受数据,渲染到页面
consolo.log(“cpnclick”);
}
}
})
具体步骤:
1. 在子组件里给定数据,定义方法准备用$emit向父组件发送数据
2. 在父组件模板里监听发过来的数据
3. 在父组件模板里监听的数据要在父组件里定义方法,以便接受数据,渲染到页面
4. 在子组件模板里监听用户点击,监听的事件就是用$emit发射的那个方法