vue3 依赖注入 compositonApi provide inject简单介绍

45 阅读2分钟

这是我参与「掘金日新计划 · 8 月更文挑战」的第14天,点击查看活动详情 使用compositonApi的 provide inject,但是这两个东西只能在setup里面调用 可以看下在compositonApi下调用,我们就不写那么多层级了

我们需要从vue当中把provide inject导出来,让我们自己定义provide属性,可以定义两个参数,第一个是属性名称,第两个参数数value值 代码 father.vue

import {
 provide,
 isRef} from 'vue'
export default {
  setup() {
    provide('name',"providename")
    provide('age',"1312313123")
  }
}

child.vue 使用 inject也有两个参数,第一个参数需要的属性名字,地两个参数是默认值

<template>
  <div>
    <div>{{a}}</div>
    <div>{{b}}</div>
  </div>
</template>
import {
 inject,
 isRef} from 'vue'
 export default {
  setup() { 
     let a = inject('name',"默认name") // 需要把接收过来的值返回才能使用
     let b = inject('age',"默认age")
     return{
        a,
        b
     } 
  }
}

可以响应式的,需要我们用定义数据的时候需要用倒ref和reactive 代码其实和上面的差别不大,主要是父组件的provide的写法需要修改

<template>
    <div>
      <div @click="changeName">
      点击
      </div> 
      </child>
    </div>
</template>  
import {
 provide,
 ref
 isRef} from 'vue'
 import child from 'child.vue'
export default {
 let name = ref('providename')
 let age = ref('1312313123')
  setup() {
    provide('name',name)
    provide('age',readonly(age))
    let changeName = ()=>{
       name.value = '我改变了'
    }
    provide('changeName',changeName)
    return {
      changeName
    }
  }
}

自组建不变,这样写就是响应式的了,和options的provide inject简单多了,父组件不需要写成函数返回,子组件不需要写计算属性接受执行了,才能实现响应式

如果我们想改变provide的数据,我们最好在父组件是操作,或者用父组件传过来的方法去改变,如果你想保证数据的改变都来自于父级,你需要用readonly来包裹provide里的数据,这样才能保证子组件不会自己擅自更改,但是有人就是想在子组件改变数据可以吗,其实是可以的我们可以看下代码 child.vue

<template>
  <div>
    <div>{{a}}</div>
    <div>{{b}}</div>
    <div @click="">点击</div>
  </div>
</template>
import {
 inject,
 isRef} from 'vue'
 export default {
  setup() { 
     let a = inject('name',"默认name") // 需要把接收过来的值返回才能使用
     let b = inject('age',"默认age")
     let changeName = inject('changeName') // 这样方式也可以改变子组件数据
     
     setimeout(()=>{
      a.vaue="大椎啊" // 这样就可以轻易的更改了父组件传过来的数据,所以建议父组件的数据加readonly保证子组建不会轻易更改
     },1000)
     
     return{
        a,
        b,
        changeName
     } 
  }
}