Vue 组件间通信方式

栏目: 编程语言 · 发布时间: 5年前

内容简介:Vue 是数据驱动的视图框架,那么组件间的数据通信是必然的事情,那么组件间如何进行数据传递呢?首先组件间通信有父子组件、兄弟组件、堂兄弟组件、叔侄组件等,分类太多可能不好理解,我们暂且分为:后续的组件间通信方式的例子就会根据这些分类进行说明。

Vue 是数据驱动的视图框架,那么组件间的数据通信是必然的事情,那么组件间如何进行数据传递呢?

首先组件间通信有父子组件、兄弟组件、堂兄弟组件、叔侄组件等,分类太多可能不好理解,我们暂且分为:

  • 父子组件通信
  • 子父组件通信
  • 非父子组件通信

    • 兄弟组件通信
    • 非兄弟组件通信(不是直属关系,如堂兄组件、叔侄组件等)

后续的组件间通信方式的例子就会根据这些分类进行说明。

Vue 本身提供哪几种通信方式?

首先 Vue 灵感源于 angular,支持双向绑定,Vue 本质还是 单向数据流 。跟 React 一样,组件间最基本的数据流是通过 prop 向子组件传递数据。

Vue 组件间通信方式

这里列举一下 Vue 本身支持的通信方式:

  • prop
  • $emit

    这个其实类似 React 的 props 回调。

  • provide / inject

    如果你熟悉 React,这与 React 的 context 特性很相似。

那么有人说 $attrs$listener 呢?这些严格意义上不能归纳为数据流的通信方式,这些只是辅助属性,本人也不建议过多的使用这些 $ 属性,除了一些有必要的场景。

prop

prop 是 Vue 三大核心概念之一,prop 在组件中无处不在。prop 只可以从上一级组件传递到下一级组件(父子组件),即所谓的 单向数据流 。而且 prop 只读,不可被修改,所有修改都会失效并警告。

可以先阅读官网的 通过 Prop 向子组件传递数据 的教程。

父子组件通信

这里也编写了一个简单的例子 http://jsrun.net/wXyKp/edit

子父组件通信

不是说是单向数据流吗,怎么还可以使用 prop 进行 子父组件通信 ?这样想是对的,prop 是无法向上传递数据,但是我们可以使用回调啊。数据流的确向上走了,但是这并不违反单向数据流的思想,这个并不会使得数据流混乱,还是比较清晰。

这个 prop 回调方式,在 React 会经常使用。但是在 Vue 却很少使用,因为组件可以自定义事件,即后面的 $emit 组件间通信方式(其实就是订阅发布模式)。

例子可以看这个 http://jsrun.net/aXyKp/edit

兄弟组件的通信

如果你了解上面提到的 父子组件通信子父组件通信 ,那么你就很容易理解 兄弟组件通信 的方式。

可以看下这个例子 http://jsrun.net/QyyKp/edit

兄弟组件的通信就是 父子组件通信子父组件通信 的结合,需要父组件作为中间组件进行数据传递。

那么这样岂不是很麻烦?的确是多了一步,所以我们基本不会使用这种方式进行数据传递。

但是单向数据流思想是不存在交叉的数据流,即使 vuex 也无法避免这一步,但是 vuex 用法上你感觉不到这一步。 所以请不要随意引入第三方订阅发布的类库来解决这个问题,兄弟组件不可以直接通信的问题,这回造成数据流混乱,这就完全违反了单向数据流的思想。

可以看下这个强烈不建议的使用例子 http://jsrun.net/PyyKp/edit ,这种使用方式完全违背了单向数据流的思想,当程序复杂起来,数据流会特别混乱,项目不好维护。

$emit

官网教程可以看 监听子组件事件

$on$emit 是 Vue 自带的订阅发布模式,可以自定义事件。在 子父组件通信 中可以使用这种模式代替 prop 回调模式,相对便捷一点。

每个组件的 $on$emit 都是独立的, $emit 只会触发当前组件的 $on 事件。

对比例子可以看这个 http://jsrun.net/cXyKp/edit

子父组件通信可以看上面提到的例子可以看这个 http://jsrun.net/aXyKp/edit

provide / inject

首先你需要看官网教程 https://cn.vuejs.org/v2/api/#...prviode / inject 在 vue@2.2.0 才新增的。这个也是作者参考 react context ,新加的用法,如果你熟悉 react,那么这个很好理解。

在组件嵌套比较深的情况下,我们再使用 prop 层层传递数据将是个噩梦。 孙辈组件想直接获取到祖辈的数据,而不用经过父辈组件,该怎么处理呢? provide / inject 可以解决这个问题。

可看这个使用例子 http://jsrun.net/nXyKp/edit

从上面的例子运行可知, provide 执行与 beforeCreatecreated 之间,也可以访问 datainject 的数据。

其他的通信方式

处理 vue 本身支持的通信方式,还有其他的吗?当然有 vuex 就是 vue 官方的数据流管理类库。

上面提到的 vue 本身支持的通信方式,涉及到的都是父子或者子父组件的通信,那么 非父子组件通信 呢?通过 vuex 我们就可以很简单的进行非父子组件的通信了,使用了 vue 支持各种方式的通信(包括父子组件、子父组件的通信)。

结合单向数据流的思想,我们难道不可以统一一个地方集中管理数据(我们简称 store),然后每个组件可以直接和 store 通信吗?答案当然可以,这就是我们 vuex 所做的事情,这个跟 react 的 redux、mobx 等类库的思想是一致的。

props 的通信方式是这样的, component -> component

而 vuex 的通信方式是这样的, component(传递数据) -> store -> (数据变化更新组件)component ,可以简单理解为 component -> store -> component 。我们在中间搭建了数据管理层,那么这样我们就可以更好的管理数据了,而且数据流符合单向数据流的思想,数据都是从 store 流向 componentcomponent 可以是任何嵌套层次的组件。

理论上我们也可以在 vue 上使用 redux,但是没人会这样做,不合适,vuex 才是量身定制的。

参考文章

  • vue组件间通信六种方式(完整版)

以上所述就是小编给大家介绍的《Vue 组件间通信方式》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

ANSI Common Lisp

ANSI Common Lisp

Paul Graham / Prentice Hall / 1995-11-12 / USD 116.40

For use as a core text supplement in any course covering common LISP such as Artificial Intelligence or Concepts of Programming Languages. Teaching students new and more powerful ways of thinking abo......一起来看看 《ANSI Common Lisp》 这本书的介绍吧!

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

html转js在线工具
html转js在线工具

html转js在线工具