Vue入门级教程六:组件间通信与插槽

打印 上一主题 下一主题

主题 952|帖子 952|积分 2856

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
在前面的Vue入门级教程中,我们已经学习了Vue的基础知识,包罗模板语法、指令、计算属性、侦听器以及组件的创建和使用。本日,我们将深入探究Vue组件间通信的方法以及插槽(slot)的使用,这两个主题对于构建复杂的Vue应用程序至关紧张。
一、组件间通信

(一)父组件向子组件传递数据(Props)


  • 基本用法
    在Vue中,父组件可以通过props向子组件传递数据。起首,在父组件中界说要传递的数据,然后在子组件中通过props选项接收。例如,我们有一个父组件ParentComponent和一个子组件ChildComponent。
    在父组件的模板中:
  1. <template>
  2.   <div>
  3.     <ChildComponent :message="parentMessage" />
  4.   </div>
  5. </template>
  6. <script>
  7. import ChildComponent from './ChildComponent.vue';
  8. export default {
  9.   components: {
  10.     ChildComponent
  11.   },
  12.   data() {
  13.     return {
  14.       parentMessage: '这是父组件传递给子组件的消息'
  15.     };
  16.   }
  17. };
  18. </script>
复制代码
在子组件中:
  1. <template>
  2.   <div>
  3.     <p>{{ message }}</p>
  4.   </div>
  5. </template>
  6. <script>
  7. export default {
  8.   props: {
  9.     message: String
  10.   }
  11. };
  12. </script>
复制代码
这样,父组件中的parentMessage数据就传递到了子组件中,并可以在子组件的模板中使用。

  • 动态绑定Props
    props的值不仅可以是静态的,还可以是动态绑定的。例如,父组件中的数据可能会根据用户的利用或其他因素发生变革,我们希望子组件能够实时接收更新后的数值。
    在父组件的模板中:
  1. <template>
  2.   <div>
  3.     <input v-model="parentMessage" />
  4.     <ChildComponent :message="parentMessage" />
  5.   </div>
  6. </template>
复制代码
当用户在输入框中输入内容时,子组件会立刻更新显示的消息。
(二)子组件向父组件传递数据(自界说变乱)


  • 使用$emit触发变乱
    子组件可以通过$emit方法触发自界说变乱,向父组件传递数据。在子组件中,当某个利用发生时(例如点击按钮),我们可以触发一个自界说变乱,并传递相关数据。
    在子组件的模板中:
  1. <template>
  2.   <div>
  3.     <button @click="sendDataToParent">向父组件传递数据</button>
  4.   </div>
  5. </template>
  6. <script>
  7. export default {
  8.   methods: {
  9.     sendDataToParent() {
  10.       const data = '这是子组件传递给父组件的数据';
  11.       this.$emit('childData', data);
  12.     }
  13.   }
  14. };
  15. </script>
复制代码
在父组件中,通过v-on指令监听子组件触发的变乱,并在变乱处理函数中接收数据。
在父组件的模板中:
  1. <template>
  2.   <div>
  3.     <ChildComponent @childData="handleChildData" />
  4.     <p>{{ receivedData }}</p>
  5.   </div>
  6. </template>
  7. <script>
  8. import ChildComponent from './ChildComponent.vue';
  9. export default {
  10.   components: {
  11.     ChildComponent
  12.   },
  13.   data() {
  14.     return {
  15.       receivedData: ''
  16.     };
  17.   },
  18.   methods: {
  19.     handleChildData(data) {
  20.       this.receivedData = data;
  21.     }
  22.   }
  23. };
  24. </script>
