Vue 3 составной API и доступ к Vue экземпляру - PullRequest
5 голосов
/ 13 февраля 2020

В main.js У меня есть что-то вроде этого:

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

Таким образом, у меня есть доступ к myUtilFunc во всем приложении с this.$myUtilFunc

Но как мне достичь то же самое в setup() методе в Vue 3, если у меня нет доступа к this?

Ответы [ 2 ]

5 голосов
/ 13 февраля 2020

В Vue 3, setup имеет необязательный второй аргумент для context. Вы можете получить доступ к экземпляру Vue через context.root вместо this:

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

Вещи, к которым вы можете получить доступ через context:

context.attrs
context.slots
context.parent
context.root
context.emit
0 голосов
/ 11 апреля 2020

Хотя ответ Дэна правильный, я хотел бы предоставить альтернативу, упомянутую в комментариях, к принятому ответу. У каждого есть свои плюсы и минусы, поэтому вам нужно выбирать в зависимости от ваших потребностей.

Чтобы понять, почему работает приведенный ниже код, важно помнить, что предоставляемые свойства являются транзитивными в дереве компонентов. Т.е. inject('foo') будет искать 'foo' в каждом родителе, идущем вверх по иерархии вплоть до app; нет необходимости декларировать что-либо в середине обертки.

Итак, мы можем написать что-то вроде этого:

main. 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>

Очевидно, что вы можете использовать

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

и

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

в любом месте вашего кода, не имеет быть app.provide()

Вы также можете указать значения, даже глобальное хранилище, например, просто не забывайте использовать ref() или reactive() по мере необходимости.

Короче говоря, когда вы предпочитаете внедрение зависимостей, предоставьте / введите ваши друзья.

...