vue中组件之间如何通信(vue组件之间互相调用方法)

作者:电脑培训网 2024-05-07 08:51:33 252

Vue中组件间通信的六大方法-总结方式一:props/$emit

父组件向子组件传值

vue中组件之间如何通信(vue组件之间互相调用方法)

通过一个例子,讲解父组件如何向子组件传值:如何获取父组件App.vue中的数据子组件Users.vueusers:['Henry','Bucky','Emily']

注意:父组件通过props向下传递数据给子组件。注意:组件中的数据有三种形式:data、props、compute

//app.vue父组件模板divid='app'usersv-bind:users='users'/users//前者自定义名称方便子组件调用,后者需要传递数据名称/div/templatescriptimportUsersfrom'./Components/Users'exportdefault{name:'App',data(){return{users:['Henry','Bucky','Emily']}},Components:{'users':Users}}——————————————33354——33354————————————————————————————————————————————————33354——————————//users子组件模板divclass='hello'ulliv-for='userinusers'{{user}}/li//遍历传入的值,然后渲染到页面/ul/div/templatescriptexportdefault{name:'HelloWorld',props:{users:{//这是父组件中子标签的自定义名称type:Array,required:true}}}/script

子组件向父组件传值

我们用一个例子来说明子组件如何向父组件传递值:当我们点击“Vue.jsDemo”时,子组件向父组件传递值,文字从“Avalueispassed”变为”改为““子向父组件传递值”,实现子组件向父组件传递值

注意:子组件通过事件向父组件发送消息。事实上,子组件将自己的数据发送给父组件。

//子组件模板头h1@click='changeTitle'{{title}}/h1//绑定一个点击事件/header/templatescriptexportdefault{name:'app-header',data(){return{title:'Vue.jsDemo'}},methods:{changeTitle(){this.$emit('titleChanged','子组件将值传递给父组件');//自定义事件传递值"子组件将值传递给父组件"}}/script——————————————————————————————————————————————333543354———————————————————————————————————————//父组件模板divid='app'app-headerv-on3第3360章titleChanged='updateTitle'/app-header//与子组件titleChanged自定义事件一致//updateTitle($event)接受传入的文本h2{{title}}/h2/div/templatescriptimport'./components/Header'exportdefault{name:'App',data(){return{title:'passesavalue'}},methods:{updateTitle(e){//声明此函数this.title=e;}},Components:{'app-header':Header,}}/script

方式二:eventBus

使用一个空的Vue实例作为中央事件总线,用它来触发事件并监听事件,巧妙而轻量地实现任意组件之间的通信,包括父子、兄弟、跨级。当我们的项目比较大的时候,我们可以选择vuex这个比较好的状态管理方案

使用方式

letEvent=newVue();Event.$emit(eventname,data);Event.$on(eventname,data={});//或者在main.js中全局定义并使用Vue。原型.$bus=newVue();

共有三个组件,即A、B、C组件。组件C如何获取组件A或B的数据?

注意:$on监听自定义事件data-a和data-b。因为有时候不确定事件什么时候会被触发,所以通常是在mounted或者created的hook中监听。

divid='itany'my-a/my-amy-b/my-bmy-c/my-c/divtemplateid='a'divh3A组件:{{name}}/h3按钮@click='发送'发送数据到C组件/button/div/templatetemplateid='b'divh3B组件:{{age}}/h3button@click='send'将数组发送到C组件/button/div/templatetemplateid='c'divh3Ccomponent:{{name}},{{age}}/h3/div/templatescriptvarEvent=newVue();//定义一个空的Vue实例varA={template:'#a',data(){return{name:'tom'}},methods:{send(){Event.$emit('data-a',this.name);}}}varB={template:'#b',data(){return{age:20}},methods:{send(){Event.$emit('data-b',this.age);}}}varC={template:'#c',data(){return{name:'',age:''}},mounted(){//执行Event.$on('data-a',name={this.name=name;//模板编译完成后,箭头函数内部不会生成新的this,如果这里不使用=,this指的是Event})Event.$on('data-b',年龄={this.age=年龄;})}}varvm=newVue({el:'#itany',components:{'my-a':A,'my-b':B,'my-c':C}});/脚本

方式三:Vuex

Vue组件:Vue组件。在HTML页面上,负责接收用户操作等交互行为,并执行dispatch方法触发相应的action进行响应。

dispatch:操作行为触发方法,是唯一可以执行动作的方法。

actions:操作行为处理模块,由组件中的$store.dispatch('actionname',data1)触发。然后commit()触发变异调用并间接更新状态。负责处理Vue组件收到的所有交互。包含同步/异步操作,支持多个同名方法,并按照注册顺序触发。对后端API的请求在此模块中执行,包括触发其他操作和提交突变。该模块提供了Promise封装来支持动作链触发。

commit:状态变更提交操作方法。提交突变是执行突变的唯一方法。

