Vue3手册译稿 - 深入组件 - Provide/注入

提供/注入

本章节需要掌握组件基础

我们经常使用props从父组件传递数据到子组件。相像一下你有一个多级嵌套的组件,你需要传递一个数据到底层的组件,你需要一级级往下传递,这样操作是比较繁琐的。
在这些场景下,我们使用provideinject对。父组件可以注入所有子组件一个数据,而不用关心这个组件到底有多少层级结构。这个功能分成两部分共同完成:父组件使用provide选项注入数据,而子组件有一个inject选项可以开始使用数据。

例如我们有个嵌套组件层级像这样:

Root
└─ TodoList
   ├─ TodoItem
   └─ TodoListFooter
      ├─ ClearTodosButton
      └─ TodoListStatistics

如果我们想传递todo-items长度到TodoListStatistics,需要层级传递:TodoList->TodoListFooter->TodoListStatistics。使用provide/inject,我们可以直接这么干 :

const app = Vue.createApp({})

app.component('todo-list', {
  data() {
    return {
      todos: ['Feed a cat', 'Buy tickets']
    }
  },
  provide: {
    user: 'John Doe'
  },
  template: `
    <div>
      {{ todos.length }}
      <!-- rest of the template -->
    </div>
  `
})

app.component('todo-list-statistics', {
  inject: ['user'],
  created() {
    console.log(`Injected property: ${this.user}`) // > Injected property: John Doe
  }
})

但是我们想传递组件实例属性时却不会工作:

app.component('todo-list', {
  data() {
    return {
      todos: ['Feed a cat', 'Buy tickets']
    }
  },
  provide: {
    todoLength: this.todos.length // 这会报错`Cannot read property 'length' of undefined`
  },
  template: `
    ...
  `
})

如果想访问组件实例属性,我们需要将provide转换为函数并返回一个对象:

app.component('todo-list', {
  data() {
    return {
      todos: ['Feed a cat', 'Buy tickets']
    }
  },
  provide() {
    return {
      todoLength: this.todos.length
    }
  },
  template: `
    ...
  `
})

这可以允许我们更安全的持续开发组件,而不必担心可能会更改或移除某些子组件依赖的内容。这些组件间的接口定义是清晰的,就像props
事实上,你可以把这种依赖注入相像成“长props”,除了:

  • 父组件并不需要知道具体是哪个层级组件使用它提供的数据。
  • 子组件并不需要知道这个数据到底是谁提供来的。

响应式工作

上面这个例子,如果我们更改了todos的列表,这个改变并不会传递到提供的todsLength属性,因为默认情况下provide并不是响应式的。我们可以传递refreactive对象给provide来改变这个行为。这个示例,我们响应式的改变顶级组件的属性值,我们需要为providetodoLength分配一个响应式的APIcomputed

app.component('todo-list', {
  // ...
  provide() {
    return {
      todoLength: Vue.computed(() => this.todos.length)
    }
  }
})

app.component('todo-list-statistics', {
  inject: ['todoLength'],
  created() {
    console.log(`Injected property: ${this.todoLength.value}`) // > Injected property: 5
  }
})

这样,任何todos.length的改变都会正确的反应到todoLength的组件中。
关于computed属性可以阅读计算属性及监听器了解更多,响应式provide/inject参考响应式API章节

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值