Vue 3.0 選項 組合

2022-04-18 14:25 更新

#mixins

  • 類型:Array<Object>

  • 詳細:

mixins 選項接收一個混入對象的數(shù)組。這些混入對象可以像正常的實例對象一樣包含實例選項,這些選項將會被合并到最終的選項中,使用特定的選項合并邏輯。例如,如果 mixin 包含一個 created 鉤子,而創(chuàng)建組件本身也有一個,那么兩個函數(shù)都會被調(diào)用。

Mixin 鉤子按照傳入順序依次調(diào)用,并在調(diào)用組件自身的鉤子之前被調(diào)用。

  • 示例:

  const mixin = {
    created: function() {
      console.log(1)
    }
  }

  
  Vue.createApp({
    created() {
      console.log(2)
    },
    mixins: [mixin]
  })

  
  // => 1
  // => 2

#extends

  • 類型:Object | Function

  • 詳細:

允許聲明擴展另一個組件 (可以是一個簡單的選項對象或構(gòu)造函數(shù))。這主要是為了便于擴展單文件組件。

這和 mixins 類似。

  • 示例:

  const CompA = { ... }

  
  // 在沒有調(diào)用 `Vue.extend` 時候繼承 CompA
  const CompB = {
    extends: CompA,
    ...
  }

#provide / inject

  • 類型:

  • provide:Object | () => Object
  • inject:Array<string> | { [key: string]: string | Symbol | Object }

  • 詳細:

這對選項需要一起使用,以允許一個祖先組件向其所有子孫后代注入一個依賴,不論組件層次有多深,并在起上下游關(guān)系成立的時間里始終生效。如果你熟悉 React,這與 React 的 context 特性很相似。

provide 選項應(yīng)該是一個對象或返回一個對象的函數(shù)。該對象包含可注入其子孫的 property。在該對象中你可以使用 ES2015 Symbols 作為 key,但是只在原生支持 SymbolReflect.ownKeys 的環(huán)境下可工作。

inject 選項應(yīng)該是:

  • 一個字符串?dāng)?shù)組,或
  • 一個對象,對象的 key 是本地的綁定名,value 是:
    • 在可用的注入內(nèi)容中搜索用的 key (字符串或 Symbol),或
    • 一個對象,該對象的:
      • from property 是在可用的注入內(nèi)容中搜索用的 key (字符串或 Symbol)
      • default property 是降級情況下使用的 value

提示:提示:provideinject 綁定并不是響應(yīng)式的。這是刻意為之的。然而,如果你傳入了一個響應(yīng)式的對象,那么其對象的 property 仍是響應(yīng)式的。

  • 示例:

  // 父級組件提供 'foo'
  const Provider = {
    provide: {
      foo: 'bar'
    }
    // ...
  }

  
  // 子組件注入 'foo'
  const Child = {
    inject: ['foo'],
    created() {
      console.log(this.foo) // => "bar"
    }
    // ...
  }

利用 ES2015 Symbols、函數(shù) provide 和對象 inject

  const s = Symbol()

  
  const Provider = {
    provide() {
      return {
        [s]: 'foo'
      }
    }
  }

  
  const Child = {
    inject: { s }
    // ...
  }

使用一個注入的值作為一個 property 的默認值:

  const Child = {
    inject: ['foo'],
    props: {
      bar: {
        default() {
          return this.foo
        }
      }
    }
  }

使用一個注入的值作為數(shù)據(jù)入口:

  const Child = {
    inject: ['foo'],
    data() {
      return {
        bar: this.foo
      }
    }
  }

注入可以通過設(shè)置默認值使其變成可選項:

  const Child = {
    inject: {
      foo: { default: 'foo' }
    }
  }

如果它需要從一個不同名字的 property 注入,則使用 from 來表示其源 property:

  const Child = {
    inject: {
      foo: {
        from: 'bar',
        default: 'foo'
      }
    }
  }

與 prop 的默認值類似,你需要對非原始值使用一個工廠方法:

  const Child = {
    inject: {
      foo: {
        from: 'bar',
        default: () => [1, 2, 3]
      }
    }
  }

#setup

  • 類型:Function

setup 函數(shù)是一個新的組件選項。它作為在組件內(nèi)部使用組合式 API 的入口點。

  • 調(diào)用時間

在創(chuàng)建組件實例時,在初始 prop 解析之后立即調(diào)用 setup。在生命周期方面,它是在 beforeCreate 鉤子之前調(diào)用的。

  • 模板使用

如果 setup 返回一個對象,則該對象的屬性將合并到組件模板的渲染上下文中:

  <template>
    <div>{{ count }} {{ object.foo }}</div>
  </template>

  
  <script>
    import { ref, reactive } from 'vue'

  
    export default {
      setup() {
        const count = ref(0)
        const object = reactive({ foo: 'bar' })

  
        // 暴露到template中
        return {
          count,
          object
        }
      }
    }
  </script>

請注意,從 setup 返回的 refs 在模板中訪問時會自動展開,因此模板中不需要 .value。

  • 渲染函數(shù)/JSX 的方法

setup 還可以返回一個渲染函數(shù),該函數(shù)可以直接使用在同一作用域中聲明的響應(yīng)式狀態(tài):

  import { h, ref, reactive } from 'vue'

  
  export default {
    setup() {
      const count = ref(0)
      const object = reactive({ foo: 'bar' })

  
      return () => h('div', [count.value, object.foo])
    }
  }

  • 參數(shù)

該函數(shù)將接收到的 prop 作為其第一個參數(shù):

  export default {
    props: {
      name: String
    },
    setup(props) {
      console.log(props.name)
    }
  }

請注意,此 props 對象是響應(yīng)式的——即在傳入新的 props 時會對其進行更新,并且可以通過使用 watchEffectwatch 進行觀測和響應(yīng):

  export default {
    props: {
      name: String
    },
    setup(props) {
      watchEffect(() => {
        console.log(`name is: ` + props.name)
      })
    }
  }

但是,請不要解構(gòu) props 對象,因為它會失去響應(yīng)式:

  export default {
    props: {
      name: String
    },
    setup({ name }) {
      watchEffect(() => {
        console.log(`name is: ` + name) // 沒有響應(yīng)式
      })
    }
  }

props 對象在開發(fā)過程中對于用戶區(qū)代碼是不可變的 (如果用戶代碼嘗試對其進行更改,則會發(fā)出警告)。

第二個參數(shù)提供了一個上下文對象,該對象暴露了以前在 this 上暴露的 property 的選擇列表:

  const MyComponent = {
    setup(props, context) {
      context.attrs
      context.slots
      context.emit
    }
  }

attrsslots 是內(nèi)部組件實例上相應(yīng)值的代理。這樣可以確保它們即使在更新后也始終會顯示最新值,以便我們可以對它們進行結(jié)構(gòu)分解,而不必擔(dān)心訪問老的引用:

  const MyComponent = {
    setup(props, { attrs }) {
      // 稍后可能會調(diào)用的函數(shù)
      function onClick() {
        console.log(attrs.foo) // 保證是最新引用
      }
    }
  }

有很多理由將 props 作為單獨的第一個參數(shù)而不是將其包含在上下文中:

  • 組件使用 props 比其他 property 更常見,并且很多情況下組件僅使用 props。
  • props 作為單獨的參數(shù)可以使單獨鍵入更容易,而不會弄亂上下文中其他 property 的類型。這也使得在具有 TSX 支持的 setup、render 和普通功能組件之間保持一致的簽名成為可能。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號