Mutations:状态改变操作方法,由actions中的commit('mutationname')触发。这是在Vuex中修改状态的唯一推荐方法。该方法只能执行同步操作,并且方法名只能是全局唯一的。运行过程中会暴露一些钩子,用于状态监控等。

state:页面状态管理容器对象。将数据对象的分散数据集中存储在Vue组件中,全局唯一,进行统一状态管理。页面显示所需的数据就是从该对象中读取的,利用Vue的细粒度数据响应机制进行高效的状态更新。

getters:状态对象读取方法。该模块在图中没有单独列出。它应该包含在渲染中。VueComponents通过该方法读取全局状态对象。

方式四:$attrs/$listeners

当多级组件嵌套需要传递数据时,常用的方法是通过vuex。但如果只是传输数据而没有中间处理的话,使用vuex来处理就有点大材小用了。Vue2.4版本为此提供了另一种方法----$attrs/$listeners$attrs:包含父作用域中的prop无法识别的属性绑定。当组件没有声明任何props时,所有父作用域绑定都将包含在此处,并且可以通过v-bind='$attrs'传递到内部组件。通常与inheritAttrs选项一起使用。$listeners:包含父作用域中的v-on事件侦听器。可以通过v-on='$listeners'//index.vuetemplatedivh2Langglixingzhou/h2child-com1:foo='foo':boo='boo':coo='coo':doo='doo'传入内部组件title='前端工匠'/child-com1/div/templatescriptconstchildCom1=()=import('./childCom1.vue');exportdefault{Components:{childCom1},data(){return{foo:'Javascript',boo:'Html',coo:'CSS',doo:'Vue'};}};/script——————————————————————————————333354——————————————33354————————————————————————————————//childCom1.vuetemplateclass='border'divpfoo:{{foo}}/ppchildCom1的$attrs第:章-com2/div/templatescriptconstchildCom2=()=import('./childCom2.vue');exportdefault{Components:{childCom2},继承Attrs:false,//可以关闭自动挂载到根元素上的属性组件且未在props中声明props:{foo:String//foo被绑定为props属性},created(){console.log(this.$attrs);//{'嘘}}};54————————————————————————————————————————————————33354————//childCom2.vuetemplatedivclass='border'pboo:{{boo}}/ppchildCom2:{{$attrs}}/pchild-com3v-bind='$attrs'/child-com3/div/templatescriptconstchildCom3=()=import('./childCom3.vue');导出默认{Components:{childCom3},继承Attrs:false,props:{boo:String},created(){console.log(this.$attrs);//{'coo':'CSS','doo':'Vue','title':'前端工匠'}}};/script————————————————————————33354——————————————333354————————————————————————————————33354————//childCom3.vuetemplatedivclass='border'pchildCom3:{{$attrs}}/p/div/templatescriptexport默认{props:{coo:字符串,title:字符串}};/脚本

如上图所示,$attrs代表不继承数据的对象,格式为{属性名:属性值}。Vue2.4提供了$attrs和$listeners来传递数据和事件,使得跨级组件之间的通信更加容易。

简单来说:$attrs和$listeners是两个对象。$attrs存储父组件中绑定的非Props属性,$listeners存储父组件中绑定的非原生事件。

方式五:provide/inject

Vue2.2.0有一个新的API。这对选项需要一起使用,以允许祖先组件向其所有后代组件注入依赖,无论组件层次结构有多深,并且在建立上下游关系时始终生效。简而言之:在祖先组件中通过provider提供变量,然后在后代组件中通过inject注入变量。Provide/InjectAPI主要解决跨级组件之间的通信问题,但其使用场景主要是子组件获取上级组件的状态,跨级组件之间建立主动提供和依赖注入的关系。

//A.vueexportdefault{Provide:{name:'乘风破浪'}}-------------------------------------------//B.vueexportdefault{insert:['name'],Mounted(){console.log(this.name);//在波浪中航行}}

可以看到,在A.vue中,我们设置了一个provide:名称,值为Langlixingzhou。它的功能是为其所有子组件提供名称变量。在B.vue中,组件A提供的name变量是通过inject注入的。那么在B组件中,可以通过this.name直接访问这个变量,它的值也是一样的。这就是provide/injectAPI的核心用法。

请注意,提供和注入绑定不是反应性的。这是故意的。但是,如果传入一个可监听的对象,该对象的属性仍然是响应式的----vue官方文档。因此,如果上面A.vue的名称发生变化,B.vue的this.name不会发生变化。改变的依然是在波浪中航行。

provide与inject怎么实现数据响应式

一般来说有两种方法:

提供祖先组件的实例,然后将依赖注入到后代组件中,这样就可以在后代组件中直接修改祖先组件实例的属性。但是这种方法有一个缺点,就是在这个实例上挂载了很多不必要的东西,比如props。方法

使用最新的2.6APIVue.observable优化响应式提供

