【前端】vue阶段案例:父子组件通信-tabControl栏

阶段案例系列:

案例 链接
【前端】vue阶段案例:购物车 https://blog.csdn.net/karshey/article/details/127473654
【前端】vue阶段案例:父子组件通信-tabControl栏 https://blog.csdn.net/karshey/article/details/127480941
【前端】vue阶段案例:组件化-房源展示 https://blog.csdn.net/karshey/article/details/127520175
【前端】vue阶段案例:vue-router使用流程 https://blog.csdn.net/karshey/article/details/127554171

文章目录

    • 目标
    • 代码
      • 0.结构:数据父传子
      • 1.点击改变样式:排它
      • 2.点击改变页面内容:子传父
    • 总代码
      • 父App.vue
      • 子TabControl.vue
    • 参考

目标

【前端】vue阶段案例:父子组件通信-tabControl栏_第1张图片

  • 移动端
  • 点击tab栏对应选项,则对应选项变红,有下边框,且显示相应页面
  • 这里我们点衣服则显示"衣服页面",以此类推,要排它
  • 用flex布局

代码

0.结构:数据父传子

在这里要完成的:要把结构写出来。

  • 由于是动态的数据,我们不能直接把数据写死
  • 而是要通过 父传子 的通信方式,把数据从App.vue传给TabControl.vue,用v-for循环显示
  • 如何父传子:父写在自己的动态绑定的属性attribute里,子在props属性里接收
  • 用flex布局

App.vue:

<template>
    <div class="app">
        
        <tab-control :titles="['衣服','裤子','鞋子']">tab-control>
        
    div>
template>

<script>
import TabControl from './TabControl.vue'
export default {
    components:{
        TabControl
    },
    data:function(){
        return{
            
        }
    }
}
script>

<style>

style>

组件TabControl.vue:

<template>
    <div class="tab-control">
        <template v-for="(item, index) in titles" :key="index">
            <div class="tab-control-item">
                <span>
                    {{ item }}
                span>
            div>
        template>
    div>
template>

<script>
export default {
    // 通信:父传子
    props: {
        titles: {
            type: Array,
            // 如果参数为空则返回空数组
            default: () => { }
        }
    }
}
script>

<style>
.tab-control {
    display: flex;
    height: 44px;
    line-height: 44px;
    text-align: center;
}

.tab-control .tab-control-item {
    flex: 1;
}
style>

效果:
【前端】vue阶段案例:父子组件通信-tabControl栏_第2张图片

1.点击改变样式:排它

效果:点哪里,哪里就显示红色,且有下划线。

在tab栏的item这里添加active类和点击事件:

<div :class="{active:currentIndex===index}" 
@click="itemClick(index)" class="tab-control-item">

添加currentIndex数据和itemClick方法:

export default {
    // 通信:父传子
    props: {
        titles: {
            type: Array,
            // 如果参数为空则返回空数组
            default: () => { }
        }
    },
    data:function(){
        return{
            // 排它的下标
            currentIndex:-1
        }
    },
    methods:{
        itemClick:function(index){
            this.currentIndex=index;
        }
    }
}

active后的css样式:

.active {
    color:red;
}

.active span {
    border-bottom:2px solid red ;
    padding:0 10px;
}

效果:
【前端】vue阶段案例:父子组件通信-tabControl栏_第3张图片

2.点击改变页面内容:子传父

效果:点”衣服“,则显示”衣服页面“,以此类推。

子传父:把事件tabItemClick传给父,且参数为index

methods:{
   itemClick:function(index){
       this.currentIndex=index;
       // 子传父:事件名称,参数
       this.$emit("tabItemClick",index)
   }
}

于是父要监听事件tabItemClick:

<tab-control @tabItemClick="tabItemClick" 
:titles="['衣服','裤子','鞋子']">tab-control>

当触发事件tabItemClick后就执行函数tabItemClick:目的是显示对应的页面。

data:function(){
    return{
        currentIndex:-1,
        pageContent:['衣服页面','裤子页面','鞋子页面']
    }
},
methods:{
    // 这里的index是子传父时的参数
    tabItemClick:function(index){
        // 显示对应参数的页面,这里的currentIndex是数组下标
        this.currentIndex=index
    }
}

html:


<h1>{{pageContent[currentIndex]}}h1>

效果:
【前端】vue阶段案例:父子组件通信-tabControl栏_第4张图片

总代码

父App.vue

<template>
    <div class="app">
        
        <tab-control @tabItemClick="tabItemClick" :titles="['衣服','裤子','鞋子']">tab-control>
        
        <h1>{{pageContent[currentIndex]}}h1>
    div>
template>

<script>
import TabControl from './TabControl.vue'
export default {
    components:{
        TabControl
    },
    data:function(){
        return{
            currentIndex:-1,
            pageContent:['衣服页面','裤子页面','鞋子页面']
        }
    },
    methods:{
        // 这里的index是子传父时的参数
        tabItemClick:function(index){
            // 显示对应参数的页面,这里的currentIndex是数组下标
            this.currentIndex=index
        }
    }
}
script>

<style>

style>

子TabControl.vue

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

<script>
export default {
    // 通信:父传子
    props: {
        titles: {
            type: Array,
            // 如果参数为空则返回空数组
            default: () => { }
        }
    },
    data:function(){
        return{
            // 排它的下标
            currentIndex:-1
        }
    },
    methods:{
        itemClick:function(index){
            this.currentIndex=index;
            // 子传父:事件名称,参数
            this.$emit("tabItemClick",index)
        }
    }
}
script>

<style>
.tab-control {
    display: flex;
    height: 44px;
    line-height: 44px;
    text-align: center;
}

.tab-control .tab-control-item {
    flex: 1;
}

.active {
    color:red;
}

.active span {
    border-bottom:2px solid red ;
    padding:0 10px;
}
style>

参考

Vue组件之间的通信-父传子-子传父

你可能感兴趣的:(前端案例,前端,vue.js,javascript)