通信:父传子

props基本用法

在组件中,使用选项props来声明需要从父级接收到的数据

props的值有两种方式:一:字符串数组,数组中的字符串就是传递时的名称;二:对象,对象可以设置传递时的类型,也可以设置默认值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<div id="app">
<!-- 用v-bind绑定vue id="app"实例的数据data值,存入子组件 -->
<cpnn :cpnmovies="movies" :cpnmessage="message"></cpnn>
</div>

<template id="cpn">
<div id="">
<h2>{{cpnmovies}}</h2>
<p>{{cpnmessage}}</p>
</div>
</template>

<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
// 父子通信演示
// 以Vue实例为父组件,该注册为子组件
// 父组件传数据给子组件用props获取
const cpnn = {
template:'#cpn',
props:['cpnmovies','cpnmessage'],
}

const app = new Vue({
el:'#app',
data:{
message:'你好啊',
movies:['海贼王','西游记','爱情公寓']
},
components:{
cpnn
}
})
</script>

PS:一开始使用模板的无法获取到message数据,不能展现在hmtl中,然后template标签内添加一个容器div,现在可以完全获取数据展现hmtl

在组件需要被一个容器包裹,template解析的时候,发现有多个根元素,就无法判断。因此需要一个容器

props数据验证

对父组件传递的数据类型,进行锁定。有如下类型:StringNumberBooleanArrayObjectDataFunctionSysmbol

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// (1) 数组传递形式
const cpnn = {
template:'#cpn',
props:['cpnmovies','cpnmessage'],
}

// (2) 对象传递形式,只确认数据类型
const cpnn1 = {
template:'#cpn',
props:{
cpnmovies:Array,
cpnmessage:String
}
}

// (3) 对象传递形式,完整形式
// type:类型、default:默认值、required:必须传入该值【true】
const cpnn2 = {
template:'#cpn',
props:{
cpnmessage:{
type:String,
default:'hello world',
required:true
}
}
}

// (3) 数据类型不同默认值写法不同,比如是Object或Array
props:{
propE:{
type:Object,
// 对象或数组默认值必须从一个工厂函数获取
default: function () {
return { message: 'hello' }
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// 官方示例
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是只读的,Vue底层会监测你对props的修改,如果进行了修改,就会发出警告,若业务需求确实需要修改,那么请复制props的内容到data中一份,然后去修改data中的数据。(props比data数据优先级更高,且不能在data重名)

一般完整属性的 required default 不会同时使用


通信:子传父

父组件访问子组件的数据,通过$children$ref

$children

了解$children属性的根源,可以通过methods,去console.log(this) 输出一下 this,可以得到如下

image-20211031214503481

组件实例对象都有 $children 属性。如果你在该组件上注册了子组件,那么$children属性就有子组件的 this属性,可以获取到 data 数据。

image-20211031220419184

$refs

$refs$children一样是Vue实例对象上的属性,默认是空对象。需要子组件去绑定

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<!-- 使用 $refs 访问子组件 -->
<div id="app">
<!-- 4. 绑定ref值 -->
<cpn ref="app1"></cpn>
<button type="button" @click="printlog">输出打印结果</button>
</div>

<script>
// 省略子组件 cpn 的创建,直接注册
new Vue({
components:{
cpn
},
methods:{
printlog(){
// 通过之间的学习,函数里面的this是指向Vue实例对象的
console.log(this.$refs.app1) // 打印的是 子组件this
console.log(this.$refs.app1 === this.$children[0]) //logs true
}
}
}).$mount('#app')
</script>

<!--
console.log(this.$refs.app1 === this.$children[0])
打印结果返回 true,表示通过 ref绑定值获取到的 全等 $children 获取的
-->

ref绑定元素
ref 同样可以用来绑定容器下的元素,效果就是真实DOM
等同于 getElementById 获取

总结

通过 $children$refs 都能获取到子组件的this属性,前者是通过数组的形式,将注册的组件存放起来;后者是通过对象的形式,将绑定了ref="name"值,存储。

如果你只需要个别组件的属性,可以通过绑定 ref 值去指定获取;如果需要对每一个子组件属性进行使用,可以通过遍历数据的方式遍历 $children 数组