Props方式(父往子)

父组件以数据绑定的形式声明要传递的数据,子组件通过defineProps()方法接收
父组件

<script setup lang="ts">
  // 引入子组件 
  import Sub from '../components/sub.vue'
  // 自定义父组件的数据
  const list = '我是父组件的数据'
</script>
<template>
    <div>
      <Sub :list='list'></Sub>
    </div>
</template>

子组件

<script lang='ts' setup>
  // 引入解构需要的defineProps
  import { defineProps } from 'vue'
  // 通过Props接收父组件传的值
  const Props = defineProps(['list'])
  console.log(Props.list);
  
</script>
<template>
    <div>
       <h1>我是子组件</h1>
       <p> {{Props.list}} </p>
    </div>
</template>

示例:
image.png
在 <script setup> 中必须使用 defineProps API 来声明 props,它具备完整的推断并且在 <script setup> 中是直接可用的。

emit方式(子往父)

子组件中通过defineEmits注册自定义事件.然后再派发这个自定义事件,父组件中通过
子组件

<script lang='ts' setup>
  // 引入解构需要的defineEmits
  import { defineEmits } from 'vue'
 // 调用defineEmits方法 并接受父组件给绑定的事件
  const emit = defineEmits(['title'])
  const btn = () =>{
      // 参数1.事件名
      // 参数2. 给父组件传递的数据
      emit('title','我是子组件的数据')
  }
</script>
<template>
    <div>
      <button @click="btn">子组件的按钮</button>
    </div>
</template>

父组件

<script setup lang="ts">
  // 引入子组件 
  import Sub from '../components/sub.vue'
  // 定义事件函数
  const title = (item) =>{
    console.log(item,'我是父组件');
  }
</script>
<template>
    <div>
      <Sub @title='title'></Sub>
    </div>
</template>

image.png

ref(子往父)

子组件可以通过 expose 暴露自身的方法和数据。

父组件通过 ref 获取到子组件并调用其方法或访问数据。

子组件

<script lang='ts' setup>
  // 引入解构需要的defineProps
  import { defineExpose , ref } from 'vue'
  // 通过ref定义数据
  const subList = ref('我是子组件的数据')
  // 定义方法
  const method = () =>{
    console.log('我是子组件的方法');
  }
  // 通过defineExpose将定义的方法,和数据暴露出去
  defineExpose({
    subList,
    method
  })
</script>
<template>
    <div>
      
    </div>
</template>

父组件

<script setup lang="ts">
  import { ref , onMounted } from 'vue'
  // 引入子组件 
  import Sub from '../components/sub.vue' 
  const sub = ref()
  onMounted(()=>{
    console.log(sub.value.subList);
    sub.value.method()
  })
</script>
<template>
    <div>
      <!-- 定义ref -->
    <Sub ref="sub"></Sub>
    </div>
</template>

image.png

provide/inject (祖宗往后代)

provide/inject是 Vue 中提供的一对 API。无论层级多深,API 都可以实现父组件到子孙组件的数据传递。

父组件

<script setup lang="ts">
import { provide } from 'vue'
//   引入子组件
import Text from '../components/text.vue'
  // 参数1.事件名
  // 参数2.传给子孙组件的值
 provide('list','giao')
</script>
<template>
    <div>
      <Text></Text>
    </div>
</template>

子组件

<script lang='ts' setup>
// 引入vue解构需要的方法
 import { inject } from 'vue'
 const list =  inject('list')
 console.log(list);
 
</script>
<template>
    <div>
      子组件
    </div>
</template>

image.png

插槽slot

匿名插槽(父给子传值)

// 父组件
<script lang="ts" setup>
    // 引入匿名插槽子组件
    import Anonymity from '../components/anonymity.vue'
</script>
<template>
        <!-- *匿名插槽 -->
        <Anonymity>
            <p>我是父组件这是传给子组件的内容</p>
        </Anonymity>
</template>
// 子组件
<script lang="ts" setup>
    
</script>
<template>
    <!-- *直接使用slot -->
    <slot></slot>
</template>

具名插槽(父给子传值)

// 父组件
<script lang="ts" setup>
    //  引入具名插槽的子组件
    import ToolName from '../components/ToolName.vue';
</script>
<template>
    <!-- *具名插槽 -->
    <ToolName>
        <!-- * 第一中写法 v-slot:list1 -->
        <template v-slot:list1>
            <p>我是具名插槽的第一条数据</p>
        </template>
        <!-- * 也可以直接写 #list2 -->
         <template #list2>
            <p>我是具名插槽的第二条数据</p>
        </template>
    </ToolName>
</template>
    // 子组件
<template>
    <!-- * 用name属性定义值 -->
    <slot name="list1"></slot>
    <slot name="list2"></slot>
</template>

作用域插槽(子组件给父亲传值)

// 子组件
<script lang="ts" setup>
    // 子组件定义的数据
    let arr = [
        {
            name:"张三",
            age:10
        },
         {
            name:"李四",
            age:12
        }
    ]
</script>
<template>
    <!-- *绑定事件将将arr的数据传给父组件 -->
        <slot :data="arr"></slot>

</template>
    // 父组件
<script lang="ts" setup>
    //  引入作用域插槽的子组件
    import Scope from '../components/scope.vue'
</script>
<template>
    <Scope>
        <!-- !获取子组件的内容 -->
        <template v-slot="{data}">
                <!-- 循环遍历 -->
            <div v-for="(item,index) in data" :key="index">
                {{ item.name }}
            </div>
        </template>
    </Scope>
</template>

道友
1 声望0 粉丝