Vue3--父子通信

2,275 阅读1分钟

通过setup()函数通信

在Vue3中,$on被移除,且setup函数中this指向undefined,并不指向Vue实例对象,所以无法使用Vue2中this.$emit()方法进行父子通信,但可以通过setup函数中第二个参数进行父子通信,

  • setup函数提供俩个参数,第一个参数为props,第二个参数为一个对象context
  • props为一个对象,内部包含了父组件传递过来的所有prop数据,context对象包含了attrs,slots, emit属性,其中的emit可以触发自定义事件的执行从而完成子传父
//代码实现:

//父组件中
<template>
  <son :name="name" @get-msg="getMsg"></son>
</template>
<script>
import { ref } from 'vue'
import Son from './components/son'
export default {
  components: {
    Son
  },
  setup() {
    const name = ref('cp')
    function getMsg(msg) { // 子组件触发自定义事件,该函数接收值
      console.log(msg)
    }
    return {
      name,
      getMsg
    }
  }
}
</script>

//子组件:
<template>
  <div>
    {{name}}
    <button @click="setMsgToSon">set</button>
  </div>
</template>

<script>
export default {
  props: {
    name: {
      type: String
    }
  },
  emits: ['get-msg'], // 声明当前组件触发的自定义事件
  setup(props,{emit}) {
    console.log(props.name)
    function setMsgToSon(){
      emit('get-msg','这是一条来自子组件的msg信息')
    }
    return {
      setMsgToSon
    }
  }
}
</script>

通过provide 和 inject通信

使用props进行父子之间的数据传递,如果组件嵌套层级较深,一层一层往下传递将会变的非常繁琐,通过provide 和 inject,它们配合起来可以方便的完成跨层传递数据

provide 和 inject都是vue实例中的方法

1. 使用步骤:
// 上层组件
<template>
  <father></father>
</template>

<script>
import Father from '@/components/Father'
import { provide } from 'vue'// 在上层组件中引入provide
export default {
  components: {
    Father
  },
  setup() {
    let name = '张三'
    // 使用provide配置项注入数据 key - value
    provide('name', name)
  }
}
</script> 
// 下层子组件或孙组件
<template>
  我是后代组件
  {{ name }}
  //输出 张三
</template>

<script>
import { inject } from 'vue' //在后代组件中引用inject方法
export default {
  setup() {
    const name = inject('name')
    return {
      name
    }
  }
}
</script>

只要是后代组件,都可以方便的获取顶层组件提供的数据

provide默认情况下传递的数据不是响应式的,也就是如果对provide提供的数据进行修改,并不能响应式的影响到底层组件使用数据的地方,如果想要传递响应数据也非常简单,只需要将传递的数据使用ref或者reactive生成即可

<template>
  <son></son>
  <button @click="changeName">change name</button>
</template>

<script>
import Son from '@/components/Son'
import { provide, ref } from 'vue'
export default {
  components: {
    Son
  },
  setup() {
    // 使用ref转换成响应式再传递
    let name = ref('张三')
    function changeName(){
      name.value = '李四'
    }
    provide('name', name)
    return {
      changeName
    }
  }
}
</script>