【问题标题】:Vue 3 composition API and access to Vue instanceVue 3 组合 API 和对 Vue 实例的访问
【发布时间】:2020-05-28 20:38:20
【问题描述】:

main.js 我有这样的东西:

import { myUtilFunc} from './helpers';
Object.defineProperty(Vue.prototype, '$myUtilFunc', { value: myUtilFunc });

通过这种方式,我可以使用this.$myUtilFunc 在整个应用程序中访问myUtilFunc

但是,如果我无法访问 this,如何在 Vue 3 的 setup() 方法中实现相同的效果?

【问题讨论】:

    标签: javascript vue.js vue-component vuejs3 vue-composition-api


    【解决方案1】:

    使用provide/inject

    提供

    const app = createApp(App);
    app.provide('someVarName', someVar);  // `Provide` a variable to all components here
    

    注入

    // In *any* component
    const { inject } = Vue;
    ...
    setup() {
      const someVar = inject('someVarName');   // injecting variable in setup
    }
    

    请注意,您不必从应用根目录提供,也可以从任何组件provide 仅提供其子组件:

    // In *any* component
    setup() {
      ...
    },
    provide() {
      return {
        someVarName: someVar
      }
    }
    

    原答案

    [编辑:虽然我下面的原始答案对context 属性仍然有用,但不再建议使用context.rootguide 中不再提及并且可能很快就会被弃用。]

    在 Vue 3 中,setup 有一个可选的第二个参数 context。你可以通过context.root而不是this来访问Vue实例:

    setup(props, context) {
      context.root.$myUtilFunc  // same as `this.$myUtilFunc` in Vue 2
    }
    

    您可以通过context 访问的内容:

    context.attrs
    context.slots
    context.parent
    context.root
    context.emit
    

    【讨论】:

      【解决方案2】:

      虽然 Dan 的答案是正确的,但我想提供 cmets 中提到的替代答案来替代已接受的答案。各有优劣,所以需要根据自己的需要来选择。

      要理解为什么下面的代码有效,重要的是要记住,提供的属性在组件树中是可传递的。 IE。 inject('foo') 将在每个父级中查找“foo”,一直到app;无需在中间包装器中声明任何内容。

      所以,我们可以这样写,其中 globalDateFormatter() 只是我们想在树下的任何组件中使用的示例函数:

      ma​​in.js

      import { createApp } from 'vue'
      import App from './App.vue'
      
      const globalDateFormatter = (date) => {
          return '[' + date.toLocaleString() + ']'
      }
      
      const app = createApp(App)
      app.provide('globalDateFormatter', globalDateFormatter) // <-- define here
      app.mount('#app')
      

      然后,在一些 DeepDownComponent.vue 中:

      <template>
        <p> {{ fmt(new Date()) }} </p>
      </template>
      
      <script>
      import { inject } from 'vue'
      export default {
          setup(){
              const fmt = inject('globalDateFormatter', x => x.toString()) 
              //           ^-- use here, optional 2nd parameter is the default
              return {fmt}
          }
      }
      </script>
      

      显然,您可以直接导入并使用provideinject,并带有以下签名

      provide<T>(key: InjectionKey<T> | string, value: T): void
      

      inject<T>(key: InjectionKey<T> | string, defaultValue: T): T
      

      代码中的任何位置,不必是app.provide()

      你也可以提供值,甚至是全局存储,像这样,只是别忘了根据需要使用ref()reactive()

      简而言之,只要你喜欢依赖注入,provide/inject 就是你的朋友。

      【讨论】:

        猜你喜欢
        • 2021-07-01
        • 1970-01-01
        • 2017-08-22
        • 2021-08-25
        • 1970-01-01
        • 2019-02-27
        • 2018-09-08
        • 1970-01-01
        • 2018-06-13
        相关资源
        最近更新 更多