Vue中 组件间的通信

这篇具有很好参考价值的文章主要介绍了Vue中 组件间的通信。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

引入

父组件==>子组件

子组件==>父组件

全局事件总线

消息订阅与发布


引入

你知道Vue中组件之间应该如何进行通信吗?这里面就涉及到了多个关系了,父子之间互传、兄弟之间互传、子孙之间互传,甚至是任意的组件之间传递......

是不是感觉有点头皮发麻。没关系,本文将带领大家一起学习对应的解决方法!!!

父组件==>子组件

父组件若想传递信息给子组件,最常见的方式就是使用props配置项。该配置项的功能是让组件接受外部传过来的数据。

传递数据:<Demo name="xxx"/>

接收数据:

1.第一种方式(只接收):props:['name']

2.第二种方式(限制类型):props:{name:String}

3.第三种方式(限制类型、限制必要性、指定默认值):

props:{
    name:{
    type:String, //类型
    required:true, //必要性
    default:'老王' //默认值
    }
}

现在在脚手架中编写一个案例来实现父组件给子组件传递数据,并在页面上显示出来。默认的父组件为App, 子组件为Student。先从父组件传入三个数据给子组件,并且显示在页面上。接受方式分别采用以上的方式来实现,对应的代码如下:

App.vue

<template>
    <div>
        <!-- 为子组件传入数据 -->
        <Student name="N-A" sex="男" age="5"/>
    </div>
</template>
​
<script>
    //导入Student组件
    import Student from './components/Student'
    export default {
        name:'App',
    //注册Student组件
        components:{Student}
    }
</script>
​

Student.vue

<template>
    <div>
        <h1>{{msg}}</h1>
        <h2>博主姓名:{{name}}</h2>
        <h2>博主性别:{{sex}}</h2>
        <h2>博主年龄:{{age}}</h2>
    </div>
</template>
<script>
    export default {
        //组件名命名为Student
        name:'Student',
        data() {
            return {
                msg:'我是一名CSDN博主'
            }
        },
        //方式一:简单声明接收
        props:['name','sex',"age"]
​
        //方式二:接收的同时对数据进行类型限制
        props:{
            name:String,
            age:Number,
            sex:String
        } 
​
        //方式三:接收的同时对数据:进行类型限制+默认值的指定+必要性的限制
        props:{
            name:{
                type:String, //name的类型是字符串
                required:true, //name是必要的
            },
            age:{
                type:Number,
                default:99 //默认值
            },
            sex:{
                type:String,
                required:true
            }
        }
    }
</script>

Vue中 组件间的通信,前端,vue.js,javascript,前端,前端框架

分别运行以上代码提供的三种方式运行的效果图如上,三种方式都能够让数据在页面上进行显示。但是其中涉及到一些问题。图二为采用方式二来接收传入的数据时的控制台出现的错误,虽然能够在页面上看到数据,但是已经存在问题了,因为我们在接收数据时规定了age属性传入的数据的类型为number类型。

但是我们在传值时,编写了age="5", 因此传入的5则为字符串。那该如何解决呢?只需要在age前面加上冒号。对其进行绑定,绑定之后双引号之中的东西都会当成是JS的表达式去解析,因此,解析之后就是纯粹的数字5,因此就能够解决相应的问题。

现在我在增加一个要求,在页面上增加一个按钮通过点击之后来实现页面上的年龄加一的效果。对应代码如下:

<template>
    <div>
        <h1>{{msg}}</h1>
        <h2>博主姓名:{{name}}</h2>
        <h2>博主性别:{{sex}}</h2>
        <h2>博主年龄:{{MyAge}}</h2>
        <button @click="updateAge">年龄加一</button>
    </div>
</template>
​
<script>
    export default {
        name:'Student',
        data() {
            return {
                msg:'我是一名CSDN博主',
                MyAge:this.age
            }
        },
        methods: {
            updateAge(){
                this.MyAge++
            }
        },
        //简单声明接收
        props:['name','age','sex'] 
    }
