最详细的Vue学习之父子组件之间通信

** 有时候需要实现一些功能时会用到组件之间的通信**

一、父传子–靠属性

比如需要做一个导航,在不同的页面需要显示不同的标题时,可以根据父组件传过来的属性来改变子组件的显示,下面的例子中,父组件是root(就是实例化的vue)

<body>
    <div id="box">
      <navbar myname = "position"></navbar>
      <navbar myname = "list"></navbar>
      <navbar myname = "shopcar"></navbar>
    </div>
</body>
<script src="./b_component/lib/vue.js"></script>
<script>
    Vue.component('navbar',{
        template:`
        <div>
            <button>首页</button>
             navbar -- {{myname}}
            <button>返回</button>
        </div>`,
        props:['myname'] //这里是接收父组件传来的属性,注意,这个是props不是prop啊!不然没法传过去!
    })
    new Vue({
        el:'#box',

显示:
在这里插入图片描述
上面的例子属于属性的绑定,再使用,如果要在子组件中绑定父组件的值,需要动态绑定,用的是bind

<body>
    <div id="box">
      <navbar myname = "position"></navbar>
      <navbar myname = "list"></navbar>
      <navbar :myname = "parentname"></navbar>
    </div>
</body>
<script src="./b_component/lib/vue.js"></script>
<script>
    Vue.component('navbar',{
        template:`
        <div>
            <button>首页</button>
             navbar -- {{myname}}
            <button>返回</button>
        </div>`,
        props:['myname'] //这里是接收父组件传来的属性,注意,这个是props不是prop啊!不然没法传过去!
    })
    new Vue({
        el:'#box',
        data:{
            parentname:"父组件的状态" //这里是父组件的状态,也是相当于是root,vue的实例
        }
    
    })

在这里插入图片描述

如果想要只显示一个导航栏,而不是三个都显示时,想要通过一个属性控制时,这时属性传递的是字符串,想要转成布尔值要用bind绑定

<body>
    <div id="box">
      <navbar myname = "position" :mystate = "false"></navbar>
      <navbar myname = "list" :mystate = "true"></navbar>
      <navbar :myname = "parentname" :mystate = "false"></navbar>
    </div>
</body>
<script src="./b_component/lib/vue.js"></script>
<script>
    Vue.component('navbar',{
        template:`
        <div v-if = "mystate">    //这里用v-if来绑定这个状态
            <button >首页</button>
             navbar -- {{myname}}
            <button>返回</button>
        </div>`,
        props:['myname','mystate'] //这里是接收父组件传来的属性,注意,这个是props不是prop啊!不然没法传过去!
    })
    new Vue({
        el:'#box',
        data:{
            parentname:"父组件的状态"
        }
    
    })

在这里插入图片描述

进一步,如果想要进行【属性验证】,主要是将props写成是对象模式,比如上面的mystate应该是布尔类型的,不加动态绑定之前是字符串类型的,这样子就会报错,如:

在这里插入图片描述
在这里插入图片描述
加了冒号之后就可以了,动态绑定,相当于是变量那个样子

二、子传父–靠事件

子传父就好像孩子给父亲打钱一样,父亲需要给孩子银行卡号作为打钱的连接,整个逻辑是:触发子组件事件–> 分发的事件–>使得父组件的事件触发 --> 使得成功给父亲打钱

<body>
    <div id="box" >
        <!-- 父组件相当于这个box -->
        父组件
        <child @myevent = fatherCard($event)></child>   
        <!-- 在父组件中用了子组件,子组件传的值时加子组件那里的哦 ,这样是监听这个事件的意思,没有写$event时,是不用写括号的-->
        <!--父组件的函数时绑定在这里的哦 -->
    </div>
</body>
<script src="./b_component/lib/vue.js"></script>
<script>
    Vue.component("child",{
        template:`
        <div>
            子组件
            <button @click = paymoney()> 打钱 </button>
        </div>`,
        data(){
            return{
                childname:"子组件的状态"
            }
        },
        methods:{
            paymoney(){
                this.$emit('myevent',2000) //找到这张银行卡号的意思,这里用的是$emit分发这个函数
            }
        }

    })
    new Vue ({
        el:"#box",
        methods:{
            fatherCard(ev){
                console.log('老子收到钱了!',ev)  //这里的ev是固定的写法
            }
        }
    })

在这里插入图片描述
传送子组件的状态时,可以这样子
在这里插入图片描述
在这里插入图片描述

子传父案例:通过子组件来获取父组件的数据(组件之间的数据作用域是不同的)

如果要实现点击按钮就控制列表的展示时,一般我们这样做:

<body>
    <div id="box">
        <!-- 这里是父组件 -->
        <button  @click = "isShow = !isShow" >确定</button>
        <child v-show = "isShow"></child>
        <!-- 这里的子组件看成是普通标签,之前的父组件给子组件传值靠的是属性 -->
    </div>
</body>
<script src="./b_component/lib/vue.js"></script>
<script>
    Vue.component("child",{
        template:`
        <div style="background:yellow">
           
            <ul>
            <li>1</li>
           <li>2</li>
           <li>3</li>
          <li>4</li>
          </ul>
        </div>
        `,
        
    })
    new Vue({
        el:"#box",
        data:{
            isShow:false
        }
        
    })

但是,如果按钮是封装在一个组件当中的话,就需要用到父传子的功能了!

<body>
    <div id="box">
        <!-- 这里是父组件 -->
        <!-- <button  @click = "isShow = !isShow" >确定</button> -->
        <navbar @myevent = "handleShow"> </navbar>
        <!-- navbar子组件通过接收父组件的数据来控制子组件的展示 -->
         <child  v-show = "isShow"> </child>
    </div>
</body>
<script src="./b_component/lib/vue.js"></script>
<script>
    Vue.component("navbar", {
        template:
            `
        <button @click = showList()> 确定 </button>
        `,
        methods:{
            showList(){
                this.$emit("myevent")
            }
        }
    })
    Vue.component("child", {
        template: `
        <div style="background:yellow">
           
            <ul>
            <li>1</li>
           <li>2</li>
           <li>3</li>
          <li>4</li>
          </ul>
        </div>
        `,

    })
    new Vue({
        el: "#box",
        data: {
            isShow: true
        },
        methods: {
            handleShow() {
                this.isShow = !this.isShow
            }
        }

    })
</script>
总结:子组件访问父组件的数据时,相当于父组件个子组件通信,这时父组件的银行卡是绑在使用的子组件上的;
使用组件开发时,还是使用父子通信的方式来控制展示好些
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值