Vue 组件学习 -- 父子组件通信

本文介绍了Vue中实现TabControl组件的详细过程,包括父组件如何向子组件传递数据,以及子组件如何根据接收到的数据动态显示界面。讨论了在template中使用v-for绑定key的重要性,以及在script中定义props和emits的注意事项,同时提供了完整的TabControl.vue和App.vue代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

TabContronl效果图

在这里插入图片描述

点击不同的选项,选项变红并底下高亮,显示对应的界面

1.结构

  • 父:App.vue 
    子:TabControl.vue
    

实现思路:

(子)TabControl.vue 构建 tabControl 组件:

  •   1. 从 App.vue 文件动态获取数据("衣服","鞋子"),不能把数据写死:
          -父传子通信
              -父写在自己的动态绑定的属性 attribute 里,子在 props 属性里接收
              -子使用 v-for 遍历数据展示
      2.  监听点击事件,用 currentIndex 记录选中项的 index,实现动态添加 active 类别、传递index 到 App.vue
      3.  flex布局         
    

(父)App.vue使用tabControl组件、显示对应界面:

  •   1. 从 TabControl.vue 文件引入 tab-control 组件,注册组件
      2. 切换界面
          -子传父通信
              -子通过 $emit,向父发送事件 "btnIndex" ,数据 index
              -利用监听事件 "btnIndex" ,事件绑定 methods ,传递 index ,切换界面
    

2.代码细节

TabControl.vue ------ template 主要部分

       <template v-for="(item, index) in titles" :key="item">
            <div class="tab-item" @click="btnClick(index)" :class="{ active: currentIndex == index}">
                {{item}}
            </div>
       </template>
  

这里有两个重点

  1. v-for需要绑定属性key,方便渲染

    个人理解:通过监听key有无改变,只重新渲染 key 发生改变的元素。不要用 index 作为 key,因为中间插入新数据可能会改变对应的内容,key应为独一无二的标识id 或者 item(没有重复的情况下)都是不错的选择

  2. 动态添加 active 类别
    active: currentIndex == index}

    active: 布尔类型,active 这个 class 存在与否将取决于是否为 true。利用 currentIndex 运行实现动态效果

TabControl.vue ------ script 主要部分

export default {
    props:{
        titles:{
            type: Array,
            default() {
                return{}
            }
        }
    },
    data(){
        return{
            currentIndex: 0,
        }
    },
    emits: ["btnIndex"],
    methods:{
        btnClick(index){
            this.currentIndex = index
            this.$emit("btnIndex", index)
        }
    }
    
}

细节:

  1. 子在props接收父传来的数据,在props对象里,对象声明类型和默认值,如默认值为空对象,最好不要用箭头函数,default() { return{} }
    这样比较稳妥,该文章有详细的解释
  2. 最好在emits里声明了要传给父组件的事件名,在父组件里使用时才会有提示

全部代码

TabControl.vue

<template>
    <div class="tab-control">
       <template v-for="(item, index) in titles" :key="item">
            <div class="tab-item" @click="btnClick(index)" :class="{ active: currentIndex == index}">
                {{item}}
            </div>
       </template>
    </div>
</template>


<script>

export default {
    props:{
        titles:{
            type: Array,
            default() {
                return{}
            }
        }
    },
    data(){
        return{
            currentIndex: 0,
        }
    },
     emits: ["btnIndex"],
    methods:{
        btnClick(index){
            this.currentIndex = index
            this.$emit("btnIndex", index)
        }
    }
    
}
</script>


<style scoped>
    .tab-control{
        display: flex;
        text-align: center;
        line-height: 14px;
        font-size: 14px;
    }

    .tab-item{
        flex: 1;
    }

    .active{
        /* box-sizing: border-box; */
        color: red;
        border-bottom: 3px solid red;
        padding-bottom: 7px;
    }
</style>

App.vue

<template>
    <div class="app">
       <tab-control :titles="['衣服', '鞋子', '裤子']" @btnIndex="changePage">
       </tab-control>
       <div class="page-content" >
            {{pages[currentIndex]}}
       </div>
    </div>
</template>


<script>
import TabControl from "./TabControl.vue"
export default {
    components:{
        TabControl
    },
    data(){
        return{
            pages: ["cloths", "shoes", "pants"],
            currentIndex: 0
        }
    },
    methods:{
        changePage(index){
            this.currentIndex = index
            console.log(this.currentIndex);
        }
    }
    
}
</script>


<style scoped>

</style>

总结

  1. 父传子:父组件把数据放在动态绑定的 attribute 里,子组件在 props 里接收,props 对象内声明类型和默认值
  2. 子传父:$emit 发送事件和传送的数据,在父组件里监听被发送事件,被发送事件绑定对应的methods,并将数据传入其中,监听到事件发生,执行方法
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值