复制代码
当子组件中的按钮被点击时,父组件会接收到子组件传递的数据,并更新receivedData的值,从而在页面上显示出来。
(三)兄弟组件通信(通过共同的父组件)


  • 父组件作为中介
    当两个兄弟组件必要通信时,可以通过它们共同的父组件作为中介来实现。兄弟组件A可以通过触发父组件中的自界说变乱,将数据传递给父组件,然后父组件再将数据传递给兄弟组件B。
    例如,我们有兄弟组件BrotherComponentA和BrotherComponentB,以及它们的父组件ParentComponent。
    在BrotherComponentA中:
  1. <template>
  2.   <div>
  3.     <button @click="sendDataToParent">向兄弟组件传递数据</button>
  4.   </div>
  5. </template>
  6. <script>
  7. export default {
  8.   methods: {
  9.     sendDataToParent() {
  10.       const data = '这是兄弟组件A传递的数据';
  11.       this.$emit('sendData', data);
  12.     }
  13.   }
  14. };
  15. </script>
复制代码
在ParentComponent中:
  1. <template>
  2.   <div>
  3.     <BrotherComponentA @sendData="handleDataFromA" />
  4.     <BrotherComponentB :dataFromA="dataForB" />
  5.   </div>
  6. </template>
  7. <script>
  8. import BrotherComponentA from './BrotherComponentA.vue';
  9. import BrotherComponentB from './BrotherComponentB.vue';
  10. export default {
  11.   components: {
  12.     BrotherComponentA,
  13.     BrotherComponentB
  14.   },
  15.   data() {
  16.     return {
  17.       dataForB: ''
  18.     };
  19.   },
  20.   methods: {
  21.     handleDataFromA(data) {
  22.       this.dataForB = data;
  23.     }
  24.   }
  25. };
  26. </script>
复制代码
在BrotherComponentB中:
  1. <template>
  2.   <div>
  3.     <p>{{ dataFromA }}</p>
  4.   </div>
  5. </template>
  6. <script>
  7. export default {
  8.   props: {
  9.     dataFromA: String
  10.   }
  11. };
  12. </script>
复制代码
这样,兄弟组件A的数据就可以通过父组件传递给兄弟组件B。
(四)非父子、非兄弟组件通信(使用变乱总线或Vuex)


  • 变乱总线(Event Bus)
    对于非父子、非兄弟组件之间的通信,可以使用变乱总线。变乱总线是一个空的Vue实例,它可以作为一个中央变乱中心,任何组件都可以在这个变乱总线上触发和监听变乱。
    起首,创建一个变乱总线文件(例如event-bus.js):
  1. import Vue from 'vue';
  2. export const eventBus = new Vue();
复制代码
在组件A中,触发变乱:
  1. <template>
  2.   <div>
  3.     <button @click="sendDataToOtherComponent">向其他组件传递数据</button>
  4.   </div>
  5. </template>
  6. <script>
  7. import { eventBus } from '../event-bus.js';
  8. export default {
  9.   methods: {
  10.     sendDataToOtherComponent() {
  11.       const data = '这是组件A传递的数据';
  12.       eventBus.$emit('dataFromA', data);
  13.     }
  14.   }
  15. };
  16. </script>
复制代码
在组件B中,监听变乱:
  1. <template>
  2.   <div>
  3.     <p>{{ receivedData }}</p>
  4.   </div>
  5. </template>
  6. <script>
  7. import { eventBus } from '../event-bus.js';
  8. export default {
  9.   data() {
  10.     return {
  11.       receivedData: ''
  12.     };
  13.   },
  14.   mounted() {
  15.     eventBus.$on('dataFromA', (data) => {
  16.       this.receivedData = data;
  17.     });
  18.   }
  19. };
  20. </script>
复制代码
使用变乱总线可以方便地实现非父子、非兄弟组件之间的通信,但在大型项目中,假如使用不妥,可能会导致变乱管理混乱,因此必要谨慎使用。

  • Vuex(状态管理模式)
    Vuex是Vue.js的官方状态管理库,它提供了一种集中式管理应用程序状态的方式,适用于大型复杂项目中的组件间通信。关于Vuex的详细先容和使用方法将在后续教程中深入讲解。
