Skip to content

Vue组件传值

INFO

  • props/$emit:可以实现父子组件的双向通信,在日常的父子组件通信中一般会作为我们的最常用选择。
  • v-slot:可以实现父子组件单向通信(父向子传值),在实现可复用组件,向组件中传入DOM节点、html等内容以及某些组件库的表格值二次处理等情况时,可以优先考虑v-slot。
  • refs/parent/children/root:可以实现父子组件双向通信,其中 $root可以实现根组件实例向子孙组件跨级单向传值。在父组件没有传递值或通过v-on绑定监听时,父子间想要获取彼此的属性或方法可以考虑使用这些api。
  • attrs/listeners:能够实现跨级双向通信,能够让你简单的获取传入的属性和绑定的监听,并且方便地向下级子组件传递,在构建高级组件时十分好用。
  • provide/inject:可以实现跨级单向通信,轻量地向子孙组件注入依赖,这是你在实现高级组件、创建组件库时的不二之选。
  • eventBus:可以实现全局通信,在项目规模不大的情况下,可以利用eventBus实现全局的事件监听。但是eventBus要慎用,避免全局污染和内存泄漏等情况。
  • Vuex:可以实现全局通信,是vue项目全局状态管理的最佳实践。在项目比较庞大,想要集中式管理全局组件状态时,那么安装Vuex准没错

Vue2父组件直接修改子组件的值

js
方式一:this.$children[0].a = 2

方式二:
<HelloWorld ref='dom'></HelloWorld>
this.$refs.dom.a = '3'

Vue2子组件修改父组件的值

INFO

常规⽅式

child.vue:

js
export defalut {
 props: {
  title: String
 },
 methods: {
    changeTitle(){
      this.$emit('change-title', 'hello')
    }
 }
}

parent.vue:

js
<child :title="title" @change-title="changeTitle" ref="c1"></child>

export default {
    data(){
        return {
            title: 'title'
        }
    },
    methods: {
        changeTitle(title){
             this.title = title
        }
    }
}

this.refs['c1'].title;
this.children[0].title;

INFO

简写⽅式

parent.vue:

js
<child :title.sync="title"></child>
复制代码
<child :title.sync="ptitle=$event"></child>
export defalut {
 data(){
    return {
       ptitle:''
    }
 }
}

child.vue:

js
export defalut {
 props: {
  title: String
 },
 methods: {
    changeTitle(){
      this.$emit('update:title', 'hello')
    }
 }
}

Vue2兄弟组件的传值,自己新建bus.js文件

js
import Vue from "vue";
const eventBus = new Vue();
export default eventBus;
js
import eventBus from './bus'

$ eventBus.$on('名称', 数据)   // 监听接收消息

$ eventBus.$off('名称')  //移除监听事件

$ eventBus.$emit('名称', 数据) // 发送消息

provide/inject

INFO

⼀个祖先组件向其所有⼦孙后代注⼊⼀个依赖,不论组件层次有多深 简单来说,⼀个组件将⾃⼰的属性通过 provide 暴露出去,其下⾯的⼦孙组件 inject 即可接收到暴露的属性。

App.vue:

js
export default {
  provide() {
    return {
      app: this,
    };
  },
};

child.vue:

js
export default {
  inject: ["app"],
  created() {
    console.log(this.app); // App.vue实例
  },
};

INFO

在 2.5.0+ 版本可以通过设置默认值使其变成可选项:

js
export default {
 inject: {
    app: {
        default: () => ({})
    }
 },
 created() {
    console.log(this.app) 9 }
 }

INFO

如果你想为 inject 的属性变更名称,可以使⽤ from 来表示其来源:

js
export default {
 inject: {
    myApp: {
      // from的值和provide的属性名保持⼀致
      from: 'app', 6 default: () => ({})
    }
 },
 created() {
    onsole.log(this.myApp)
  }
}

INFO

需要注意的是 provide 和 inject 主要在开发⾼阶插件/组件库时使⽤。并不推荐⽤于普通应⽤程序代码中。但是某些时候,或许它能帮助到我们