Vue组件通信详解

一,父组件与子组件之间的通信

1,了解props属性

        (1)props是单向绑定的,当父组件传递的数据发生变化时子组件props也会更新为最新值

           (2)props的type(属性)和default(默认值)可以验证传入props参数的数据规格

        (3)静态props传入的值不会发生变化,父组件中定义,子组件使用

        (4)动态props要动态绑定父组件传入的数据

2,props静态传值子组件使用

 
<body>
    <div id="box">
    //通过父组件静态传值给子组件,子组件通过自定义属性接收父组件传的值
    <navbar row="我是父组件的值"></navbar>
    </div>
</body>

<script>
    Vue.component("navbar",{
        props:["row"],//通过props接收父组件传递的值
        template:`
        <div>
            {{row}}
            </div>
        `
    })
    new Vue({
        el:"#box",
        data:{
            // datalist:"我是父组件的值"
        }
    })
</script>

浏览器显示结果 

3,父子通信通过props动态传递数据

<body>
    <div id="box">
    //动态绑定自定义属性 接收父组件的状态  
    <navbar :row="datalist"></navbar>
    </div>
</body>
<script>
    Vue.component("navbar",{
        props:["row"],
        template:`
        <div>
            {{row}}
            </div>
        `
    })
    new Vue({
        el:"#box",
        data:{
             datalist:"我是父组件的动态值"
        }
    })
</script>

浏览器显示结果 

 4,props中type和default的使用

<body>
    <div id="app">
        <navbar myname="影院" :aaa="false"></navbar>
        <navbar myname="电影" ></navbar>
    </div>
</body>
<script>
    Vue.component("navbar",{
        props:{
            //定义mymane的属性为字符串默认值为空,aaa为布尔型默认值为true
            myname:
            {
                type:String,
                default:""
                    },
            aaa:{
                type:Boolean,
                default:true
            }
        },
        template:`
        <div style="background:red;border:5px solid black">
        <button @click="handleft()" >left</button>
        {{myname}}
        <button @click="handright()" v-show="aaa">right</button> 
        </div>     
        `  
    })
    new Vue({
        el:"#app",
    
    })
</script>

浏览器显示结果

 5,子传父通过#emit事件传值

vm.#emit(evenname....,[args])

参数:evenname自定义事件名,[args] 需要发送的数据

作用:触发当前实例,附加参数都会传给监听器回调

<body>
    <div id="box">
            //@event父组件中自定义事件,父组件实现函数编写
            <button-nav @event="eventprents"></button-nav>
    </div>
</body>
<script>
    Vue.component("buttonNav",{
             data(){
            return{
                datalist:"我是子组件的数据"
            }
           
            },
            template:`
            <div>
            //@click点击事件触发handshow函数
            <button @click="handshow">按钮</button>    
            </div>
            `,
            methods:{
                handshow(){
                    //函数运行 this.$emit触发event事件
                    //this.datalist是子组件向父组件传递的数据
                    this.$emit("event",this.datalist)
                }
            }

        })
    new Vue({
        el:"#box",
        methods:{
            eventprents(){
            //父组件接收数据并在控制台输出
             console.log(res)
            }
        }

    })

</script>

浏览器显示结果 

6,通过ref实现子父组件通信

通过ref绑定元素可以通过this.$refs.name获取当前dom节点

通过ref绑定组件可以通过this.$refs.name获取当前组件实例,可以使用组件的方法

不介意使用ref直接改变子组件状态

<body>
    <div id="box">
        //ref绑定span标签
        <span ref="a">aaaaaaaaaaa</span>
        //通过点击事件触发handclick函数
        <button @click="handclick">click</button>
        //ref绑定navbar 组件
        <navbar ref="b"></navbar>
    </div>
</body>
<script>
    Vue.component("navbar",{
        data(){
            return{
                //定义子组件状态
                mytext:"我是子组件的状态"
            }
        },
        template:`
        <div>
            child
            </div>
        `
    })
    new Vue({
        el: "#box",
        data: {

        },
        methods: {
                handclick(){
                    //获取span标签的dom节点
                    console.log(this.$refs.a)
                    //获取navbar组件的mytext状态
                    console.log(this.$refs.b.mytext)
                }
        }
    })

