随笔 - 12  文章 - 0  评论 - 0  阅读 - 6081

Vue3系列7--父子组件传参

1 父组件传递给子组件

父组件通过v-bind绑定一个数据,然后子组件通过defineProps接受传过来的值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<template>
    <div class="layout">
        <Menu v-bind:data="data"  title="我是标题"></Menu> // 传递字符串的时候可以不需要v-bind,传递非字符串类型需要加v-bind
        <div class="layout-right">
            <Header></Header>
            <Content></Content>
        </div>
    </div>
</template>
  
<script setup lang="ts">
import Menu from './Menu/index.vue'
import Header from './Header/index.vue'
import Content from './Content/index.vue'
import { reactive } from 'vue';
  
const data = reactive<number[]>([1, 2, 3])
</script>

子组件接受值,通过defineProps 来接受 defineProps是无须引入的直接使用即可

1
2
3
4
5
6
7
8
9
10
11
12
13
<template>
    <div class="menu">
        菜单区域 {{ title }}
        <div>{{ data }}</div>
    </div>
</template>
  
<script setup lang="ts">
defineProps<{
    title:string,
    data:number[]
}>()
</script>

TS特有的默认值方式

withDefaults是个函数也是无须引入开箱即用接受一个props函数第二个参数是一个对象设置默认值

1
2
3
4
5
6
7
8
type Props = {
    title?: string,
    data?: number[]
}
withDefaults(defineProps<Props>(), {
    title: "张三",
    data: () => [1, 2, 3]
})

2 子组件给父组件传参

是通过defineEmits派发一个事件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<template>
    <div class="menu">
        <button @click="clickTap">派发给父组件</button>
    </div>
</template>
  
<script setup lang="ts">
import { reactive } from 'vue'
const list = reactive<number[]>([4, 5, 6])
 
const emit = defineEmits(['on-click'])
const clickTap = () => {
    emit('on-click', list)
}
</script>

我们在子组件绑定了一个click 事件 然后通过defineEmits 注册了一个自定义事件,点击click 触发 emit 去调用我们注册的事件 然后传递参数,父组件接受子组件的事件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<template>
    <div class="layout">
        <Menu @on-click="getList"></Menu>
        <div class="layout-right">
            <Header></Header>
            <Content></Content>
        </div>
    </div>
</template>
  
<script setup lang="ts">
import Menu from './Menu/index.vue'
import Header from './Header/index.vue'
import Content from './Content/index.vue'
import { reactive } from 'vue';
  
const data = reactive<number[]>([1, 2, 3])
const getList = (list: number[]) => {
    console.log(list,'父组件接受子组件');
}
</script>

我们从Menu 组件接受子组件派发的事件on-click 后面是我们自己定义的函数名称getList,会把参数返回过来。

3 子组件暴露给父组件内部属性

Vue3 中,默认不会暴露任何在 <script setup> 中声明的绑定,即不能通过模板 ref 获取到组件实例声明的绑定。Vue3 提供了 defineExpose 编译器宏,可以显式地暴露需要暴露的组件中声明的变量和方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// ./components/HelloWorld.vue
<script setup lang="ts">
import { ref } from 'vue'
const msg = ref('Hello Vue3')
 
const handleChangeMsg = (v: string) => {
  msg.value = v
}
 
defineExpose({
  msg,
  handleChangeMsg
})
</script>
 
<template>
  <h1>{{ msg }}</h1>
</template>

使用组件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import HelloWorld from './components/HelloWorld.vue'
// 此处暂时使用any,需要定义类型
const root = ref<any>(null)
 
onMounted(() => {
  console.log(root.value.msg)
})
 
const handleChangeMsg = () => {
  root.value.handleChangeMsg('Hello TS')
}
</script>
 
<template>
  <HelloWorld ref="root" />
  <button @click="handleChangeMsg">handleChangeMsg</button>
</template>
posted on   LotusFlower  阅读(475)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
· 上周热点回顾(2.17-2.23)
< 2025年2月 >
26 27 28 29 30 31 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 1
2 3 4 5 6 7 8

点击右上角即可分享
微信分享提示