手机版

vue组件之间的六种通信方式(摘要)

时间:2021-08-24 来源:互联网 编辑:宝哥软件园 浏览:

前言

组件是vue.js最强大的功能之一,组件实例的范围是相互独立的,这意味着不同组件之间的数据不能相互引用。一般来说,组件可以具有以下关系:

如上图所示,A和B,B和C,B和D都是父子关系,C和D是兄弟,A和C是代际关系(可能相隔多代)。

如何针对不同的使用场景选择有效的沟通方式?这就是我们要讨论的主题。总结了props、$emit/$on、vuex、$parent/$children、$attrs/$listeners、提供/注入等几种vue组件间的通信模式,并以通俗易懂的例子讲述了其中的区别和使用场景,希望对小伙伴们有所帮助。

请用这篇文章的代码戳一下github博客,纸上谈兵会比较浅薄,大家要多敲敲代码!

方法1:道具/$emit

父组件A通过道具传递给子组件B,B到A通过B组件中的$ emit和A组件中的v-on实现。

1.父组件将值传递给子组件

接下来,我们用一个例子来说明父组件如何将值传递给子组件:如何获取子组件Users.vue中的数据users 3360[' Henry ',' Bucky ',' Emily']

//App.vue父组件模板div id=' app ' users v-bind : users=' users '/users//前者的自定义名称方便子组件调用。后者将从'传递数据名称/div/模板脚本导入用户'。/components/users ' export default { name : ' app ',data(){ return { users :[' Henry ',' bucky ',Emily']},components 3360 { ' users ' : users } }//users子组件模板div class=' hello ' ul liv-for=' user in users ' { user } }/Li//遍历传递的值。然后呈现给页面/ul/div/template脚本导出默认{ name: ' hello world,prop : { user 3360 {//这是父组件type3360array中子标签的自定义名称,required d 3360 true } }/脚本摘要:父组件通过props向下传递数据给子组件。注意:组件中有三种形式的数据:数据、道具和计算数据

2.子组件将值传递给父组件(以事件的形式)

接下来,我们用一个例子来说明子组件如何向其父组件传递值:当我们点击“Vue.js Demo”时,子组件向其父组件传递值,文本由“传递一个值”变为“从子组件向父组件传递值”,从而实现子组件向父组件的值传递。

//子组件template header h1 @ click=' change title ' { title } }/h1//绑定一个click事件/header/templatescript导出默认值{name:' app-header ',Data(){ return { title : ' vue . jsdemo ' } },方法: {change title () {this。$ emit('标题已更改','子组件将值传递给父组件');//自定义事件传递值“子组件将值传递给父组件”}}} /script //父组件template div id=' app ' app-header v-: title changed=' updateTitle '/app-header//与子组件title一致已更改的自定义事件//updateTitle($event)接受传递的文本H2 { { title } }/H2/div/模板脚本导入header from '。/components/Header ' export default { name : ' app ',data () {return {title: '传递了一个值' }},methods : { updatetitle(e){//声明了此函数this . title=e;}},components 3360 { ' app-header ' : header,} }/脚本摘要:子组件通过事件向父组件发送消息,实际上,子组件向父组件发送自己的数据。

方法2,$emit/$on

该方法使用一个空的Vue实例作为中心事件总线(event center),并利用它来触发事件和监控事件,从而巧妙地、轻松地实现了包括父子、兄弟和跨级在内的任何组件之间的通信。当我们的项目相对较大时,我们可以选择更好的状态管理解决方案vuex。

1.具体实现:

var Event=new Vue();事件。$emit(事件名称,数据);事件。$on(事件名称,数据={ });2.例如:有三个兄弟组件,即A、B和C,C组件如何获取A或B组件的数据

