vue组件之间通信的八种方式: props、$attrs、$root、$parent、$refs、$emit、依赖注入、Vuex

本文深入解析Vue组件间的通信方式,包括props传值、$attrs、$root、$parent、$children、$refs、$emit、依赖注入及Vuex的使用场景与特性,帮助开发者掌握高效组件交互技巧。
摘要由CSDN通过智能技术生成

今天看vue的API,看到组件通信这一块,发现通信方式有好多种,但官网上的说明都是一笔带过,而且语句有点拗口,里面又有很多不理解的专有名词,以致于以前看的时候漏掉了很多东西,今天就好好总结一下。

1. props传值
props方式是用得比较多的:

  <div id="app">
    <child :value="msg" :fun="printMsg"></child>
  </div>
  Vue.component('child', {
    props: ['value', 'fun'],
    mounted() {
      this.fun(' 我是在child组件中加入的参数')
    },
    template: `
      <div>{{value}}</div>
    `
  })
  new Vue({
    el: '#app',
    data: {
      msg: '我是app内的msg'
    },
    methods: {
      printMsg(str = '') {
        console.log('msg:', this.msg + str) // msg: 我是app内的msg 我是在child组件中加入的参数
      }
    }
  })

上例中根组件向子组件传了两个值,分别是一个字符串和一个方法,在子组件中,传入的值会放到vm实例中,可用this来访问。
传入的方法(不是用箭头函数定义的)在调用时,方法内部的this仍然指向根的Vue实例,并且能获取子组件传递的参数,这样就能方便的在子组件中调用父组件的方法。
特点:

  1. 在子组件调用时给子组件写入的属性,在子组件内用props注册后会添加到子组件的vm实例上;
  2. 在子组件中不能直接修改props传入的值;
  3. 只能是父组件传子组件,不能‘隔代’;

2. $attrs
$attrs是2.4版本添加的内容,目的是解决props在‘隔代’传值时反复注册props属性的问题。

若现在有三个组件grand, parent 和 child,parent是grand的子组件,child是parent的子组件,现在需要grand组件传值到child组件,如果用props来注册的话,不管parent组件需不需要用到这个值,都必须在parent中用props注册,再传给child。

$attrs是一个对象,它的值是组件在调用时写入的属性(不包括style, class以及在子组件中注册的props)。使用$attrs就可以避免过多的注册props:

 <div id="app">
   <parent :value="msg"></parent>
 </div>
  Vue.component('parent', {
    data() {
      return {
        msg: ''
      }
    },
    mounted() {
      console.log('parent', this.$attrs)
    },
    template: `
      <div>
        <child :value="$attrs.value"></child>
      </div>
    `
  })

  Vue.component('child', {
    props: ['value'],
    mounted() {
      console.log('child', this.value)
    },
    template:`<div></div>`
  })

  new Vue({
    el: '#app',
    data: {
      msg: '我是app内的msg'
    },
  })

上例中parent组件没有注册props,通过$attrs将值传给了child

3. $root
在任何一个组件中,$root都指向根组件实例,即_uid 为0的vue实例,通过vm.$root可以访问到根上的属性和方法

 <div id="app">
	 <child></child>
 </div>
  Vue.component('child', {
    mounted() {
      this.$root.fun('子组件的参数')
    },
    template:`<div></div>`
  })

  new Vue({
    el: '#app',
    data: {
      msg: '我是app内的msg'
    },
    methods: {
	  fun (str) {
        console.log(this.msg + str) // 我是app内的msg 子组件的参数
	  }
	}
  })

4. $parent和$children
$parent指向父组件实例,在根实例中的值为undefined
$children是一个数组,包含了该组件下的所有子组件

 <div id="app">
	 <child></child>
 </div>
  Vue.component('child', {
    mounted() {
      this.$parent.fun('子组件的参数')
    },
    template:`<div></div>`
  })

  new Vue({
    el: '#app',
    data: {
      msg: '我是app内的msg'
    },
    methods: {
	  fun (str) {
        console.log(this.msg + str) // 我是app内的msg 子组件的参数
	  }
	}
  })

5. $refs
这个也比较常用,直接上码:

<body>
  <div id="app">
    <child ref="child"></child>
    <div ref="myDiv"></div>
  </div>
</body>
<script>
  Vue.component('child', {
    data () {
      return {
        msg: '我是子组件的msg'
      }
    },
    methods: {
      fun(str) {
        console.log(this.msg + str)
      }
    },
    template: `<div></div>`
  })
  new Vue({
    el: '#app',
    mounted () {
      this.$refs['child'].fun(' 我是父组件的参数') // 我是子组件的msg 我是父组件的参数
      console.log('myDiv',this.$refs['myDiv']) // 这是一个DOM对象
    }
  })
</script>

6. $emit
子传父常用的方法,上码:

<body>
  <div id="app">
    <child @getmsg="fun"></child>
  </div>
</body>
<script>
  Vue.component('child', {
    data () {
      return {
        msg: '我是子组件的msg'
      }
    },
    mounted() {
      this.$emit('getmsg', this.msg)
    },
    template: `<div></div>`
  })
  new Vue({
    el: '#app',
    methods: {
      fun (msg) {
        console.log(msg) // 我是子组件的msg
      }
    },
  })
</script>

7. 依赖注入
使用 $parent 属性无法很好的扩展到更深层级的嵌套组件上。这也是依赖注入的用武之地,它用到了两个新的实例选项:provide 和 inject。
provide 选项允许我们指定我们想要提供给后代组件的数据/方法。
然后在任何后代组件里,我们都可以使用 inject 选项来接收指定的我们想要添加在这个实例上的属性:

<body>
  <div id="app">
    <child></child>
  </div>
</body>
<script>
  Vue.component('child', {
    inject: ['value'],
    mounted() {
      console.log(this.value) // 我是根组件的msg
    },
    template: `<div></div>`
  })
  new Vue({
    el: '#app',
    data: {
      msg: '我是根组件的msg'
    },
    provide() {
      return {
        value: this.msg
      }
    }
  })
</script>

8. Vuex
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式,更多信息请移步官网

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值