浏览器显示结果  

 二,兄弟组件之间的通信

一,通过父组件作为中间人让其兄弟组件通信

子组件通过$emit事件给父组件传递值,父组件通过props属性传值给子组件 

  <div id="box">
        //点击click事件调用handjson函数,获取json数据
        <button @click="handjson">点击</button>
        //父组件获取得json数据传给子组件navbar ,父组件复写eventclick函数
        <navbar :list="datalist" @event="eventclick"></navbar>
        //子组件filr-text接收子组件navbar 传递给父组件的数据
        <filr-text :details="details"> </filr-text>

    </div>
</body>
<script>
    Vue.component("navbar",{
        props:["list"],
        template:`
        <div>
        <ul class="item">
            <li v-for="(item,index) in list">
                <img :src="item.img" alt="">
                {{item.name}}
                //点击事件触发handclick函数,并向函数发送一个index下标
                <button @click="handclick(index)">詳情</button>
                </li>
               
        </ul>
       </div>
        `,
        methods:{
            handclick(index){
                //函数运行触发this.$emit向event事件分发数据
                //console.log(this.list[index].details)
                this.$emit("event",this.list[index].details)
            }
        }

    })
   Vue.component("filrText",{
    //接收子组件navbar发送给父组件,filrText通过动态绑定获取父组件状态
    props:["details"],
    template:`
    <div class="filetext"> 
        {{details}}
        </div>
    `
   })
new Vue({
    el:"#box",
    data:{
      
        datalist:'',
      
        details:''
    },
    methods:{
        handjson(){
            //获取json数据    
            fetch("./test.json")
            .then(res=>res.json())
            .then(res=>{
                //将json数据赋值给datalist
                this.datalist=res.datalist
                console.log(this.datalist)
                // console.log(res.datalist)
            })
        },
        eventclick(data){
              //子组件向父组件发送的数据赋值给details
            this.details=data
        }
    }
})
</script>
</html>

二,中央事件总线,订阅和发布模式

通过创建一个新的vm对象,专门统一注册事件,供所有组件共同操作,达到所有组件随意隔代传值的效果
也就是:各个组件内部要传输的数据或者要执行的命令信息,靠bus来通信。

通过bus=new Vue()创建总线

bus.$emit("name")                发布者发布

bus.$on("name",回调接收)             订阅者接收

    <div id="box">

        <button @click="handjson">点击</button>

        <navbar :list="datalist" ></navbar>

        <filr-text > </filr-text>

    </div>
</body>
<script>
    //创建中央事件总线
    var bus=new Vue();
    
    Vue.component("navbar",{
        props:["list"],
        template:`
        <div>
        <ul class="item">
            <li v-for="(item,index) in list">
                <img :src="item.img" alt="">
                {{item.name}}
                <button @click="handclick(index)">詳情</button>
                </li>
               
        </ul>
       </div>
        `,
        methods:{
            handclick(index){
                // console.log(this.list[index].details)
                //发布者通过vue实例方法$emit发送事件名称和数据
                bus.$emit("xiaoming",this.list[index].details)
                // this.$emit("event",this.list[index].details)
            }
        }

    })
        Vue.component("filrText",{
            data(){
                return{
                    info:''
                }
            },
        //挂载至生命周期
        mounted(){
            //订阅者通过发布者的事件名称接收发布者发送的数据
            bus.$on("xiaoming",(data)=>{
            this.info=data
    })
        },
            template:`
            <div class="filetext"> 
            {{info}}
                </div>
            `
        })
            new Vue({
                el:"#box",
                data:{
                    datalist:'',
                
                },
                methods:{
                    handjson(){
                        fetch("./test.json")
                        .then(res=>res.json())
                        .then(res=>{
                            this.datalist=res.datalist
                            console.log(this.datalist)
                            // console.log(res.datalist)
                        })
                    },
                
                }
            })
            </script>
            </html>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小明同学`

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值