【Vue3.x】父子组件传值
父子组件间的传值
vue2的父子的传值和vue2的是基本一样的,只是在当我们在使用组合式api式,只是在子组件的写法不同。
-
defineProps 和 defineEmits 都是只能在
<script setup>
中使用的编译器宏。他们不需要导入,且会随着<script setup>
的处理过程一同被编译掉。 -
defineProps 接收与 props 选项相同的值,defineEmits 接收与 emits 选项相同的值。
-
defineProps 和 defineEmits 在选项传入后,会提供恰当的类型推导。
-
传入到 defineProps 和 defineEmits 的选项会从 setup 中提升到模块的作用域。因此,传入的选项不能引用在 setup 作用域中声明的局部变量。这样做会引起编译错误。但是,它可以引用导入的绑定,因为它们也在模块作用域内。
1.defineProps() 父传子
父组件绑定v-bind,同vue2一样简写作冒号: ,data-by-props就是props名称,data为具体要传递的数据。数据如果是字符串可以不加v-bind(😃,如果是非字符串必须要加v-bind(😃,
<template>
<div>
左侧导航菜单
<Tree @on-click="getItem" :data-by-props="data"></Tree>
</div>
</template>
子组件使用组合式api+TS时,可以无需引入直接使用defineProps()接收props,并用接口泛型约束传递的数据类型。
// 通过接口约束树结构(并递归子集),递归边界是子集没有children了
interface TreeList {
name: string,
icon?: string,
children?: TreeList[] | [] // 子集为联合类型,可能是同样的树结构,也可能是空数组。甚至children是可选的,没有children就是递归边界
}
// 通过接口并使用泛型约束-父组件传来的props data树形结构
interface Props<T> {
data?: T[] | []
};
// 接受父组件传来的props data树形结构,并使用泛型约束props
defineProps<Props<TreeList>>()
使用withDefaults()来赋予props 的默认值,同vue2里props的default,使用withDefaults()传入第一个参数defineProps(),并传入第二个参数是一个对象赋予默认值,注意如果第二个参数的配置项里有引用类型,需用函数形式返回。
export interface Props {
msg?: string
labels?: string[]
}
const props = withDefaults(defineProps<Props>(), {
msg: 'hello',
labels: () => ['one', 'two']
})
2.defineEmits() 子传父自定义事件
例子同上面,子组件上绑定一个单击事件clickItem,然后通过defineEmits()定义并触发自定义事件on-click,同vue2相似,只是写法上的改变。
<script setup lang='ts'>
// 递归引入自身并取
import TreeChild from "./index.vue";
// 通过接口约束树结构(并递归子集),递归边界是子集没有children了
interface TreeList {
name: string,
icon?: string,
children?: TreeList[] | [] // 子集为联合类型,可能是同样的树结构,也可能是空数组。甚至children是可选的,没有children就是递归边界
}
// 子→父通信,告知父组件Menu当前点击的是具体哪一个菜单
const emit = defineEmits(['on-click'])
const clickItem = (item: TreeList) => {
emit('on-click', item)
}
</script>
然后在父组件中接收自定义事件
<template>
<div>
左侧导航菜单
<Tree @on-click="getItem" :data="data"></Tree>
</div>
</template>
const getItem = (item: TreeList) => {
console.log(item, '父组件拿取到了item');
}
3. defineExpose() 子组件暴露给父组件内部属性
子组件暴露数据
const list = reactive<number[]>([4, 5, 6])
defineExpose({
list
})
父组件通过ref获取实例来接收
<Menu ref="menus"></Menu>
const menus = ref(null)
// 必须在onMounted钩子里才能拿到节点
onMounted(()=>{
console.log('```',treeNode.value);
})
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现