总结!Vue 组件之间传值的几种方式

136 阅读2分钟

Vue组件传值大致有以下几种:

  • props $emit
  • provider inject
  • $refs
  • 中央事件总线 event bus
  • vuex

1,父子组件之间通过props传值是最为常用的方式:

//父组件 father.vue
<template>
  <div id="app">
    <p>我是父组件</p>
    <son :data="fatherData"></son> // 3,使用子组件,并传值
  </div>
</template>

<script>
import son from "./components/son"; // 1,引入子组件

export default {
  name: 'father',
  components: { // 2,注册组件
    son
  },
  data(){
    return {
      fatherData:{
        title:"我是父组件的数据"
      }
    }
  }
}
</script>
// 子组件 son.vue
<template>
  <div>
    <p>我是子组件</p>
    <p>{{data.title}}</p>
  </div>
</template>

<script>
export default {
  name: 'son',
  props: ['data'], // 此处props的类型,可以是一个字符串,也可以使用对象,规定传入数据的数据类型和一些额外参数(官方文档有详细介绍)。
}
</script>

这里提到了 $emit,既子组件可以触发父组件的方法,将子组件的值传递给父组件。 拿上面代码举例: 子组件son中的某个标签可以绑定一个方法,

// son.vue
<p @click="updateTitle">{{data.title}}</p>
在script中写一个updateTitle方法
upateTitle() {
	this.$emit('fatherMethod', '1');
}
fatherMethod就是父组件中在子标签上绑定的方法。

// father.vue
<son @fatherMethod="triggerMethod"></son>
在script中写一个triggerMethod方法,
triggerMethod(data){
	console.log('子组件触发了父组件的方法,并传了一个值' + data);
}

2,说完了props,来看看provider和inject,这个方法用的不多,官网也说:provide 和 inject 主要在开发高阶插件/组件库时使用。并不推荐用于普通应用程序代码中。不过作为组件传值的方式,也要说一下。

他们可以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在其上下游关系成立的时间里始终生效。

provide 选项应该是一个对象返回一个对象的函数。该对象包含可注入其子孙的 property。

inject 选项应该是:

一个字符串数组,或

一个对象,对象的 key 是本地的绑定名,value 是:

在可用的注入内容中搜索用的 key (字符串或 Symbol),或

一个对象,该对象的:

from property 是在可用的注入内容中搜索用的 key (字符串或 Symbol)

default property 是降级情况下使用的 value

说了这么多,怎么用呢?

// 父级组件提供 'foo'
var Provider = {
  provide: {
    foo: 'bar'
  },
  // ...
}

// 子组件注入 'foo'
var Child = {
  inject: ['foo'],
  created () {
    console.log(this.foo) // => "bar"
  }
  // ...
}

3,上面提到的emit是子组件给父组件传值,emit是子组件给父组件传值,refs则是父组件可以直接访问子组件,调用其方法。

<template>
  <div id="app">
    <child-com ref="child"></child-com>
    <!--用ref给子组件起个名字-->
    <button @click="getMyEvent">点击父组件</button>
  </div>
</template>
<script>
  import ChildCom from './components/childCom.vue'
  export default {
    components: {
      ChildCom
    },
    data() {
      return {
        msg: "我是父组件中的数据"
      }
    },
    methods: {
      getMyEvent(){
          this.$refs.child.emitEvent(this.msg);
          //调用子组件的方法,child是上边ref起的名字,emitEvent是子组件的方法。
      }
    }
  }
</script>

这里说一下我在应用ref的坑:::::比如调用的子组件的方法是请求接口数据,此时是异步的,或者是用了elementUI的一些组件,这些组件是懒渲染的,可能就会出现数据不展示或者页面不渲染,用一个很简单的方法就可以解决:nextTick,你懂得(手动狗头)。

4,中央事件总线event bus,这个就不在这里详述了,看我之前的一篇文章,单独写了这个方法。

最后一种,Vuex,这是一个神器,在一个组件中把数据存起来,可以在任意组件中获取,真是超级方便(略...)。

做个总结吧:组件间数据的传递,props和vuex平分秋色,用的都非常的多,建议这两种要用的非常的熟练,工作中会省下很多时间;ref次之,主要用于父组件直接访问子组件的情形;event bus个人没用过,不做评价,不过面试倒是问的挺多;至于provider就算了,基本上是用不到的。