美文网首页
vue 组件通信传值

vue 组件通信传值

作者: web30 | 来源:发表于2020-02-09 14:51 被阅读0次

1. 父组件向子组件传值

父组件通过 prop 给子组件下发数据,子组件通过$emit触发事件给父组件发送消息,即 prop 向下传递,事件向上传递。

  • 新建父组件文件
<template>
  <div>
     父组件:
    <input type="text" v-model="name">
    <!--引入子组件-->
    //这里传的是一个变量值(可修改的,所以要使用v-bind属性)
    <son :inputName="name"></son> 
  </div>
</template>

<script>
// 引入子组件
import son from './son'

export default {
  name: 'father',
  data () {
    return {
      name: '',  
    }
  },
  components: { //接收组件
    son
  }
}
</script>
  • 新建子组件文件
<template>
  <div>
    子组件:
    <span>{{inputName}}</span> //接收父组件传过来的值
  </div>
</template>

<script>
export default {
  name: 'son',
  data () {
    return {}
  },
  // 接受父组件的值
  props: {
    inputName: String, //声明的类型
    required: true
  }
}
</script>
image.png

另一种(在封装组件里传值)父组件向子组件传值

局部封装


image.png image.png

‘a’是字符串数组

2. 子组件向父组件传值

vue是禁止子组件直接向父组件传值的,所以只能通过$emit触发事件来达到目的。

  • 新建子组件文件
<template>
  <div>
    子组件:
    <span>{{sonValue}}</span> 
    <!-- 定义一个子组件传值的方法 -->
    <button @click="sonClick">点击触发</button> //绑定一个点击事件
  </div>
</template>

<script>
export default {
  name: 'son',
  data () {
    return {
      sonValue: '我是子组件的数据'
    }
  },
  methods: {
    sonClick () {
      // sonByValue是在父组件on监听的方法
      // 第二个参数this.sonValue是需要传给父组件的值,就是return中的值
      this.$emit('sonByValue', this.sonValue)
    }
  }
}
</script>
  • 新建父组件文件
<template>
  <div>
    父组件:
    <span>{{name}}</span>  
    <!-- 引入子组件 定义一个on的方法监听子组件的状态-->
    //@sonByValue是接收子组件的事件名称,需要和子组件保持一致
    <son @sonByValue="outSon"></son>  //outSon自定义名称方法
  </div>
</template>

<script>
import son from './son'

export default {
  name: 'father',
  data () {
    return {
      name: ''
    }
  },
  methods: {
    // sonValue就是子组件传过来的值
    outSon(sonValue) {
      // 把子组件里传过来的值赋值给this.name,当点击触发方法时,就把值传过来了并显示在页面上了
      this.name = sonValue 
    }
  },
  components: {
    son
  }
}
</script>
image.png

3.非父子组件传值(兄弟组件传值)

需要新建一个公共的公共实例文件bus.js,作为中间仓库来传值

  • 1.在src目录下新建一个bus.js文件
import Vue from 'vue'
export default new Vue()
  • 2.新建组件A
<template>
  <div id="emit">
    A组件:
    <span>{{elementValue}}</span>
    <button @click="elementByValue">点击触发</button>
  </div>
</template>

<script>
// 引入公共的bug,来做为中间传达的工具
import Bus from './bus.js'

export default {
  name: 'componentA',
  data () {
    return {
      elementValue: '我要给兄弟组件传值啦'
    }
  },
  methods: {
    elementByValue () {
     // 用$emit来触发
      Bus.$emit('val', this.elementValue)
      // console.log(this.elementValue)
    }
  }
}
</script>
  • 新建组件B
<template>
  <div>
    B组件:
    <!--<button @click="getBata">点击触发</button>-->
    <span>{{name}}</span>
  </div>
</template>

<script>
// 引入公共的bug,来做为中间传达的工具
import Bus from './bus.js'

export default {
  name: 'componentB',
  data () {
    return {
      name: ''
    }
  },
  mounted () {
    var vm = this
    // 用$on来接收
    Bus.$on('val', (data) => {
      console.log(data)
      vm.name = data
    })
  }
  // methods: {
  //   getBata () {
  //     this.name++
  //   }
  // }
}
</script>

4. 袓孙隔代传值

当一个模板里嵌套了很多层时,如:组先、儿子、孙子、曾孙等,你要从最里层曾孙组件里去访问最外层袓先的数据,如果你要一层一层的去传值的话,那这会非常麻烦,并且数据容易出错。这时就需要用到provide 和inject方法,它们俩需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效。

不推荐直接用于应用程序代码中。一般使用的场景是自定义组件库的时候,底层组件之间需要通信的时候使用。

  • provide: 一个对象或返回一个对象的函数

  • inject:一个字符串数组,或 一个对象,对象的 key 是本地的绑定名

    1. 新建袓先级组件
<template>
  <div>
    <span>祖先级组件:parent</span>
    <input type="text" v-model="toGdata.name">
    <div>
      <dadC></dadC> // 定义父组件
    </div>
  </div>
</template>

<script>
// 引入父组件
import dadC from './dadC'

export default {
  name: 'parent',
  data () {
    return {
      toGdata: {name: '李三'} // 存放数据
    }
  },
  // import引入的组件需要注入到对象中才能使用
  components: {
    dadC
  },
  // 注入数据
  provide () {
    return {
      toGdata: this.toGdata
    }
  }
}
</script>
    1. 新建儿子级组件
<template>
  <div>
    <span>儿子级组件C:dadC</span>
    <div>
      <grandSon></grandSon>  // 定义孙子组件
    </div>
  </div>
</template>

<script>
// 引入孙子组件
import grandSon from './grandSon'

export default {
  name: 'dadC',
  data () {
    return {}
  },
  // import引入的组件需要注入到对象中才能使用
  components: {
    grandSon
  }
}
</script>
    1. 新建孙子级组件
<template>
  <div>
    <span>孙子级组件G:grandSon</span>
    <div>
      接受来自袓父级组件parent的数据【toGdata】:{{toGdata}}
      <input type="text" v-model="fromParentData.name">
    </div>
  </div>
</template>

<script>
export default {
  name: 'grandSon',
  data () {
    return {
      fromParentData: this.toGdata
    }
  },
  // 接受袓先级传过来的数据
  inject: ['toGdata'],
  components: {}
}
</script>

注意:这里不论子组件嵌套有多深, 只要调用了 inject 那么就可以注入 provide 中的数据,而不局限于只能从当前父组件的props属性中回去数据

image.png

总结:
在简单的功能模块,可以通过传递对象实现跨级组件通信,复杂的功能模块不建议使用,因为传递的数据,如果其他的儿子级组件,其他儿子级组件的孙子级组件也在使用的话,会造成数据的混乱,甚至无法理解数据是在哪里变化的,排查故障艰难。
跨级组件通信可以定义一个中央事件总线(eventBus),但是更复杂的系统,还是建议使用vuex。

参考以下资料:
https://blog.csdn.net/weihaifeng163/article/details/88338822
https://www.cnblogs.com/pangchunlei/p/12112318.html

相关文章

  • VUE组件(传值,生命周期)

    VUE生命周期 VUE子传父组件通信 VUE非父子组件传值

  • Vue组件间通信

    Vue组件间通信 父子组间通信 通过props向子组件传值,通过事件向父级组件发送消息 通过props向子组件传值...

  • vue组件梳理

    vue组件 未经同意 禁止转载 通信传值 1. props 父组件向子组件传值,子组件通过props接收值 2. ...

  • vue通信方式

    vue组件通信方式 使用props父传子 定义child组件 父组件传值