Vue — 组件通信(一)

最后更新于:2022-04-02 08:08:40

[Toc] >[success] # 组件通信 ~~~ 1.常见的组件通信方式使用'props'父传子,使用'$emit' 子传父,使 用'bus'/'vuex' 实现兄弟组件通信,使用一些特别的方式例如'ref','$parent' ,'$children'。 2.另外一种不常见的,组件的通信 'provide / inject',这种通信和'vuex','bus' 不同,它是一种vue.js 内置的接口 3. 'provide / inject' 和'props' 不同点是'props' 只能进行父子之间的传值, 简单的说就是一层,但如果想爷孙传值就不行,爷孙直接的可以使用 'provide / inject' 可以理解是一个加强版本的'props',但做不到兄弟组件通信 ,兄弟间还是需要使用'bus' 和'vuex' ,但是也有其他办法利用 'provide / inject'实现 4.provide 和 inject 绑定并不是可响应的。这是刻意为之的。然而,如果你传入了 一个可监听的对象,那么其对象的属性还是可响应的 ~~~ >[info] ## 使用provide / inject 官网讲解 ~~~ 1.解释单词意思方便更好的理解 ,provide -- 提供 , inject -- 注入 2.官方文档不推荐使用,但是iview作者给出的建议是可以好好利用让其变得强大。 3.'provide:Object | () => Object' 'inject:Array | { [key: string]: string | Symbol | Object }' 官方给的两个参数接收的值,其中provide 支持对象和一个方法返回对象 ,下面的案例将对这个详细讲解 ~~~ >[danger] ##### provide 对象形式使用 * 下面代码实现效果: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/9d8110772b38e1d36b9fe09362c903ba_213x32.png) ~~~ 1.使用'provide' 对象的形式,注意如果使用对象的形式,是无法获得当前 ,组件的'this'指向因此也无法获取其中的data 2.下面案例中 'Acomponents' 组件中嵌套了'Bcomponents',在一个视图组 件中去调用'Acomponents' 这样这个视图和'Bcomponents' 形成了爷孙关系 ~~~ * Acomponents.vue 组件中 ~~~ ~~~ * 组件 Bcomponents 写法 ~~~ ~~~ * 调用组件Acomponents 的视图组件写法 ~~~ ~~~ >[danger] ##### provide 使用方法返回对象 * 代码效果图 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/6dedfc7c1f4d8b2d43f8ef52c9f14581_293x40.png) ~~~ 1. 'provide' 在刚才案例中使用对象的形式传入this,会报错但是不能传递 固定值,为了让代码更灵活,使用方法返回对象的形式如下代码。 ~~~ * Acomponents.vue 组件中 ~~~ ~~~ * 组件 Bcomponents 写法 ~~~ ~~~ * 调用组件Acomponents 的视图组件写法 ~~~ ~~~ >[danger] ##### provide技巧 ~~~ 1.在文章开头就说了'provide 和 inject 绑定并不是可响应的。这是刻意为之 的。然而,如果你传入了一个可监听的对象,那么其对象的属性还是可响应 的'简单的说父组件提供给子组件的内容,当父组件再次改变数据的时候, 子组件是收不到的,并且子组件也无法更改父组件传递的值 2.但是官方的这句话也说了,如果是一个可监听的对象就可以,这样就有一 个解决方法,就是父组件在提供属性值的时候提供的参数是对象,或者是 当前的this本身 3.在vue2.6版本提供了一个'Vue.observable' 来帮忙解决如果传递一个this过 于浪费,和如果传递必须要把数据变成对象的形式的尴尬 ~~~ * 父组件 ~~~ ~~~ * 子组件 ~~~ ~~~ >[info] ## 根据案例衍生 ~~~ 1.思考什么时候可以利用这个属性?如何利用这个属性可以达到最佳 2.答:当我们封装一个select 标签的时候,我们将select 和里面的opition, 拆成两个组件去写和维护,这时候'opition' 组件想获取'select' 组件的值时候 ,可以利用这个或者'props' 来传递 3.答:如何达到最佳,当我们使用'provide' 时候使用方法返回对象可以传递 一个this,如果我们直接将祖先组件的'this' 传递过去,就会发现在子孙组件 中就可以去调用祖先组件的中的内容 ~~~ >[danger] ##### 关于问题一种select 组件 直接参考简书文章 >[danger] ##### 利用问题二的特性做一个Vuex ~~~ 1.下面的案例不是为了替代Vuex,只是一种方案来实现Vuex 2.根据cli搭建的项目,我们可以发现'app.vue'实际上是所有的根,而且 app.vue 是整个项目第一个被渲染的组件,而且只会渲染一次(即使切换路 由,app.vue 也不会被再次渲染),利用这个特性,很适合做一次性全局的 状态数据管理 3.尝试写一个全局登陆用户信息案例 ~~~ * 首先下面代码是对第二条的解释(常见的app.vue一般只有一个router-view) ~~~ ~~~ * 开始案例利用provide 方法的形式返回app.vue this执行,让全局组件获取 到登陆信息 ~~~ ~~~ * 接下来,任何组件(或路由)只要通过 inject 注入 app.vue 的 app 的话,都可以直接通过 this.app.xxx 来访问 app.vue 的 data、computed、methods (下面代码还是写在app.vue文件中的) ~~~ ~~~ * 在组件中或者其他视图组件中获取(userInfo 信息) ~~~ ~~~ * 如果某个组件中改变从app中的值,需要全局统一的时候可以这么做,更改对应app.vue中的值 ~~~ ~~~
';