logo头像
Snippet 博客主题

vue 组件之间通信

本文于1006天之前发表,文中内容可能已经过时。

props/$emit

v-model

  • 语法糖,子组件通过this.$emit(‘input’, value)更新父组件v-model绑定的值

sync

  • 语法糖,子组件通过this.$emit(‘update:xx’, value)更新父组件:xx.sync=”value”里面的value的值

$parent/$children

  • 尽量不要用

$ref

v-bus

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// bus.js
const bus = new Vue()
export default bus
// main.js
import bus from './bus.js'
Vue.prototype.$bus = bus
// 广播事件组件
this.$bus.$emit('on-change', xx)
// 订阅事件组件, 在beforeDestroy 需要通过bus.$off('on-change')去消除订阅
this.$bus.$on('on-change', function(val){
console.log(val)
})

vuex

  • 需要注意页面刷新,整个store清空,可以通过插件实现数据持久化,本质就是利用缓存

inheritAttrs $attrs/$listeners

  • 可以少写很多props,通过$attrs将属性一层一层往下传递,组件库使用比较方便
    • 父组件
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      // 父组件
      <template>
      <f-son :name="name"
      :age="age"
      @on-ok="ok"
      @on-change="changeName"
      >
      </f-son>
      </template>
      <script>
      import Fson from './Fson.vue'
      export default{
      data() {
      return {
      name: '章三',
      age: 12
      }
      },
      methods: {
      changeName(value) {
      this.name = value
      },
      ok() {
      conosle.log(222)
      }
      },
      components: {
      Fson
      }
      }
      </script>
    • 子组件
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      // 子组件
      <template>
      <div>
      <grand-son v-bind="$attrs" v-on="$listeners">{{name}}</grand-son>
      </div>
      </template>
      <script>
      import GrandSon from './GrandSon'
      export default{
      inheritAttrs: false, //默认是true,如果不设置为false则所有不用prop继承的属性都将绑定到父组件的div上
      creted() {
      console.log(this.$attrs) // {name: '章三', age: 12}
      console.log(this.$listeners)
      // {
      // on-ok: ƒ invoker()
      // on-change: ƒ invoker()
      // }
      },
      components: {
      GrandSon
      }
      }
      </script>
    • 孙组件
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      // 孙组件
      <template>
      <div>
      <div>{{$attrs.name}} {{$attrs.age}}</di>
      </div>
      </template>
      <script>
      export default{
      inheritAttrs: false, //默认是true,如果不设置为false则所有不用prop继承的属性都将绑定到父组件的div上
      creted() {
      console.log(this.$attrs) // {name: '章三', age: 12}
      console.log(this.$listeners)
      // {
      // on-ok: ƒ invoker()
      // on-change: ƒ invoker()
      // }
      }
      }
      </script>

provide/inject

  • 组件库使用较多,在最顶级定义provide,可以跨级传递属性,只需要在要用的组件中inject一下,不会双向绑定,除非provide的值为data里面的引用
    • 顶级组件
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      // 顶级组件
      <template>
      <div>
      </div>
      </template>
      <script>
      export default{
      provide () {
      return {
      firstName: '张',
      secondeName: 'fsafdsa',
      }
      }
      }
      </script>
    • 用到的组件
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      // 用到的组件
      <template>
      <div>
      {{firstName}}
      </div>
      </template>
      <script>
      export default{
      inject: {
      firstName: {
      default: ''
      }
      }
      }
      </script>