Vue学习笔记(五)

组件传递数据_props

组件与组件之间不是完全独立的,而是有交集的,那就是组件与组件之间可以传递数据的。
传递数据的解决方案就是 props

App.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<script>
import parent from './components/parent.vue';

export default {
name: 'App',
components: {
parent,
}
}
</script>

<template>
<div id="app">
<parent />
</div>
</template>

<style>

</style>

parent.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<script>
import child from './child.vue';

export default {
data() {
return {

}
},
components: {
child,
}
}
</script>

<template>
<h3>parent</h3>
<child title="Parent数据"/>
</template>

child.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<script>
export default {
data() {
return {

}
},
props: ['title']
}
</script>

<template>
<h3>Child</h3>
<p>{{ title }}</p>
</template>

动态数据传递

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<script>
import child from './child.vue';

export default {
data() {
return {
message: "Parent数据"
}
},
components: {
child,
}
}
</script>

<template>
<h3>parent</h3>
<child :title="message"/>
</template>

注意:只能从父级传递到子级

组件传递多种数据类型

通过 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
<script>
import child from './child.vue';

export default {
data() {
return {
message: "Parent数据",
age: 20,
names: ['张三', '李四', '王五'],
userInfo: {
name: '张三',
age: 20
}
}
},
components: {
child,
}
}
</script>

<template>
<h3>parent</h3>
<child :title="message" :age="age" :names="names" :userInfo="userInfo"/>
</template>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<script>
export default {
data() {
return {

}
},
props: ['title', 'age','names','userInfo'],
}
</script>

<template>
<h3>Child</h3>
<p>{{ title }}</p>
<p>{{ age }}</p>
<ul>
<li v-for="(item,index) in names " :key="index">{{ item }}</li>
</ul>
<p>{{ userInfo.name }}</p>
<p>{{ userInfo.age }}</p>
</template>

组件传递 props 效验

Vue 组件可以更细致地声明对传入的 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
34
<script>
export default {
data() {
return {

}
},
props: {
title: {
type: [String, Number,Array,Object],
//必选项
Required: true
},
age: {
type: Number,
default: 18
},
// 数字和字符串可以直接default,对象和数组需要用函数返回
names: {
type: Array,
default() {
return ['张三', '李四', '王五']
}
}
}
}
</script>

<template>
<h3>componentB</h3>
<p>{{title}}</p>
<p>{{age}}</p>
<p v-for="(item,index) in names" :key="index">{{ item }}</p>
</template>

props 是仅读

组件事件

在组件的模版表达式中,可以直接使用 $emit方法触发自定义事件
触发自定义事件的目的是组件之间传递数据。

自定义事件可以在组件中反向传递数据,prop 可以将数据从父组件传递到子组件,那么反向如何操作呢,就可以利用自定义事件实现 $emit

child.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<script>
export default {
data() {
return {

}
},
methods: {
clickHandle() {
this.$emit('parentEvent', '我是parent组件传递的数据');
}
}
}
</script>

<template>
<h3>Parent组件事件</h3>
<button @click="clickHandle">传递数据</button>
</template>

parent.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
<script>
import childA from './childA.vue';
export default {
data() {
return {
message: ""
}
},
components: {
childA
},
methods: {
getHandle(data) {
console.log(data);
this.message = data;
}
}
}
</script>

<template>
<h3>child组件事件</h3>
<childA @parentEvent="getHandle"/>
<p>{{message}}</p>
</template>

温馨提示:

组件之间传递数据的方案:

  1. 父传子: props
  2. 子传父: 自定义事件(this.$emit)

配合 v-model使用

如果是用户输入,我们希望在获取数据的同时发送数据配合 v-model来使用。

searchDemo.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<script>
export default {
data() {
return {
search: '',
}
},
watch: {
search(newVal, oldVal) {
this.$emit('searchEvent', newVal);
}
}
}
</script>

<template>
搜索:<input type="text" v-model="search">
</template>

main.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
<script>
import searchDemo from './searchDemo.vue';
export default {
data() {
return {
search: ""
}
},
components: {
searchDemo
},
methods: {
getSearch(data) {
this.search = data;
}
}
}
</script>

<template>
<h3>Main</h3>
<p>搜索内容为:{{ search }}</p>
<searchDemo @searchEvent="getSearch"/>
</template>

组件数据传递

我们之前学过了组件之间的数据传递,props和自定义事件 两种方式

  1. props:父传子
  2. 自定义事件:子传父

除了上诉的方案,props也可以实现子传父

componentA.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
<script>
import componentB from './componentB.vue';
export default {
data() {
return {
message: ''
}
},
components: {
componentB,
},
methods: {
dataFn(data) {
this.message = data;
}
}
}
</script>

<template>
<h3>componentA</h3>
<componentB title="标题" :onEvent="dataFn"/>
<p>{{ message }}</p>
</template>

componentB.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<script>
export default {
data() {
return {

}
},
props: {
title: {
type: String,
},
onEvent: {
type: Function,
}
}
}
</script>

<template>
<h3>componentB</h3>
<p>{{ title }}</p>
<p>{{ onEvent('传递参数') }}</p>
</template>