简述几种Vue3组件之间的通信方式

434 阅读2分钟

简述几种Vue3组件之间的通信方式

props/emit

这种通信方式和vue2里父子组件写法基本一致

//混合写法
//父组件
<template>
    <div>
           <son :msg="person.name" @updateVal="updateVal"> </son>  
    </div>
</template>
<script >
import son from './son1'
import {  ref, reactive, toRefs} from 'vue'
export default {
    components: {
        son
    },
    setup() {
        const comp = ref(null)
        const person = reactive({
            name: 'parentName',
            age: 12
        })
        const updateVal = val => {
            person.age = val
        }
        return {
            person,
            updateVal
        }
    }
}
</script>


//子组件
<template>
    <div>
     <button @click="updateVal(36)">修改年龄</button>
    </div>
</template>
<script lang="ts">
export default {
    props: ['msg'],
    setup(props: any, context: any) {
    console.log(props.msg)//打印结果:parentName
   //   子组件emit父组件事件 
        const updateVal = (e: number) => {
            context.emit('updateVal', e)
        }
        
    }
    </script>

attrs

包含了父作用域中不作为 prop 被识别 (且获取) 的特性绑定 (classstyle 除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (classstyle 除外),并且可以通过 v-bind="$attrs" 传入内部组件——在创建高级别的组件时非常有用。(这个通过属性传值的方式vue2中也有的 使用关键字attr)

此处代码不在赘述 参考上述代码
//父组件
<son  value='子组件value属性值' > </son>

//子组件
import {  useAttrs  } from 'vue' 

 setup(props: any, context: any) {
        // 打印父组件的属性
       const attrs = useAttrs()
    console.log(attrs.value) //打印结果:子组件value属性值

expose / ref

expose是setupe 语法糖 context上的一个函数接收一个对象,里面包含了所有想从当前组件实例导出的内容,就像封装一个模块一样,只向外暴露一些必要的方法和数据。(不像vue2中this.$refs能拿到子组件的所有内容,vue3中ref对象只能获取到子组件暴露的内容这一点应该是考虑了组件的封闭性)

//子组件定义暴露的方法
  setup(props: any, context: any) {
        context.expose({
            childrenName: '这是子组件暴露的组件名称',
            setMyName: (name: any) => {
                myInfo.name = '通过子组件暴露的方法修改的姓名' + name
            }
        })
        }
        
      //父组件定义组件ref属性名并先定义一个值为null的响应式数据之后,将其返回给模板使用即可.
      <son  ref='comp' > </son>
       setup() {
        const comp = ref(null)
        // 获取子组件对外暴露的属性
         console.log(comp.value.childrenName)   //打印结 果 这是子组件暴露的组件名称
         //也可以直接调用子组件暴露的comp.value.setMyName('') 
        }

v-model/emit

双向绑定,可以给组件绑定做个值

//父组件
  <son  v-model:keyWord='keyWord' > </son>
<script lang="ts">
import {ref } from 'vue'

export default {
setup(){
const keyWord = ref("keyWord")
return{
keyWord
}
}

</script>
//子组件 修改父组件值
setup(props,{emit}){
emit("update:keyWord", "新的keyWord")
}

provide(提供)/inject(注入)

vue3的composition Api 提供了一套协助父组件忘深层次组件传参的方法 通过provide传入的数据不是响应式的,如果修改了提供方的数据,在使用方是不会改变的,可以使用computed去计算传入的数据。provide的定义方式使用- 分开定义方式,两个参数,provide(属性名, 属性值)

//父组件
import {provide} from 'vue'
 setup() {
   provide("name", "沐华")
 }
 //子组件
 import {inject  } from 'vue'
  setup() {
  let name=inject('name')
 }

如果要将provide数据改为响应式数据 可以写成 provide("name", 为一个响应式值)

vuex

vue3中的vuex写法基本与vue2一致。使用时记得引入compositionAPI 中的{useStore} 大型项目依旧可以使用模块化状态管理;

//store/index.js定义时引入
import { createApp } from "vue" 


import { useStore, computed } from "vuex"
const store = useStore()
console.log(store.state[属性名])

文章参考Vue2.0与Vue3.0组件通信方式总结