</script>

Vue中 组件间的通信,前端,vue.js,javascript,前端,前端框架

效果能够正常显示。看了以上的代码可能会有小伙伴会问,为啥子组件接收到的age数据不直接修改呢,直接修改也能够实现相应的效果。为啥还需要另一个设置MyAge来接收它,再修改MyAge的值呢?这时候就需要注意一下以下的注意事项了。

注意:props是只读的,Vue底层会监测你对props的修改,如果进行了修改,就会发出警告,若业务需求确实需要修改,那么请复制props的内容到data中一份,然后去修改data中的数据。

子组件==>父组件

实现方法一:通过父组件给子组件传递函数类型的props,从而实现子组件给父组件传递数据。在前面我们已经对props有了一定的了解了,那么现在我们就来通过代码实现吧!

案例:School组件有学校名以及学校地址两个信息,现在需要实现App父组件可以接收到School子组件传过来的学校名。

App.vue(父组件)

<template>
    <div class="app">
        <!-- 通过父组件给子组件传递函数类型的props实现:子给父传递数据 -->
        <School :getSchoolName="getSchoolName"/>
    </div>
</template>
​
<script>
    import School from './components/School'
    export default {
        name:'App',
        components:{School},
        methods: {
            getSchoolName(name){
                console.log('App收到了学校名:',name)
            }
        }
    }
</script>
​
<style scoped>
    .app{
        background-color: gray;
        padding: 5px;
    }
</style>

在App父组件中,定义了一个getSchoolName函数,并为子组件传递了该函数。

School.vue(子组件)

<template>
    <div class="school">
        <h2>学校名称:{{name}}</h2>
        <h2>学校地址:{{address}}</h2>
        <button @click="sendSchoolName">把学校名给App</button>
    </div>
</template>
​
<script>
    export default {
        name:'School',
        props:['getSchoolName'],
        data() {
            return {
                name:'史莱克学院',
                address:'天斗帝国',
            }
        },
        methods: {
            sendSchoolName(){
                this.getSchoolName(this.name)
            }
        },
    }
</script>
​
<style scoped>
    .school{
        background-color:rgb(212, 237, 210);
        padding: 5px;
    }
</style>

子组件使用props配置项接收了getSchoolName函数,在sendSchoolName函数中调用传过来的函数,并传入学校名。并为按钮绑定getSchoolName点击事件。通过点击之后来实现向父组件传递学校名的目的。对应的实现效果如下:

Vue中 组件间的通信,前端,vue.js,javascript,前端,前端框架



实现方法二:若子组件想要传数据给父组件,还可以使用组件的自定义事件。使用场景为:若A是父组件,B是子组件,B想给A传数据,那么就要在A中给B绑定自定义事件(事件的回调在A中)。

绑定自定义事件有如下的两种方式:

第一种方式,在父组件中:<Demo @自定义事件名="test"/><Demo v-on:自定义事件名="test"/>

案例还是上面的,通过修改第一种方式的自定义事件对应的代码如下:

App.vue(父组件)

<template>
    <div class="app">
        <!-- 通过父组件给子组件绑定一个自定义事件实现:子给父传递数据(第一种写法,使用@或v-on) -->
        <School @showName="getSchoolName"/>
    </div>
</template>
​
<script>
    import School from './components/School'
    export default {
        name:'App',
        components:{School},
        methods: {
            getSchoolName(name){
                console.log('App收到了学校名:',name)
            }
        },
    }
</script>
​
<style scoped>
    .app{
        background-color: gray;
        padding: 5px;
    }
</style>
​

School.vue(子组件)

<template>
    <div class="school">
        <h2>学校名称:{{name}}</h2>
        <h2>学校地址:{{address}}</h2>
        <button @click="sendSchoolName">把学校名给App</button>
    </div>
