Vue2与Vu3组件通信方式总结

作者&投稿:耿砍 (若有异议请与网页底部的电邮联系)
~

我们都知道Vue作为一个轻量级的低门槛入门前端框架,其核心就是组件化开发。Vue就是由多个组件组建成的,组件化是它的精髓,更是它的强大之处。各组件实例之间是相互独立的,这也就意味着不同组件之间数据是无法相互共用。

但实际项目开发中,我们时常需要其他组件的数据,为此诞生了组件通信的问题。针对组件之前的关系:父子、兄弟、子孙的不同选用的数据传输方式也不一样,今天就来做个总结。

Vue2组件通信

父组件向子组件传值

props

父组件以属性的方式传值给子组件

子组件通过props方式接收数据

在父组件中引入子组件并绑定fatherData自定义属性

<Son:fatherData="fatherData"></Son><script>importSonfrom'@/components/son'exportdefault{name:'Father',components:{Son},data(){return{fatherData:'我是父组件向子组件传递的值-props方式'}}}</script>

在子组件中使用props接收父组件传递的数据,props里的名字跟父组件定义的属性名一致

<template><div>我是父组件的数据:{{fatherData}}</div><div>我是父组件传递修改后的数据:{{mydata}}</div></template><script>exportdefault{name:'Son',props:{fatherData:{type:String,default:''}}data(){mydata:'公众号:初级前端仔'+this.fatherData},watch:{fatherData(newVal){this.mydata='公众号:初级前端仔'+newVal}},}</script>

因为Vue的单向数据流机制,子组件不能够直接去修改父组件传递的值修改的,否则能改的话那父组件的值就被“污染”了。

但是子组件内想要修改父组件传过来的值却不“污染”父组件的话,可以在子组件内定义一个变量mydata去接收fatherData数据,并使用watch监听fatherData数据的变更。

子组件向父组件传值

$emit()

子组件绑定自定义事件

使用$emit()触发更改数据

<el-button@click="handleEmit">告诉父组件我要更改数据啦</el-button><script>exportdefault{name:'Son',methods:{handleEmit(){this.$emit('triggerEmit','我是来自子组件的数据')}}}</script>

父组件定义并绑定子组件传递的triggerEmit事件

triggerEmit事件名需跟子组件$emit()的事件名一致

