【Vue3.x】父子组件传值

父子组件间的传值

vue2的父子的传值和vue2的是基本一样的,只是在当我们在使用组合式api式,只是在子组件的写法不同。

  1. defineProps 和 defineEmits 都是只能在 <script setup> 中使用的编译器宏。他们不需要导入,且会随着 <script setup> 的处理过程一同被编译掉。

  2. defineProps 接收与 props 选项相同的值,defineEmits 接收与 emits 选项相同的值。

  3. defineProps 和 defineEmits 在选项传入后,会提供恰当的类型推导。

  4. 传入到 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);

})
posted @ 2022-10-06 16:01  wanglei1900  阅读(539)  评论(0编辑  收藏  举报