iT邦幫忙

2021 iThome 鐵人賽

DAY 9
0
Modern Web

別再說我不會框架,網頁 Vue 起來!系列 第 9

[Part 3 ] Vue.js 的精隨-元件 provide/inject

利用 provide & inject 機制,父元件當作所有其子元件的 provider,無論所屬的子元件有多深!

  • 父元件利用 provide option 提供資料
    • 要傳遞的資料使用 provide 定義
  • 子/孫元件利用 inject option 去使用資料

假設有一個這樣的層級:

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

要從todo-items傳值給 TodoListStatistics ,可以利用先前介紹的 props 一層一層往下傳
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 的屬性: John Doe
  }
})

但但但,無法傳遞實體元件的屬性,如以下例子
ex:

app.component('todo-list', {
  data() {
    return {
      todos: ['Feed a cat', 'Buy tickets']
    }
  },
  provide: {
    todoLength: this.todos.length // 會報錯 `Cannot read property 'length' of undefined` 
    // 無法取得 data 中的 todos
  },
  template: `
    ...
  `
})

如果要取得實體元件中的屬性,必須將 provide 轉成 function 並回傳物件

ex:

app.component('todo-list', {
  data() {
    return {
      todos: ['Feed a cat', 'Buy tickets']
    }
  },
  // function 形式
  provide() {
    // 回傳物件
    return {
      todoLength: this.todos.length
    }
  },
  template: `
    ...
  `
})

補充

有關跨層級傳遞,往後還會介紹(?!)

  • mitt
  • Vuex
  • Vue Composition API

下篇預告

  • Slots

每日一句:
每天都在跟時間賽跑 /images/emoticon/emoticon33.gif


上一篇
[Part 2 ] Vue.js 的精隨-元件 Props
下一篇
[番外] 來個 Weather App (序)
系列文
別再說我不會框架,網頁 Vue 起來!30

尚未有邦友留言

立即登入留言