Vue3 中的通信方式

151 阅读1分钟

Vue3 中的通信方式

父子通信

在vue3的组合式API中,父传子的基础套路完全一样,基础思想依旧为:父传子是通过prop进行传入,子传父通过调用自定义事件完成

实现步骤

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

父传子代码演示

父组件

<template>
  <div>
    <Son :name="name" :age="20" />
  </div>
</template>

<script>
import Son from './Son.vue'
import {ref} from 'vue'
export default {
  name: 'App',
  components:{
    Son
  },
  setup() {
    // 准备一个父组件中的数据
    const name = ref('this is name')
    return {
      name
    }
  }
}
</script>

子组件

<template>
  <!-- 模板中直接使用 -->
  <div>son {{ name }} {{ age }}</div>
</template>

<script>
import { ref } from 'vue'
export default {
  props: {
    name: {
      type: String
    },
    age: {
      type: Number
    }
  },
  setup(props) {
    // 重点:如何在这里使用传递过来的数据
    // 补充一个参数props
    // props里面存着父传子传递过来的所有的数据 它是一个对象
    console.log(props.name)
    console.log(props.age)
  }
}
</script>

子传父代码演示

父组件

<template>
  <div>
    <Son @get-msg="getMsg"/>
  </div>
</template>

<script>
import Son from './Son.vue'
import {ref} from 'vue'
export default {
  name: 'App',
  components:{
    Son
  },
  setup() {
    // 自定义事件的回调函数
    function getMsg(sonMsg){
      console.log(sonMsg.value)
    }
    return {
      getMsg
    }
  }
}
</script>

子组件

<template>
  <button @click="sendMsg">sendMsg</button>
</template>

<script>
import { ref } from 'vue'
export default {
  // 当前组件触发的所有自定义事件在这里申明一下
  emits:['get-msg'],
  setup(props, ctx) {
    const sonMsg = ref('this is sonMsg')
    function sendMsg() {
      // 触发自定义事件
      // this.$emit('get-msg')
      // ctx 是一个对象上下文 属性emit
      ctx.emit('get-msg', sonMsg)
    }
    return {
      sendMsg
    }
  }
}
</script>

provide 和 inject

通常我们使用props进行父子之间的数据传递,但是如果组件嵌套层级较深,一层一层往下传递将会变的非常繁琐,provideinject,它们配合起来可以方便的完成从顶层组件向任意底层组件传递数据的效果

provider.png

基础使用

实现步骤

  • 顶层组件在setup方法中使用provide函数提供数据

    provide('key',数据)

  • 任何底层组件setup方法中使用inject函数获取数据

    const data = inject('key')

代码演示

爷爷组件

<template>
  <father></father>
</template>

<script>
import Father from '@/components/Father'
import { provide } from 'vue'
export default {
  components: {
    Father
  },
  setup() {
    let name = '柴柴老师'
    // 使用provide配置项注入数据 key - value
    provide('name', name)
  }
}
</script> 

孙组件

<template>
  我是子组件
  {{ name }}
</template>

<script>
import { inject } from 'vue'
export default {
  setup() {
    const name = inject('name')
    return {
      name
    }
  }
}
</script>

传递响应式数据

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

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

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