div id=' it any ' my-a/my-a my-b/my-b my-c/my-c/div模板id=' a' div h3a组件:{{name}}/h3按钮@click='send '发送数据到c组件/按钮/div/模板id='b' div h3B组件:{{age}}/h3按钮@click='send '发送数组到c组件/按钮/div/模板id=' c' div h3c组件:{{name}},{ { age } }///定义一个空的Vue实例var a={template:' # a ',data () {return {name:' Tom'}},methods: {send () {event。$ emit ('data-a ',这个。姓名);} } } var B={ template: '#b ',data() { return { age: 20 } },methods: { send() { Event。$emit('data-b ',this . age);}}} var c={template:' # c ',data () {return {name3360 ' ',age:''},mounted () {//execute event。$ on ('data-a ',名称={this。名称)。//箭头函数内部不会有新的this。如果这里没有使用=的话,这里指的是event})事件。$ on ('data-b),age={this。年龄=年龄;})} } var VM=new Vue({ El : ' # itany ',components: { 'my-a': A,' my-b': B,' my-C ' : C } });/脚本

方法三,vuex

1.简要介绍Vuex原理

Vuex实现了单向数据流,并有一个全局存储数据的状态。当一个组件想要改变状态中的数据时,它必须通过突变来实现。突变还为外部插件调用和获取状态数据的更新提供了订阅者模式。但是当所有异步操作(一般称为后端接口异步获取更新数据)或者批量同步操作都需要采取Action,但是Action不能直接修改State,或者State的数据需要通过突变进行修改时。最后,根据状态的变化,将其渲染到视图中。

2.简要介绍流程中各模块的功能:

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

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

Actions:由组件中的$store.dispatch('action name ',data1)触发的操作行为处理模块。然后commit()触发突变的调用来间接更新状态。处理Vue组件接收到的所有交互行为。它包含同步/异步操作,支持多个同名方法,按照注册顺序依次触发。后台API请求的操作在这个模块中执行,包括触发其他动作和提交变异操作。该模块提供了承诺包,以支持行动链触发。

Commit:状态更改提交操作方法。提交变异是执行变异的唯一方法。

变体:状态改变操作方法,由动作中的提交(“突变名称”)触发。是Vuex修改状态的唯一推荐方法。方法只能同步,方法名只能是全局唯一的。在操作过程中,会暴露一些钩子来监控状态。

状态:页面状态管理容器对象。Vue组件中数据对象的分散数据被集中存储,并且对于统一的状态管理是全局唯一的。页面显示所需的数据是从这个对象中读取的,并且通过使用Vue的细粒度数据响应机制来高效地更新状态。

Getters:状态对象读取方法。该模块没有在图中单独列出,应该包含在渲染中。Vue组件通过这个方法读取全局状态对象。

3.Vuex和localStorage

Vuex是vue的状态管理器,存储的数据是响应的。但是,它不会被保存。刷新后会回到初始状态。具体来说,当vuex中的数据发生变化时,应该将数据的副本保存在localStorage中。刷新后,如果localStorage中有保存的数据,取出来替换存储中的状态。

