Почему это глобальное локальное свойство Vue не определено в компоненте во время монтирования? - PullRequest
0 голосов
/ 21 января 2019

Я создал собственный плагин Vue, который создает глобальное свойство в Vue, например:

function (Vue, options) {
    Vue.$detector = new TranslatableStringDetector();
}

В моем компоненте я использую его внутри вычисляемого свойства, например:

export default {
    // ...
    computed: {
        decoratedProfileName () {
            return this.$detector.decorate(this.$props.profileName);
        }
    }
    // ...
}

В тесте «Карма / Мокко» я настроил его следующим образом:

before(() => {
            const localVue = createLocalVue();
            localVue.use(Vuex);
            localVue.use(TranslationDetector);

            store = new Vuex.Store(cloneDeep(storeDefinition));
            store.commit(SET_USER_DATA, userData);

            wrapper = shallowMount(Avatar, {
                localVue,
                store,
                propsData: {
                    id: 0,
                    inputElPrio: 2,
                    profileName: 'Default'
                }
            });
        });

shallowMount() - это то, что не работает со следующим сообщением об ошибке:

[Vue warn]: Error in config.errorHandler: "TypeError: Cannot read property 'decorate' of undefined"
TypeError: Cannot read property 'decorate' of undefined
    at VueComponent.decoratedProfileName (http://localhost:9877/base/index.js?22adbcd7eb33d018f956122e913fca2646b1c60b:132143:35)
    at Watcher.get (http://localhost:9877/base/index.js?22adbcd7eb33d018f956122e913fca2646b1c60b:71415:25)
    at Watcher.evaluate (http://localhost:9877/base/index.js?22adbcd7eb33d018f956122e913fca2646b1c60b:71522:21)
    at VueComponent.computedGetter [as decoratedProfileName] (http://localhost:9877/base/index.js?22adbcd7eb33d018f956122e913fca2646b1c60b:71780:17)
    at Object.get (http://localhost:9877/base/index.js?22adbcd7eb33d018f956122e913fca2646b1c60b:70216:20)
    at Proxy.render (http://localhost:9877/base/index.js?22adbcd7eb33d018f956122e913fca2646b1c60b:180100:43)
    at VueComponent.Vue._render (http://localhost:9877/base/index.js?22adbcd7eb33d018f956122e913fca2646b1c60b:72817:22)
    at VueComponent.updateComponent (http://localhost:9877/base/index.js?22adbcd7eb33d018f956122e913fca2646b1c60b:71061:21)
    at Watcher.get (http://localhost:9877/base/index.js?22adbcd7eb33d018f956122e913fca2646b1c60b:71415:25)
    at new Watcher (http://localhost:9877/base/index.js?22adbcd7eb33d018f956122e913fca2646b1c60b:71404:12)
[Vue warn]: Error in render: "TypeError: Cannot read property 'decorate' of undefined"

found in

---> <Avatar> at src/components/controls/Avatar.vue
       <Root>
TypeError: Cannot read property 'decorate' of undefined
    at VueComponent.decoratedProfileName (http://localhost:9877/base/index.js?22adbcd7eb33d018f956122e913fca2646b1c60b:132143:35)
    at Watcher.get (http://localhost:9877/base/index.js?22adbcd7eb33d018f956122e913fca2646b1c60b:71415:25)
    at Watcher.evaluate (http://localhost:9877/base/index.js?22adbcd7eb33d018f956122e913fca2646b1c60b:71522:21)
    at VueComponent.computedGetter [as decoratedProfileName] (http://localhost:9877/base/index.js?22adbcd7eb33d018f956122e913fca2646b1c60b:71780:17)
    at Object.get (http://localhost:9877/base/index.js?22adbcd7eb33d018f956122e913fca2646b1c60b:70216:20)
    at Proxy.render (http://localhost:9877/base/index.js?22adbcd7eb33d018f956122e913fca2646b1c60b:180100:43)
    at VueComponent.Vue._render (http://localhost:9877/base/index.js?22adbcd7eb33d018f956122e913fca2646b1c60b:72817:22)
    at VueComponent.updateComponent (http://localhost:9877/base/index.js?22adbcd7eb33d018f956122e913fca2646b1c60b:71061:21)
    at Watcher.get (http://localhost:9877/base/index.js?22adbcd7eb33d018f956122e913fca2646b1c60b:71415:25)
    at new Watcher (http://localhost:9877/base/index.js?22adbcd7eb33d018f956122e913fca2646b1c60b:71404:12)

Как это возможно?С помощью операторов console.debug() (недавно Chrome прервал отладку) я могу подтвердить, что localVue.$detector настроен правильно.Однако внутри моего компонента он недоступен как this.$detector.В примере это приводит к неопределенности:

export default {
    // ...
    created: function () {
        console.debug(this.$detector);
    }
    // ...
}

Ответы [ 2 ]

0 голосов
/ 21 января 2019

Вводя в заблуждение документацией Vue.js Я предполагал "глобальный" в смысле единого объекта, доступного для всех компонентов. Придерживаясь документации, я действительно хотел иметь «метод экземпляра», который действительно отображает свойство для всех компонентов. Это небольшое, но важное отличие, которое решает проблему. Я как-то пробовал и пропустил этот подход раньше, потому что что-то еще не работало. Установка должна выглядеть так:

function (Vue, options) {
    Vue.prototype.$detector = new TranslatableStringDetector();
}
0 голосов
/ 21 января 2019

Насколько я понимаю, использование лямбда-функций (анонимная функция) в хуках жизненных циклов работать не будет, поскольку this имеет ссылку на родительский объект, для которого он является нулевым.

вместо него используется function() { /*your code*/ }.

...