</template>
​
<script>
    export default {
        name:'School',
        data() {
            return {
                name:'史莱克学院',
                address:'天斗帝国',
            }
        },
        methods: {
            sendSchoolName(){
                //触发School组件实例身上的showName事件
                this.$emit('showName',this.name)
            }
        },
    }
</script>
​
<style scoped>
    .school{
        background-color:rgb(212, 237, 210);
        padding: 5px;
    }
</style>

实现效果如下:能够正常的显示出来!

Vue中 组件间的通信,前端,vue.js,javascript,前端,前端框架

第二种方式,只是在父组件中换一种绑定事件的方式,只需要修改父组件中代码:

<template>
	<div class="app">
		<!-- 通过父组件给子组件绑定一个自定义事件实现:子给父传递数据(第二种写法,使用ref) -->
		<School ref="school" />
	</div>
</template>

<script>
	import School from './components/School'
	export default {
		name:'App',
		components:{School},
		methods: {
			getSchoolName(name){
				console.log('App收到了学校名:',name)
			}
		},
		mounted() {
			this.$refs.school.$on('showName',this.getSchoolName) //绑定自定义事件
		},
	}
</script>

<style scoped>
	.app{
		background-color: gray;
		padding: 5px;
	}
</style>

实现效果与之上的相同。关于自定义事件的其他知识点,我就不在这里过多赘述,毕竟主要是分享它如何实现子组件向父组件传数据。

注意:通过this.$refs.xxx.$on('atguigu',回调)绑定自定义事件时,回调要么配置在methods中,要么用箭头函数,否则this指向会出问题!

全局事件总线

全局事件总线是一种组件间通信的方式,适用于任意组件间通信。

1.安装全局事件总线:

new Vue({
    ......
    beforeCreate() {
        Vue.prototype.$bus = this //安装全局事件总线,$bus就是当前应用的vm
    },
    ......
}) 

2.使用事件总线:

  • 接收数据:A组件想接收数据,则在A组件中给$bus绑定自定义事件,事件的回调留在A组件自身。
methods(){
  demo(data){......}
}
......
mounted() {
  this.$bus.$on('xxxx',this.demo)
}
  • 提供数据:this.$bus.$emit('xxxx',数据)

3.最好在beforeDestroy钩子中,用$off去解绑当前组件所用到的事件。

案例:现有两个兄弟组件,分别是Student组件以及School组件,要实现Student组件给School组件传送数据。对应的实现代码如下:

main.js入口文件,需要先安装全局事件总线。

//引入Vue
import Vue from 'vue'
//引入App
import App from './App.vue'
//关闭Vue的生产提示
Vue.config.productionTip = false
​
//创建vm
new Vue({
    el:'#app',
    render: h => h(App),
//安装全局事件总线
    beforeCreate() {
        Vue.prototype.$bus = this 
    }
})

提供数据方组件代码如下:

<template>
    <div class="student">
        <h2>学生姓名:{{name}}</h2>
        <h2>学生性别:{{sex}}</h2>
        <button @click="sendStudentName">把学生名给School组件</button>
    </div>
</template>
​
<script>
    export default {
        name:'Student',
        data() {
            return {
                name:'N-A',
                sex:'男',
            }
        },
        methods: {
            //提供数据
            sendStudentName(){
                this.$bus.$emit('hello',this.name)
            }
        },
    }
</script>
​
<style  scoped>
    .student{
        background-color:rgb(212, 237, 210);
        padding: 5px;
        margin-top: 30px;
    }
</style>

接收数据方组件代码如下:

<template>
    <div class="school">
        <h2>学校名称:{{name}}</h2>
        <h2>学校地址:{{address}}</h2>
    </div>