二、插槽(slot)


  • 基本插槽用法
    插槽用于在父组件中向子组件传递内容。在子组件中,使用<slot>标签来界说插槽的位置,然后在父组件使用子组件时,可以在子组件标签内部插入内容,这些内容将会替换子组件中的<slot>标签。
    例如,我们有一个子组件AlertComponent,它用于显示一个提示框。
    在子组件的模板中:
  1. <template>
  2.   <div class="alert">
  3.     <slot></slot>
  4.   </div>
  5. </template>
  6. <style scoped>
  7. .alert {
  8.   border: 1px solid #ccc;
  9.   padding: 10px;
  10.   background-color: #f9f9f9;
  11. }
  12. </style>
复制代码
在父组件中:
  1. <template>
  2.   <div>
  3.     <AlertComponent>这是提示框的内容</AlertComponent>
  4.   </div>
  5. </template>
复制代码
这样,父组件中的“这是提示框的内容”就会显示在子组件的提示框内。

  • 具名插槽(Named Slots)
    有时候,子组件可能必要多个插槽,并且希望父组件能够明白指定内容插入到哪个插槽中。这时候就可以使用具名插槽。
    在子组件的模板中,为插槽添加name属性来界说具名插槽:
  1. <template>
  2.   <div class="card">
  3.     <header><slot name="header"></slot></header>
  4.     <main><slot name="main"></slot></main>
  5.     <footer><slot name="footer"></slot></footer>
  6.   </div>
  7. </template>
复制代码
在父组件中,使用v-slot指令(缩写为#)来指定内容插入到哪个具名插槽中:
  1. <template>
  2.   <div>
  3.     <CardComponent>
  4.       <template v-slot:header>
  5.         <h2>卡片标题</h2>
  6.       </template>
  7.       <template #main>
  8.         <p>卡片正文内容</p>
  9.       </template>
  10.       <template v-slot:footer>
  11.         <p>卡片底部信息</p>
  12.       </template>
  13.     </CardComponent>
  14.   </div>
  15. </template>
复制代码
这样,父组件中的内容就会分别插入到子组件对应的具名插槽中。

  • 作用域插槽(Scoped Slots)
    作用域插槽允许子组件向父组件传递数据,父组件可以根据这些数据来渲染插槽内容。在子组件中,在<slot>标签上使用v-bind绑定数据,然后在父组件中通过slot-scope(在Vue 2.6.0+中已废弃,使用v-slot的新语法)或v-slot来接收数据并使用。
    在子组件的模板中:
  1. <template>
  2.   <div class="list">
  3.     <ul>
  4.       <li v-for="item in items" :key="item.id">
  5.         <slot :item="item"></slot>
  6.       </li>
  7.     </ul>
  8.   </div>
  9. </template>
  10. <script>
  11. export default {
  12.   data() {
  13.     return {
  14.       items: [
  15.         { id: 1, name: '苹果', price: 5 },
  16.         { id: 2, name: '香蕉', price: 3 },
  17.         { id: 3, name: '橙子', price: 4 }
  18.       ]
  19.     };
  20.   }
  21. };
  22. </script>
复制代码
在父组件中:
  1. <template>
  2.   <div>
  3.     <ItemListComponent>
  4.       <template v-slot="{ item }">
  5.         <p>{{ item.name }} - 价格: {{ item.price }}</p>
  6.       </template>
  7.     </ItemListComponent>
  8.   </div>
  9. </template>
复制代码
父组件可以根据子组件传递过来的item数据来渲染每个列表项的内容。
通过学习组件间通信和插槽的使用,我们可以构建更加灵活和复杂的Vue应用程序。在现实开发中,根据不同的场景选择合适的通信方式和插槽用法,能够进步代码的可读性、可维护性和复用性。希望本教程对你在Vue的学习过程中有所帮助,后续我们将继续深入学习Vue的其他高级特性。假如你有任何问题或发起,接待在批评区留言。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

张国伟

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表