<Son@triggerEmit="changeData"></Son><script>importSonfrom'@/components/son'exportdefault{name:'Father',components:{Son},methods:{changeData(name){console.log(name)//=>我是来自子组件的数据}}}</script>

使用场景:通用组件更改内部的数据时告知父组件此时数据状态。

兄弟之前传值

$emit和props结合的方式

父组件引入两个子组件

父组件充当一个桥梁作用

<childA:myName="name"></ChildA><ChildB:myName="name"@changeName="editName"></ChildB>exportdefault{data(){return{name:'初级前端仔'}},methods:{editName(name){this.name=name}}}

在子组件B中接收变量和绑定触发事件

<p>姓名:{{myName}}</p><button@click="changeName">修改姓名</button><script>exportdefault{props:{myName:String},methods:{changeName(){this.$emit('changeName','公众号:初级前端仔')}}}</script>

父组件接受到B组件的changeName事件,就会执行editName事件并修改name的数据,利用响应式机制,父组件就会将最新的name值传递给组件A,组件A渲染最新的name值

<p>姓名:{{newName}}</p><script>exportdefault{props:{myName:String}}</script>

至今组件B的更改就通过父组件传达到给组件A完成数据的传递

bus方式

创建一个公共的bus.js文件

暴露出Vue实例

importVuefrom"vue"exportdefaultnewVue()

在需要组件通信的组件中都引入该文件

<template><div><div>我是通信组件A</div><el-button@click="changeName">修改姓名</el-button></div></template<script>import{EventBus}from"../bus.js"exportdefault{data(){return{}},methods:{changeName(){EventBus.$emit("editName",'初级前端仔,点点关注!')}}}</script>

另外一个组件中同样引入bus.js文件,通过$on监听事件回调

<template><div>我是通信组件B</div></template<script>import{EventBus}from"../bus.js"exportdefault{data(){return{}},mounted:{EventBus.$on('editName',(name)=>{console.log(name)//=>初级前端仔,点点关注!})}}</script>

通过引入bus.js文件,使得EventBus获得Vue实例,其实是跟上一种方式是一样的。

直接访问组件实例

parent/children

子组件通过$parent获得父组件实例

父组件通过$children获得子组件实例数组

<template><div>我是父组件的数据:{{fatherData}}</div><div>我是父组件传递修改后的数据:{{mydata}}</div></template><script>exportdefault{name:'Son',props:{fatherData:{type:String,default:''}}data(){mydata:'公众号:初级前端仔'+this.fatherData},watch:{fatherData(newVal){this.mydata='公众号:初级前端仔'+newVal}},}</script>0

由图可知this.$parent可以获取到父组件的方法、data的数据等,并可以直接使用和执行。

<template><div>我是父组件的数据:{{fatherData}}</div><div>我是父组件传递修改后的数据:{{mydata}}</div></template><script>exportdefault{name:'Son',props:{fatherData:{type:String,default:''}}data(){mydata:'公众号:初级前端仔'+this.fatherData},watch:{fatherData(newVal){this.mydata='公众号:初级前端仔'+newVal}},}</script>1

正如你所看到的,父组件是在mounted()生命周期中获取子组件实例的,并且获取的实例是一个数组形式

所以需要this.$children[0]才可以获取某个组件实例,并调用组件方法和数据

$refs

父组件使用$refs获得组件实例

<template><div>我是父组件的数据:{{fatherData}}</div><div>我是父组件传递修改后的数据:{{mydata}}</div></template><script>exportdefault{name:'Son',props:{fatherData:{type:String,default:''}}data(){mydata:'公众号:初级前端仔'+this.fatherData},watch:{fatherData(newVal){this.mydata='公众号:初级前端仔'+newVal}},}</script>2

这样父组件就可以直接使用this.$refs.xx获取子组件的实例了

多组件或深层次组件通信

provide/inject(提供/注入)

父组件使用provide注入数据

子组件使用inject使用数据

例如,如果我们有这样的层次结构:

那么我们的provide/inject就可以派上用场了

<template><div>我是父组件的数据:{{fatherData}}</div><div>我是父组件传递修改后的数据:{{mydata}}</div></template><script>exportdefault{name:'Son',props:{fatherData:{type:String,default:''}}data(){mydata:'公众号:初级前端仔'+this.fatherData},watch:{fatherData(newVal){this.mydata='公众号:初级前端仔'+newVal}},}</script>3

至此provideName这个变量可以提供给它其下的所有子组件,包括曾孙、孙子组件等,只需要使用inject就能获取数据

<template><div>我是父组件的数据:{{fatherData}}</div><div>我是父组件传递修改后的数据:{{mydata}}</div></template><script>exportdefault{name:'Son',props:{fatherData:{type:String,default:''}}data(){mydata:'公众号:初级前端仔'+this.fatherData},watch:{fatherData(newVal){this.mydata='公众号:初级前端仔'+newVal}},}</script>4

这个方法的好处是:

父组件不需要知道哪个组件使用它提供出去的数据

子附件不需要知道这个数据从哪里来

vuex状态管理

相当于一个公共数据的仓库

提供一些方法管理仓库数据

关于这个的话直接去看官网吧vuex[https://vuex.vuejs.org/zh]

总结

至此vue2中组件通信的方式就总结完了,主要分为三大类:

.父子通信:父向子传递数据通过props,子向父传递数据通过$emit事件,父链/子链使用parent/children,直接访问组件实例用refs

.兄弟通信:bus、Vuex

.跨级通信:bus、Vuex、provide/inject

Vue3组件通信props和emit

setup函数可以接受两个参数,prop和context,其中context可以解构出emit实例

<template><div>我是父组件的数据:{{fatherData}}</div><div>我是父组件传递修改后的数据:{{mydata}}</div></template><script>exportdefault{name:'Son',props:{fatherData:{type:String,default:''}}data(){mydata:'公众号:初级前端仔'+this.fatherData},watch:{fatherData(newVal){this.mydata='公众号:初级前端仔'+newVal}},}</script>5

Vue3中没有this的概念了,所以就不会有this.$emit存在,所以可以从setup传入的context结构出emit实例,从而派发事件给父组件

<template><div>我是父组件的数据:{{fatherData}}</div><div>我是父组件传递修改后的数据:{{mydata}}</div></template><script>exportdefault{name:'Son',props:{fatherData:{type:String,default:''}}data(){mydata:'公众号:初级前端仔'+this.fatherData},watch:{fatherData(newVal){this.mydata='公众号:初级前端仔'+newVal}},}</script>6

ref

Vue3我们可以从Vue中导出ref方法,得到子组件的实例

<template><div>我是父组件的数据:{{fatherData}}</div><div>我是父组件传递修改后的数据:{{mydata}}</div></template><script>exportdefault{name:'Son',props:{fatherData:{type:String,default:''}}data(){mydata:'公众号:初级前端仔'+this.fatherData},watch:{fatherData(newVal){this.mydata='公众号:初级前端仔'+newVal}},}</script>7

通过,在子组件声明ref属性,属性值必须和constbtnRef=ref(null)这里声明的变量名一致,否则会报错,拿到子组件实例后就可以直接调用组件的sendParent方法了

这里使用的btnRef.value?.是可选链操作符语法,代表?前面的值为true才继续执行后面的语句,感兴趣的小伙伴可以点击去看看,这里就不赘叙了

<template><div>我是父组件的数据:{{fatherData}}</div><div>我是父组件传递修改后的数据:{{mydata}}</div></template><script>exportdefault{name:'Son',props:{fatherData:{type:String,default:''}}data(){mydata:'公众号:初级前端仔'+this.fatherData},watch:{fatherData(newVal){this.mydata='公众号:初级前端仔'+newVal}},}</script>8

子组件只提供一个方法,供父组件获取实例后执行,也可以执行更为复杂的数据通信

provide/inject

这里的用法跟Vue2差异不大,直接上案例吧

<template><div>我是父组件的数据:{{fatherData}}</div><div>我是父组件传递修改后的数据:{{mydata}}</div></template><script>exportdefault{name:'Son',props:{fatherData:{type:String,default:''}}data(){mydata:'公众号:初级前端仔'+this.fatherData},watch:{fatherData(newVal){this.mydata='公众号:初级前端仔'+newVal}},}</script>9

直接使用provide将需要传递的数据注入,不需要考虑谁去获取

<el-button@click="handleEmit">告诉父组件我要更改数据啦</el-button><script>exportdefault{name:'Son',methods:{handleEmit(){this.$emit('triggerEmit','我是来自子组件的数据')}}}</script>0

子孙组件使用inject获取到父组件注入的数据

感谢


给我个卡巴斯基6.0的激活码
Z3H7H-TUZRA-MS863-ZQV4U 3NQ5K-5QA7Z-SFXBZ-CSHHW U7YSF-Y8Q7K-31MCC-5ASSH QCXW2-E4TRF-SGAGQ-D9GMP PRHHP-X5ZDC-46GCR-DX1UE 9NNJM-Q173U-1WUW4-FXPXE………98820:FHJ4S-R1XEX-5BW3T-JYEKBFHJ4S-R1XEX-5BW3T-JYEKB98872:E81H5-97UMH-2W21C-81CK2E81H5-97UMH-2W21C-81CK2989...

名侦探柯南剧场版漆黑的追踪者没原声版的?
[名侦探柯南剧场版]漆黑的追迹者_2.mp4:FLASHGET:\/\/W0ZMQVNIR0VUXWh0dHA6Ly84LmRvd24ueTgwcy5jb206OTIwLzA5MTAvW8P71ezMvb\/CxM++57OhsOZdxuG62rXE17e8o9XfL1vD+9XszL2\/wsTPvuezobDmXcbhutq1xNe3vKPV318yLm1wNFtGTEFTSEdFVF0=&80410&1279895828 [名侦探柯南剧场版]漆黑的追迹者_3.mp4:F...

求一个卡巴斯基序列号
QCXW2-E4TRF-SGAGQ-D9GMP --- PRHHP-X5ZDC-46GCR-DX1UE --- 9NNJM-Q173U-1WUW4-FXPXE --- 8QP3X-VMNQG-WSPP4-3ZRSB ---

vue3官网文档?
创建好vue3项目的第帆旁一步就是安装vue-router,因为vite默认并没有安装的。参考官网:安装|VueRouter(vuejs.org) 然后在src目录下创建router目录,并添加2个文件index.js,routes.js. 这里就要画重点了。因为vue3的过度动画transition组件跟vue2比变化还是比较大的。主要是以下的2各方面: 1.transition组件在vue2中...

vue3官方文档pdf(vue30pdf)
一、Vue3 Vue3中文文档[1] 2.x全局API3.x实例API(app)Vue.configapp.configVue.config.productionTip无Vue.config.ignoredElementsapp.config.isCustomElementVue.componentapp.componentVue.directiveapp.directiveVue.mixinapp.mixinVue.useapp.useVue.prototypeapp.config.globalProperties 引入此配置选项的目的是支持原生...

vue界面看到原信息后显示新信息
您要问的是ue界面看到原信息后显示新信息怎么办吗?方法如下:1、在数据改动的代码后加this.$forceUpdate。2、添加this.$forceUpdate();进行强制渲染,效果实现显示新信息。

求卡巴基斯6。0的激活码
随意一个即可 我用的是第一个:9JZJH-9DJY2-ZYPAY-C68GM 589FY-XR6U9-1PWHK-NA7EY R2EDV-CYTTY-AWS83-2C62U 5X7BT-THTWR-GEGTU-9EP1B FM1YW-CGXJS-9ZM5P-9C197 WDVWG-6ZRTJ-M9TYJ-5G7JJ K5XJH-FCH26-4A3EA-RPTAY 99X71-BZMJ8-NWPRE-YECHC 参考资料:http:\/\/down.dzf...

高县15796308351: vue2.0中子组件之间怎么传递方法 -
东郭杨法斯: 建议好好阅读官方文档,里面说的很详细 组件之间数据传递有三种:1. 父子组件:属性向下事件向上.也就是说父组件是通过属性传递给自组件,然而自组件是通过事件的方式传递给父组件.2. 非父子组件:通过eventBus.3. vuex这个状态管理

高县15796308351: vue如何使用vuex,vuex是vuex.js文件吗 -
东郭杨法斯: vue有自己的脚手架构建工具vue-cli,使用起来非常方便,使用webpack来集成各种开发便捷工具,比如:代码热更新,修改代码之后网页无刷新改变,对前端开发来说非常的方便PostCss,再也不用去管兼容性的问题了,只针对chrome写css代...

高县15796308351: vue.js中两个component之间如何调用其中的方法? -
东郭杨法斯: react是单向数据流的.但是为了特殊需要,提供了mixin去做双向通信,这违反了react的本质,一般不推荐用,官网也对此做出了警告.两个毫无关系的组件A B,通信是可以的.A点一个button去设置B里的datastoreB,B里getInitial或者renderDidMount里监听它的datastroeB,如果datastroeB有变化,就产生响应的行为.我目前用的是microEvent.js去设置datastoreB的对象上的监听.

高县15796308351: vue2父组件怎么调用子组件的方法 -
东郭杨法斯: vue中的组件有个ref属性,你可以理解成组件的id,而父组件这有个属性值叫$refs,可以取出所有带ref属性的组件.然后就可以通过this.$refs.xxx访问到子组件.xxxx即为你的组件的ref属性的值!里面的属性或者方法都可以直接取了!

高县15796308351: Vue2中怎么实现Vue1中的广播事件 -
东郭杨法斯: DOM事件在Vue中为DOM元素绑定事件的具体方法在文章中的 方法与事件处理器 章节,通过v-on指令或事件语法糖 @ 为DOM元素绑定事件.Vue解析组件模板后,在绑定更新 v-on 指令时会为DOM元素绑定事件(当然如果元素为 iframe ,会...

高县15796308351: 前端都学什么内容呀?
东郭杨法斯: 这里根据行业变化和企业用人需求整理了一份web前端系统全面的学习路线,主要学习以下内容:第一阶段:专业核心基础阶段目标:1. 熟练掌握HTML5、CSS3、Less、Sass、响应书布局、移动端开发.2. 熟练运用HTML+CSS特性完成页面...

高县15796308351: vue.js同一组件两个方法之间怎么传递参数 -
东郭杨法斯: 用Vuex 将数据源存在 store里的 state 中. 可以实现 2个组件 同时调取统一数据源

高县15796308351: Vue2 父子组件props传数组 怎么双向绑定 -
东郭杨法斯: 子组件在props中定义数据,然后父组件传数据过去,例如: 子组件: props: { show: { default: false } } 父组件: //test是子组件名字 parentShow是父组件定义的data数据

高县15796308351: vue.js和angularjs的区别 -
东郭杨法斯: 选择 Vue 而不选择 Angular,有下面几个原因,当然不是对每个人都适合: 在 API 与设计两方面上 Vue.js 都比 Angular 简单得多,因此你可以快速地掌握它的全部特性并投入开发. Vue.js 是一个更加灵活开放的解决方案.它允许你以希望的方...

高县15796308351: vueling的附加费,vueling的Tarifa Optim?
东郭杨法斯: VUELING的票一般都包含一件23KG免费托运行李的.早上7:50的飞机,6:30之前到就很保险了,不过要注意不要去错航站楼.

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网