vue 组件之间传值方式总汇

  在vue中组件之间的传值从大类上讲有父子组件和兄弟组件的传值,其他的小类还有通过状态管理器,或者是路由中的params和query。其中vuex状态管理本质上是通过共享数据实现的,路由方面则是通过附加额外参数(这个时候数据和route是高度耦合的,你只有通过$route对象才能拿到你需要的数据,所以为了实现数据和路由的解耦,我们还可以在设置路由的时候通过props去解决这个问题,详细操作可见路由官网的路由组件传参部分)。

  父组件通过prop向子组件传值,子组件通过this.$emit触发父组件中通过v-on监听的事件来完成一次数据的变更。子组件内是无法直接修改prop的值的,不然会有警告。为什么不能直接修改呢,因为这破坏了父子组件之间数据的单向传递,导致数据的变化难以追踪。我们可以看到子组件通知父组件变化,父组件是需要v-on监听一个对应的函数才能了解到变化,虽然这种对应关系很明确,但如果我有多个prop,而且每个prop都需要不同的$emit去触发监听事件,那么对应的父组件就要有多个不同的函数仅仅是为了监听到多个prop的变化,这其实有点浪费。那么我们有没有一种类似双向绑定的方式,不需要我们在父组件之中写繁琐的v-on了呢。答案是有的。例如父组件有个title属性,子组件只要通过this.$emit('update:title',xxxx),父组件的title属性要加上sync修饰符,就可以实现父子组件传参的伪双向绑定,避免了繁琐的v-on带来的多余的function。具体写法如下:

<tfunc :title.sync="title"/> (父组件内,注意sync)

this.$emit('update:title', this.title + this.click) (子组件中使用emit时注意update:)

   除了上面的几种方式外,组件间的传值还可以通过总线发布订阅的方式实现,它的本质还是一方监听一方触发,但他的影响范围却从父子之间扩展到了兄弟之间,甚至是页面之间(但首先要确保页面实例存在,监听的事件没有被销毁,不然一方的触发是找不到对应的执行函数的)。具体实现呢还是利用VUE天生自带的那套监听模式,你可以在根实例中监听事件,然后在对应的页面用根实例的emit去触发。写法如下:

this.$rooot.$on('doSomething', this.doSomething)  (订阅方)

this.$root.$emit('doSomething',参数) (发布方)

this.$root其实就是我们一开始new出来的vue实例,一般为了减少在vue实例上绑定太多的东西,所以我们秉承着专人干专事的原则我们会重新new 一个vue专门用来做总线,就像下方的bus一样:

在使用过程中通过this.$root.Bus.$on(......) 和this.$root.Bus.$emit(.....)就可以了。像这种事件监听的订阅模式还可以通过dispatchEvent的方式广播实现,这里就不扩展了,感兴趣的朋友可以看笔者的另一篇博客广播与派发原理(基于vue实现dispatch, broadcast)。道路千万条,总有一条适合你。

 

Vue2中,子组件向父组件可以使用以下几种方法: 1. 通过定义$emit方法来向父组件发射一个事件,并。子组件中使用this.$emit('eventName', value)来触发事件,父组件监听该事件,并定义对应的处理函数接收递的。例如: - 子组件中: this.$emit('changeActiveStep', 3); - 父组件中: 监听事件并定义处理函数,如 @changeActiveStep="handleStepChange",然后在methods中定义 handleStepChange(value) 函数来接收递的。 2. 通过props属性将从父组件递给子组件,并在子组件中使用该属性。父组件中通过属性绑定将递给子组件,子组件中通过props属性接收该。例如: - 父组件中: <editable-cell :text="text" :inputType="inputType" /> - 子组件中: 在props中声明接收的属性,如 props: ['text', 'inputType'],然后在子组件中使用该属性。 3. 通过ref属性获取子组件实例对象,然后在父组件中调用子组件的方法或访问子组件的属性。父组件中使用ref属性给子组件指定一个引用名称,然后通过this.$refs.refName来获取子组件的实例对象。例如: - 父组件中: <grade ref="Grade"></grade> - 子组件中: 在mounted钩子中使用this.$on来监听事件,并通过this.$emit触发事件,如 this.$emit('getGrade', grade) - 父组件中: 在mounted钩子中通过this.$refs.Grade.$on监听子组件的事件,并指定处理函数,如 this.$refs.Grade.$on('getGrade', this.handleGrade) 以上是在Vue2中子向父组件的三种常用方法。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Vue2的router-view中子组件与父组件](https://blog.youkuaiyun.com/yuxuan89814/article/details/117113525)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [VUE组件向父组件的方法](https://blog.youkuaiyun.com/weixin_48931415/article/details/123044309)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [【vue2】子组件向父组件参方法汇总](https://blog.youkuaiyun.com/weixin_44431073/article/details/125006029)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值