Vue 中的透传,插槽,依赖注入

1. 透传attributes

在组件上使用透传attribute : 当你在父组件中使用子组件时,你可以添加一些attribute到子组件上,即使这些attribute没有在子组件的props中声明。

父组件:

复制代码
<!-- 父组件,例如 ParentComponent.vue -->
<template>
  <div>
    <MyComponent
      data-id="123"
      data-user="alice"
      class="my-custom-class"
      style="color: red;"
    />
  </div>
</template>

<script>
import MyComponent from '../components/MyComponent.vue';

export default {
  components: {
    MyComponent
  }
};
</script>

<style>
/* 父组件样式 */
</style>

子组件:

复制代码
<!-- MyComponent.vue -->
<template>
    <div v-bind="$attrs">
      <h3>透传的Attributes:</h3>
      <ul>
        <li v-for="(value, name) in $attrs" :key="name">
          {{ name }}: {{ value }}
        </li>
      </ul>
    </div>
  </template>
  
  <script>
  export default {
    inheritAttrs: false, // 禁用默认的attribute继承行为
  };
  </script>
  
  <style>
  /* 组件样式 */
  </style>

显示效果:

当然如果你想在控制台打印出来,你可以打印 this.&attrs

复制代码
  <script>
  export default {
    inheritAttrs: false, // 禁用默认的attribute继承行为,
    mounted() {
      // 在组件挂载后,打印透传的attributes
      console.log('透传的Attributes:', this.$attrs);
    },
  };
  </script>

2. 插槽

就是直接在组件中插入对应的模版

2.1 简单点的插入:

ChildComponent.vue:

复制代码
<template>
    <div>
      before
      <slot></slot>
      <slot></slot>
      <slot></slot>
      after
    </div>
</template>

<script setup>


</script>

<style>
</style>

父组件:

复制代码
<template>
  <div class="home">

      <ChildComponent>
        <div>{{hello}}</div>
      </ChildComponent>

  </div>
</template>

<script setup>
import { ref } from 'vue'
import ChildComponent from '../components/ChildComponent.vue'

const hello = ref('Hello world! 2024')
</script>

显示效果:就是将插入的div代替了子组件的slot位置

2.2 在插槽指定的位置,插入指定的值

ChildComponent.vue:

复制代码
<template>
    <div>
      <slot name="header"></slot>
      <slot name="content"></slot>
      <slot name="footer"></slot>
    </div>
  </template>

父组件:

复制代码
<template>
  <div class="home">
    <ChildComponent>
      <template #header>
        <p>This is the header slot</p>
      </template>
      <template #content>
        <p>This is the content slot with a variable: {{ contentVariable }}</p>
      </template>
      <template #footer>
        <p>This is the footer slot</p>
      </template>
    </ChildComponent>
  </div>
</template>

<script>
import { ref } from 'vue'
import ChildComponent from '../components/ChildComponent.vue'

export default {
  components: {
    ChildComponent
  },
  setup() {
    const contentVariable = ref('This is some content.')
    return { contentVariable }
  }
}
</script>

3. 依赖注入

为了便于祖孙之间数据的传输,

3.1 祖组件向子组件和孙组件传递数据示例

祖组件:

复制代码
<template>
  <div>
    <h1>Ancestor Component</h1>
    <p>Providing a message: "{{ message }}"</p>
    <ChildComponent />
  </div>
</template>

<script>
import { provide, ref } from 'vue';
import ChildComponent from '../components/ChildComponent.vue';

export default {
  components: {
    ChildComponent
  },
  setup() {
    const message = ref('Hello from Ancestor!');
    provide('ancestorMessage', message);
    return { message };
  }
}
</script>

子组件:

复制代码
<template>
    <div>
      <h2>Child Component</h2>
      <p>Message from Ancestor: "{{ ancestorMessage }}"</p>
      <GrandchildComponent />
    </div>
  </template>
  
  <script>
  import { inject } from 'vue';
  import GrandchildComponent from '../components/GrandchildComponent.vue';
  
  export default {
    components: {
      GrandchildComponent
    },
    setup() {
      const ancestorMessage = inject('ancestorMessage');
      return { ancestorMessage };
    }
  }
  </script>

孙组件:

复制代码
<template>
    <div>
      <h3>Grandchild Component</h3>
      <p>Message from Ancestor: "{{ ancestorMessage }}"</p>
    </div>
  </template>
  
  <script>
  import { inject } from 'vue';
  
  export default {
    setup() {
      const ancestorMessage = inject('ancestorMessage');
      return { ancestorMessage };
    }
  }
  </script>

然后你会发现子和孙组件都是通过inject来接收数据,而祖组件只需要通过provide发送数据

显示效果:

相关推荐
linux_cfan22 分钟前
17 · 引擎适配器全景:HLS/DASH/Vimeo/Mux/Cast
前端·javascript·音视频
计算机魔术师1 小时前
烧掉2780亿美元还不够?OpenAI的资本豪赌让人头皮发麻
前端
IT_陈寒2 小时前
Java线程池用错参数,我的服务居然悄悄崩溃了
前端·人工智能·后端
卡布鲁2 小时前
React useMemo 与 useCallback 完全指南:原理、场景与避坑
前端·react.js
碳基修炼2 小时前
排查记:本地 devServer 是 http,浏览器却把 302 重定向升级成了 https
前端·http
步行cgn2 小时前
Spring p 命名空间注入详解
java·前端·spring
何何____2 小时前
Vue 生命周期详解
前端·javascript
江米小枣tonylua3 小时前
TypeScript 全面の拥抱 !Prisma 8 + Electron 升级实战
前端
闪耀之光M783 小时前
npm命令解析
前端
咸鱼老弟3 小时前
AI Agent 的"自主性悖论"——为什么给它的自由度越大,越要配一套更硬的护栏
前端·人工智能