</template>
​
<script>
    export default {
        name:'School',
        data() {
            return {
                name:'史莱克学院',
                address:'天斗帝国',
            }
        },
        //绑定一个hello事件,用于接收数据
        mounted() {
            this.$bus.$on('hello',(data)=>{
                console.log('我是School组件,收到了数据',data)
            })
        },
        //用$off去解绑<span style="color:red">当前组件所用到的</span>事件。
        beforeDestroy() {
            this.$bus.$off('hello')
        },
    }
</script>
​
<style scoped>
    .school{
        background-color:rgb(212, 237, 210);
        padding: 5px;
    }
</style>

实现效果如下,兄弟组件之间实现了数据的传递。

Vue中 组件间的通信,前端,vue.js,javascript,前端,前端框架

消息订阅与发布

消息订阅与发布是一种组件间通信的方式,适用于任意组件间通信。使用方式如下:

1.安装pubsub:npm i pubsub-js

2.引入: import pubsub from 'pubsub-js'

3.接收数据:A组件想接收数据,则在A组件中订阅消息,订阅的回调留在A组件自身。

methods(){
  demo(data){......}
}
......
mounted() {
  this.pid = pubsub.subscribe('xxx',this.demo) //订阅消息
}

4.提供数据:pubsub.publish('xxx',数据)

5.最好在beforeDestroy钩子中,用PubSub.unsubscribe(pid)去取消订阅。

该方式与上述的全局事件总线比较相似,主要是不需要用到$bus,而是替换成了pubsub。

对以上的代码进行修改之后如下:

提供数据方组件代码如下:

<template>
    <div class="student">
        <h2>学生姓名:{{name}}</h2>
        <h2>学生性别:{{sex}}</h2>
        <button @click="sendStudentName">把学生名给School组件</button>
    </div>
</template>
​
<script>
    import pubsub from 'pubsub-js'
    export default {
        name:'Student',
        data() {
            return {
                name:'N-A',
                sex:'男',
            }
        },
        methods: {
            sendStudentName(){
                pubsub.publish('hello',this.name)
            }
        },
    }
</script>
​
<style  scoped>
    .student{
        background-color:rgb(212, 237, 210);
        padding: 5px;
        margin-top: 30px;
    }
</style>

接收数据方组件代码如下:

<template>
    <div class="school">
        <h2>学校名称:{{name}}</h2>
        <h2>学校地址:{{address}}</h2>
    </div>
</template>
​
<script>
    import pubsub from 'pubsub-js'
    export default {
        name:'School',
        data() {
            return {
                name:'史莱克学院',
                address:'天斗帝国',
            }
        },
        mounted() {
            this.pubId = pubsub.subscribe('hello',(msgName,data)=>{
                console.log(data)
            })
        },
        beforeDestroy() {
            pubsub.unsubscribe(this.pubId)
        },
    }
</script>
​
<style scoped>
    .school{
        background-color:rgb(212, 237, 210);
        padding: 5px;
    }
</style>

实现效果如下:

Vue中 组件间的通信,前端,vue.js,javascript,前端,前端框架

好啦,本文就到这里结束了,你学到了吗?若有任何的疑问或者问题欢迎各位在评论区或者私信找我一起交流学习!文章来源地址https://www.toymoban.com/news/detail-648259.html