我们看一个例子:Sun组件D、E、F获取组件A传过来的颜色值,可以实现数据响应变化。即A成分的颜色发生变化后,D、E、F成分的颜色也会发生相应的变化。

//一个组件divh1A组件/h1按钮@click='()=changeColor()'更改颜色/按钮ChildrenB/ChildrenC//div.data(){return{color:'blue'};},//Provide(){//return{//theme:{//color:this.color//这种方式绑定的数据是没有响应的//}//即A组件颜色改变后,分量D,E,F不会改变//};//},Provide(){return{theme:this//方法一:提供祖先组件的实例};},methods:{changeColor(颜色){if(颜色){this.color=颜色;}else{this.color=this.color==='蓝色'?'红色':'蓝色';}}}//方法2:使用最新2.6APIVue.observable来优化响应式provide//Provide(){//this.theme=Vue.observable({//color:'blue'//});//返回{//theme:this.theme//};//},//methods:{//changeColor(color){//if(color){//this.theme.color=color;//}else{//this.theme.color=this.theme.color==='blue'?'红色':'蓝色';//}//}//}————————————————————————————————————————3354————354——————————————————————————————————————//F组件模板功能divclass='border2'h3:style='{color:injections.theme.color}'F组件/h3/div/templatescriptexport默认{注入:{主题:{//功能组件的取值不同default:()=({})}}};/script

虽然provide和inject主要是为高端插件/组件库提供用例,但是如果你能在业务中熟练使用它们,那么你可以达到事半功倍的效果。

方式六:$parent/$children与ref

ref:如果用在普通的DOM元素上,则引用指向DOM元素;如果用在子组件上,则引用指向组件实例$parent/$children:访问父/子实例时需要注意的是:这两个方法都是直接获取组件实例,可以直接调用组件的方法或使用后访问数据。我们先看一个使用ref访问组件的例子

//组件-子组件exportdefault{data(){return{title:'Vue.js'}},methods:{sayHello(){window.alert('Hello');}}}——————————————————————————————————————————————33354————————————————————————3————————//父组件模板组件-aref='comA'/component-a/templatescriptexportdefault{Mounted(){constcomA=this.$refs.comA;console.log(comA.标题);//Vue.jscomA.sayHello();//弹出窗口}}/script————————————————————————————————————————————333354——————————————————————————————————//不过这两种方法的缺点是不能跨层级或者兄弟之间通信//parent.vuecomponent-a/component-acomponent-b/component-b组分-b/组件-b

如果你想访问在Component-a中引用它的页面中的两个Component-b组件,这种情况下,你必须配置额外的插件或工具,例如Vuex和Bus。解决方案

父子书信:

父级通过props向子级传递数据,子级通过事件向父级传递数据;也可以通过母链/子链进行通信;ref还可以访问组件实例;提供/注入API;$属性/$监听器

兄弟通讯:

总线;Vuex

跨层级沟通:

公共汽车;视图;提供/注入API,$attrs/$listeners

相关推荐

  • 福特dfmea培训学校,福特mmog培训

    福特dfmea培训学校,福特mmog培训

    大家好,今天小编关注到一个比较有意思的话题,就是关于福特dfmea培训学校的问题,于是小编就整理了2个相关介绍福特dfmea培训学校的解答,让我们一起看看吧。汽…

    福特dfmea培训学校,福特mmog培训 2024-06-13 00:51:40
  • 烟台iso培训学校,烟台iso培训学校电话

    烟台iso培训学校,烟台iso培训学校电话

    大家好,今天小编关注到一个比较有意思的话题,就是关于烟台iso培训学校的问题,于是小编就整理了4个相关介绍烟台iso培训学校的解答,让我们一起看看吧。Gp12是…

    烟台iso培训学校,烟台iso培训学校电话 2024-05-27 15:44:58
  • 培训学校iso认证,培训学校iso认证有用吗

    培训学校iso认证,培训学校iso认证有用吗

    大家好,今天小编关注到一个比较有意思的话题,就是关于培训学校iso认证的问题,于是小编就整理了5个相关介绍培训学校iso认证的解答,让我们一起看看吧。ISO与Q…

    培训学校iso认证,培训学校iso认证有用吗 2024-05-13 14:39:55
  • watcht5pro手表(watch two)

    watcht5pro手表(watch two)

    watch和compute的区别前言watch和compute是vue实例对象中两个重要的属性。watch是一个监控属性,用于监控vue实例对象上的属性和方法的…

    watcht5pro手表(watch two) 2024-05-07 10:03:29
  • vue3.0按需引入(vue中引入vant组件)

    vue3.0按需引入(vue中引入vant组件)

    vue3+vite项目下按需引入vant,报错无法解决导入解决方案在vue3+vite项目下按需引入vant报错Failedtoresolveimport解决方…

    vue3.0按需引入(vue中引入vant组件) 2024-05-07 02:01:11