Vue的依赖注入

70 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第7天,点击查看活动详情

🎈大家好,我是李乐一,新人初来乍到,请多多关照~
📝小小的前端一枚,分享一些日常的学习和项目实战总结~
😜如果本文对你有帮助的话,帮忙点点赞呀!ღ( ´・ᴗ・` )比心~

依赖注入

组件逐层传递属性值是我们经常需要用到的,有时候,爷爷级别的组件需要传递给孙子级。这个时候通过pros逐层传递,父亲级可能不需要这个数据,这样使用pros会无形中增加父亲级的负担。vue给我们提供了provide 和 inject两个属性

provide 提供

举个栗子:父组件为它的子级组件提供数据。通过provide提供。

export default { 
    provide: { name: 'sara' } 
}

需要提供对象的时候也可以使用函数定义的形式,提供整个对象

export default {
  data() {
    return {
      name: 'sara'
    }
  },
  provide() {
    // 使用函数的形式,可以访问到 `this`
    return {
      name: this.name
    }
  }
}

注意:并不会保持响应性

除了给在局部的组件中注入,也可以全局提供。

举个栗子:

import { createApp } from 'vue' 
const app = createApp({}) 
app.provide(/* 注入名 */ 'name', /* 值 */ 'sara!')

这样这个数据就可以全局使用了。

Inject 注入

export default {
  inject: ['name'],
  created() {
    console.log(this.name) // injected value
  }
}

注意:注入的内容可以在在组件自身的状态之前被解析,所以我们可以在 data() 中访问到注入的属性

export default {
  inject: ['name'],
  data() {
    return {
      // 基于注入值的初始数据
      fullname: this.name
    }
  }
}

有时候可能注入的名字和组件内的属性的名字一样,这时候可以使用别名,来区分两者

export default {
  inject: {
      /* 本地属性名 */ localName: {
      from: /* 注入来源名 */ 'name'
    }
  }
}

这样就很方便了!我们可以在组件内给属性自定义一个名字。

前面说过,注入不是响应性的,这显然不符合我们的需求,我们希望传入的数据是最新的。这时候可以使用computed

import { computed } from 'vue'

export default {
  data() {
    return {
      name: 'sara!'
    }
  },
  provide() {
    return {
      // 显式提供一个计算属性
      sara: computed(() => this.sara)
    }
  }
}

完整栗子

爷爷级组件

<script>
import Child from './Child.vue'

export default {
  components: { Child },
  provide() {
    return {
      name: 'sara'
    }
  }
}
</script>

<template>
  <Child />
</template>

父亲级组件

<script>
import GrandChild from './GrandChild.vue'

export default {
  components: {
    GrandChild
  }
}
</script>

<template>
  <GrandChild />
</template>

孙子级组件

<script>
export default {
  inject: ['name']
}
</script>

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

我们看到,爷爷级组件通过provide提供给了孙子级组件name值。孙子组件通过inject注入了name属性。