让defaultCity=' Shanghai '试试{//用户关闭了本地存储功能,现在添加一个试试.catch if(!default city){ default city=JSON . parse(window . local storage . getitem(' default city ')} } catch(e){ }导出默认的新Vuex。store({ state : { city 3360 DefaultCiTY }),突变: { changeCity(州、市){ state . city=city try { window . local storage . set item(' DefaultCiTY ',JSON.stringify(州、市));//当数据发生变化时,将数据的副本保存到localStorage} catch (e) {}}}})。这里需要注意的是,我们在vuex中保存的所有状态都是数组,而localStorage只支持字符串,所以需要JSON转换:

JSON . stringify(state . subscribe list);//数组-字符串JSON . parse(window . local storage . getitem(' subscribe list '));//字符串数组方法四。$attrs/$listeners

1.介绍

当多级组件嵌套需要传输数据时,通常使用vuex。但是用vuex处理代替中间处理有点大材小用。对于这个2.4版本,提供了另一种方法。当一个组件没有声明任何prop时,所有父范围(除了类和样式)的绑定都将包含在这里,内部组件可以通过v-bind=' $ attr '传入。通常与interitAttrs选项结合使用。

//demo.vue模板div child-com : foo=' foo ' : boo=' boo ' : COO=' COO ' : doo=' doo '/child-com/div/tempalte脚本const childCom=()=import('。/childCom1.vue)导出默认值{ data(){ return { foo : ' Hello World!',boo:“你好,Javascript!”,coo: 'Hello Vue ',doo: ' Last ' },components 3360 { child com } }/script//child com 1 . Vue模板div pfoo : { { foo } }/p pattrs : { { $ attrs } }/p child-com 2v-bind=' $ attrs '/child-com 2/div/模板脚本const childCom2=()=import('。/childCom2.vue)导出默认值{ prop :[' foo '],//foo被绑定为道具属性inheritattrs: false,created () {console.log (this。$ attrs)//{boo: '你好JavaScript!',coo: 'Hello Vue ',do : ' Last ' } }/script//child com 2 . Vue模板Div pboo : { { boo } }/p pattrs : { { $ attrs } }/p child-com 3v-bind=' $ attrs '/child-com 3/Div/模板脚本const childcom3=()=import('。/childcom3.vue)导出默认值{ prop :[' boo ']//boo被绑定为道具属性inheritAttrs: false。已创建(){console.log(这。$ attrs)//{首席运营官:' hello vue ',doo : ' last ' } }/script $ attrs表示没有继承数据的对象,格式为{属性名:属性值}。Vue2.4提供$ attrs和$ listeners来传输数据和事件,这使得跨级别组件之间的通信更加容易

方法5:提供/注入

1.介绍

Vue2.2.0增加了API,需要配合使用,让一个祖先组件可以将依赖注入到它的所有后代中,不管组件层次有多深,在建立上下游关系的时候总会生效。总之:祖先组件通过provider提供变量,然后后代组件通过inject注入变量。

2.举个例子

假设有两个组件:A.vue和B.vue,B是a的子组件。

//a.vue导出默认值{provide: {name: '乘风破浪' }}//b.vue导出默认值{inject: ['name'],mounted(){ console . log(this . name);//在波浪中划船}}可以看到,在A.vue中,我们设置了一个provide:名称,值为“在波浪中划船”。它的功能是为所有子组件提供变量名。在B.vue中,组件a提供的name变量是通过inject注入的,所以在组件b中,这个变量可以通过this.name直接访问,它的值也是浪中之舟。这是提供/注入应用编程接口的核心用法。

请注意,提供和注入绑定没有响应。但是,如果传入一个可监视的对象,其对象的属性仍然是响应的。因此,如果上面的A.vue的名字改变了,B.vue的这个.名字也不会改变,它仍然是一艘在波浪中的船。

方法6。$ parent/$ child和ref

引用:如果在普通的DOM元素上使用,引用指向DOM元素;如果在子组件上使用,引用将指向组件实例

$parent/$children:访问父/子实例

需要注意的是,这两种方法都可以直接获取组件实例,使用后可以直接调用组件的方法或者访问数据。让我们首先看一个使用ref访问组件的例子:

//component-a subcomponent export default { data(){ return { title : ' vue . js ' } },methods : { say hello(){ window . alert(' hello ');} } }//父组件模板组件-a ref=' coma '/组件-a/模板脚本导出默认值{mounted () {constcoma=this。$ refs.com;console . log(CoMa . title);//Vue . js CoMa . SayHello();//弹出窗口} }/脚本然而,这两种方法的缺点是不能跨级别或者兄弟之间进行交流。

//parent.vue component-a/component-a component-b/component-b/component-b我们想要访问引用它的页面中的两个component-b组件(这里是parent . vue)。在这种情况下,我们必须配置额外的插件或工具,例如Vuex和Bus解决方案。

摘要

常见的使用场景可以分为三类:

亲子沟通:家长通过道具向孩子传递数据,孩子通过事件($emit)向家长传递数据;沟通也可以通过父链/子链($ parent/$ children);引用也可以访问组件实例;提供/注入应用编程接口.兄弟交流:公交;Vuex跨级通信:总线;Vuex提供/注入API,$attrs/$listeners以上就是边肖介绍的vue组件之间的六种通信方式(总结),希望对大家有所帮助。如果你有任何问题,请给我留言,边肖会及时回复你。非常感谢您对我们网站的支持!如果你觉得这篇文章对你有帮助,请转载,请注明出处,谢谢!

版权声明:vue组件之间的六种通信方式(摘要)是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。