vue父子组件通信

1、props+$emit

Parent.vue:

<template>
  <div>
    <h1>父组件</h1>
    <p>{{message}}</p>
    <Child :message='message' @messageChange='message=$event' />
  </div>
</template>
<script>
import Child from './Child'
export default {
  data() {
    return { message: 'hello' }
  },
  components: { Child }
}
</script>

Child.vue:

<template>
  <div>
    <h1>子组件</h1>
    <p>{{message}}</p>
    <button @click="$emit('messageChange','123456')">按钮</button>
  </div>
</template>
<script>
export default {
  props: ['message']
}
</script>

通过props接收父组件传来的值,通过$emit触发父组件中自定义事件(messageChange)改变值

改造成v-model的形式:

Parent.vue:

<template>
  <div>
    <h1>父组件</h1>
    <p>{{message}}</p>
    <!-- <Child :message='message' @messageChange='message=$event' /> -->
    <Child v-model="message" />
  </div>
</template>
<script>
import Child from './Child'
export default {
  data() {
    return { message: 'hello' }
  },
  components: { Child }
}
</script>

Child.vue:

<template>
  <div>
    <h1>子组件</h1>
    <p>{{message}}</p>
    <button @click="$emit('messageChange','123456')">按钮</button>
  </div>
</template>
<script>
export default {
  props: ['message'],
  model: {
    prop: 'message',
    event: 'messageChange'
  }
}
</script>

在子组件中将model的prop和event改变成自己需要的值,这样在使用该子组件时会更加方便

2、回调函数

Parent.vue:

<template>
  <div>
    <h1>父组件</h1>
    <p>{{message}}</p>
    <Child :message='message' :changeMsg='changeMsg' />
  </div>
</template>
<script>
import Child from './Child'
export default {
  data() {
    return { message: 'hello' }
  },
  methods: {
    changeMsg() {
      this.message = '123456'
    }
  },
  components: { Child }
}
</script>

Child.vue:

<template>
  <div>
    <h1>子组件</h1>
    <p>{{message}}</p>
    <button @click="changeMsg">按钮</button>
  </div>
</template>
<script>
export default {
  props: ['message', 'changeMsg']
}
</script>

将函数作为属性传递给子组件

3、$parent+$children

Parent.vue:

<template>
  <div>
    <h1>父组件</h1>
    <p>{{message}}</p>
    <button @click="changeChildNum">按钮</button>
    <Child />
  </div>
</template>
<script>
import Child from './Child'
export default {
  data() {
    return { message: 'hello' }
  },
  methods: {
    changeChildNum() {
      this.$children[0].num = 10000
    }
  },
  components: { Child }
}
</script>

Child.vue:

<template>
  <div>
    <h1>子组件</h1>
    <p>{{num}}</p>
    <p>{{parentMessage}}</p>
    <button @click="handleClick">按钮</button>
  </div>
</template>
<script>
export default {
  data() {
    return { num: 5 }
  },
  computed: {
    parentMessage() {
      return this.$parent.message
    }
  },
  methods: {
    handleClick() {
      this.$parent.message = '123456'
    }
  }
}
</script>

通过$children改变子组件的值,通过$parent获取父组件的值以及改变父组件的值

4、provide+inject

Parent.vue:

<template>
  <div>
    <h1>父组件</h1>
    <Child />
  </div>
</template>
<script>
import Child from './Child'
export default {
  provide: { message: '奥运冠军' },
  components: { Child }
}
</script>

Child.vue:

<template>
  <div>
    <h1>子组件</h1>
    <p>{{message}}</p>
  </div>
</template>
<script>
export default {
  inject: ['message']
}
</script>

5、$attrs+$listeners

Parent.vue:

<template>
  <div>
    <h1>父组件</h1>
    <p>name:{{name}}</p>
    <p>age:{{age}}</p>
    <Child :name='name' :age='age' @changeName='changeName' />
  </div>
</template>
<script>
import Child from './Child'
export default {
  data() {
    return {
      name: '小明',
      age: 18
    }
  },
  methods: {
    changeName() {
      this.name = '小王'
    }
  },
  components: { Child }
}
</script>

Child.vue:

<template>
  <div>
    <h1>子组件</h1>
    <button @click="$listeners.changeName">按钮</button>
    <GrandChild v-bind="$attrs" />
  </div>
</template>
<script>
import GrandChild from './GrandChild'
export default {
  components: { GrandChild }
}
</script>

GrandChild.vue:

<template>
  <div>
    <h1>孙子组件</h1>
    <p>name:{{$attrs.name}}</p>
    <p>age:{{$attrs.age}}</p>
  </div>
</template>
<script>

有的时候,父组件传一个值到子组件中,但是子组件并不需要使用这个值,而是将这个值传到孙子组件中使用,此时如果用props略显麻烦,可以通过$attrs将该值传递下去。

$attrs和props的区别:如果父组件中传了a、b、c三个值,props中接收了a,那么$attrs中还剩下b和c传递下去。

$attrs和$listeners

6、ref注册组件实例

Parent.vue:

<template>
  <div>
    <h1>父组件</h1>
    <button @click="changeAge">按钮</button>
    <Child ref="childRef" />
  </div>
</template>
<script>
import Child from './Child'
export default {
  methods: {
    changeAge() {
      console.log(this.$refs.childRef.age)
      this.$refs.childRef.age = 50
      console.log(this.$refs.childRef.age)
    }
  },
  components: { Child }
}
</script>

Child.vue:

<template>
  <div>
    <h1>子组件</h1>
    <p>{{age}}</p>
  </div>
</template>
<script>
export default {
  data() {
    return { age: 10 }
  }
}
</script>
原文地址:https://www.cnblogs.com/wuqilang/p/15085786.html