到了这里,关于Vue中 组件间的通信的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 前端实现websocket通信讲解(vue2框架)

    前言 :最近接到的需求是前端需要实现一个全局告警弹窗,如果使用ajax请求http接口只能用定时器定时去请求是否有告警,这样既消耗资源,又不能实时监测到告警信息。所以这个时候就可以采用websocket来实现通信,因为websocket不用请求一次才响应一次,它可以实现服务器主

    2024年02月12日
    浏览(26)
  • 【js&vue】联合gtp仿写一个简单的vue框架,以此深度学习JavaScript

    lifecycle.js 注解: this.$options.beforeMount.call(this);与 this.$options.beforeMount();有什么区别: call(this)  的作用是将当前对象( this )作为参数传递给  beforeMount  方法,使得在  beforeMount  方法内部可以通过  this  访问到当前对象的上下文 直接调用了  beforeMount  方法,没有指定上下

    2024年02月09日
    浏览(42)
  • vue.js前端框架应用案例

    Vue.js 是一种流行的前端框架,它可以帮助开发者构建单页应用(SPA)和复杂的用户界面。以下是几个 Vue.js 的案例,涵盖了不同领域的应用: Vue.js 官方文档 :Vue.js 的官方文档本身就是一个使用 Vue.js 构建的项目。它展示了 Vue.js 的各种功能和最佳实践,包括组件、指令、混

    2024年02月21日
    浏览(31)
  • 前端开发 5: Vue.js 框架

    在前端开发中,Vue.js 是一个流行且灵活的 JavaScript 框架,用于构建用户界面。它采用了组件化的开发方式,使得前端开发更加模块化和可维护。在本篇博客中,我将为你介绍 Vue.js 的基础知识和常用技巧,帮助你更好地掌握前端开发中的框架部分。 Vue.js 是一个轻量级的 Jav

    2024年01月19日
    浏览(33)
  • Web前端 ---- 【Vue】(组件)父子组件之间的通信一文带你了解

    目录 前言 父组件传子组件 ---- props 给要传递数据的子组件绑定要传过去的属性及属性值 在子组件中使用props配置项接收 props配置项 子组件传父组件 ---- 组件的自定义事件 子组件向父组件传递数据 通过代码来绑定自定义事件 本文将介绍在Vue中父子组件如何进行通信 这里先介

    2024年02月05日
    浏览(34)
  • 从javascript到vue再到react:前端开发框架的演变

    目录 JavaScript: 动态语言的基础 JavaScript:Web开发的起点 Vue.js: 渐进式框架的兴起 Vue.js:简洁、高效的前端框架 React.js: 声明式UI的革新 React.js:强大、灵活的前端框架 演变之路与未来展望 演变过程 当提到前端开发中的框架时,JavaScript、Vue.js和React.js是三个最常见的名词。它

    2024年02月07日
    浏览(41)
  • 【热门前端【vue框架】】——vue框架和node.js的下载和安装保姆式教程

    👨‍💻个人主页 :@程序员-曼亿点 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 曼亿点 原创 👨‍💻 收录于专栏 :vue框架开发   Vue.js 是一款流行的 JavaScript 前端框架,它以其简单、灵活和高效的特性,成为了构建现代化 Web 应用程序的首选工具

    2024年04月27日
    浏览(44)
  • 常见的web前端开发框架:Vue.js

            常见的Web前端开发框架包括Bootstrap、Vue.js、React.js、Angular.js等。每个框架都有其独特的特点和优势,开发者可以根据项目的需求和个人的喜好来选择合适的框架。同时,随着技术的不断发展,新的框架和工具也会不断涌现,为Web前端开发带来更多的选择和可能性。

    2024年02月20日
    浏览(36)
  • 探索前端跨组件通信:EventBus在Vue和React中的应用

    本文作者系360奇舞团前端开发工程师 事件总线(Event Bus) 是一种用于组件间通信的模式,通常用于解决组件之间的解耦和简化通信的问题。在前端框架中,如 Vue.js,事件总线是一个常见的概念。基本上,事件总线是一个能够触发和监听事件的机制,使得组件能够在不直接依

    2024年02月02日
    浏览(57)
  • JavaScript框架 Angular、React、Vue.js 的全栈解决方案比较

    在 Web 开发领域,JavaScript 提供大量技术栈可供选择。其中最典型的三套组合,分别是 MERN、MEAN 和 MEVN。前端框架(React、Angular 和 Vue)进行简化比较。 MERN 技术栈包含四大具体组件: MongoDB:一款强大的 NoSQL 数据库,以灵活的 JSON 格式存储数据。 Express.js:一套极简但强大的

    2024年02月03日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包