组件传值
vue3中引入组件直接在template中使用即可,无需注册。
vue
<template>
<Child/>
</template>
<script lang="ts" setup>
import Child from './ChildView.vue';
</script>
1
2
3
4
5
6
7
2
3
4
5
6
7
父传子
TIP
父组件:自定义属性发送;
子组件:defineProps
接收;
注意:defineProps
在使用的时候无需引入,就可以自动地在 <script setup>
中可用。
vue
/* 父组件 */
<template>
<h2>父组件</h2>
<hr />
<Child :msg="msg"></Child>
</template>
<script lang="ts" setup>
import Child from './ChildView.vue'
import { ref } from 'vue'
let msg = ref('vue3中的父子传值')
</script>
/* 子组件 */
<template>
<h2>子组件</h2>
<p>{{ msg }}</p>
</template>
<script lang="ts" setup>
let props = defineProps({
msg: {
type: String,
default: '你好'
}
})
// 在script中也可以使用父组件传递过来的数据
console.log('props', props)
</script>
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
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
子传父
TIP
子组件:(1)契机:一个点击事件;(2)先声明emit,const emit = defineEmits<{ (e: string, v: 传递的数据的类型): void }>()
;(3)然后在方法内通过 emit('自定义事件名','数据')
传递数据;
父组件:子组件标签绑定自定义事件,自定义事件触发的方法的形参就是子组件传递的数据;
注意:和 defineProps
一样, defineEmits
也无需引入就可以自动地在 <script setup>
中可用。
vue
/* 子组件 */
<template>
<h2>子组件</h2>
<button @click="send">发送</button>
</template>
<script lang="ts" setup>
// 范型指定emit的参数
const emit = defineEmits<{ (e: string, v: string): void }>()
const send = () => {
// 自定义事件名,发送的内容
emit('receive', '小苏同学')
}
</script>
/* 父组件 */
<template>
<h2>父组件</h2>
<hr />
<Child @receive="getChildData"></Child>
</template>
<script lang="ts" setup>
import Child from './ChildView.vue'
// 自定义事件方法的形参就是子组件传递的数据
const getChildData = (v: string) => {
console.log(v)
}
</script>
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
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
v-model 父子组件传值
首先vue的单项数据流特性导致子组件只能接收父组件传递的数据,也就是只能读不能改,所以若要修改父组件的数据便只能由父组件自己去改。
根据这个特性我们实现父子传值的思路就是:父组件向子组件传递一个值,然后子组件修改后,告诉父组件我把值改了。
具体的实现步骤就是:(1)先通过自定义属性进行父传子;(2)再通过emit进行子传父;(3)然后在父组件中通过自定义事件去接收,然后修改。
通过v-model
传值,可以省略第三步,也就是不用父组件写修改方法,只需要在子组件中使用 emit
即可,由 v-model
实现修改操作。这里的 emit
的写法有不同,具体写法参考下面的示例代码。
TIP
父组件:子组件标签自定义属性绑定 v-model:自定义属性 = "值"
;
子组件:emit("update:自定义属性",修改的值)
;
vue
/* 父组件 */
<template>
<h2>父组件</h2>
{{ num }}
<hr />
<Child v-model:count="num"></Child>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import Child from './ChildView.vue'
let num = ref(10)
</script>
/* 子组件 */
<template>
<h2>子组件</h2>
<div>{{ count }}</div>
<button @click="increment">增加</button>
</template>
<script lang="ts" setup>
// 如果想在js中使用父组件传递过来的参数,需要使用变量接取 defineProps
let props = defineProps({
count: {
type: Number, // 首字母必须大写
default: 0
}
})
const emit = defineEmits<{ (e: string, v: Number): void }>()
const increment = () => {
console.log('父组件传递的数据', props.count)
let count = props.count
count++
emit('update:count', count)
}
</script>
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
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