Программно созданный компонент Vue, в котором отсутствуют глобальные свойства, определенные в Vue.prototype

У меня проблема при создании экземпляра компонента vue, импортированного из объединенной библиотеки накопительных пакетов, я добавляю глобальное свойство к корневому экземпляру Vue с помощью Vue.prototype, и оно используется всеми моими компонентами, однако, когда я создаю новый экземпляр используя метод Vue.extend, вновь созданный компонент не имеет ни одного из свойств прототипа или глобальных переменных, все они просто возвращают undefined.



//Main.js
Vue.prototype.$example = 'Hello there!';

//////////////////////////////

new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')


//App.vue
import { MyDynamicComponent } from 'my-bundled-rollup-library';
export default {
    created() {

        var DynamicComponent = Vue.extend(MyDynamicComponent);

        console.log(this.$example) //Returns 'Hello there!' (correct)
        var instance = new DynamicComponent({
            propsData: {
                hello:'world',
            },
        })

        ///////////////////////////////////////////

        console.log(instance.$example) //Returns undefined (does not have the property)
    }
}

А вот пример компонента до того, как он был собран.

//MyDynamicComponent.vue
const MyDynamicComponent = {
     props:{
          hello:{
               type:String
          }
     },
     created() {
          console.log(this.$example) //undefined
     }
}

export default component
export { MyDynamicComponent as MyDynamicComponent }

Моя первая мысль заключается в том, что каким-то образом компонент использует другой экземпляр Vue, чем экземпляр Vue.extend.


person Cade Embery    schedule 26.04.2020    source источник
comment
Обычно это означает, что vue в my-bundled-rollup-library не то же самое, что vue в Main.js. Это очень специфическая для вас установка, которая не была показана. Шаги для решения этой проблемы: 1. Убедитесь, что vue не входит в комплект my-bundled-rollup-library. 2. Убедитесь, что ограничения vue dep максимально свободны, должны быть peerDependencies или * в зависимостях. 3. Выведите пакеты с помощью npm dedupe, если это не поможет, удалите и переустановите node_modules. Позвольте мне знать, если это помогает. Если этого не произошло, дайте возможность воспроизвести проблему.   -  person Estus Flask    schedule 26.04.2020
comment
@EstusFlask СПАСИБО! Иногда самые простые предложения помогают найти ответ. Я уже установил vue как peerDependency и указал как внешний. Однако (я уже должен это знать) я удалил папку node_modules, переустановил и перестроил снова, а затем смог найти проблему в файле rollup.config.   -  person Cade Embery    schedule 26.04.2020


Ответы (2)


Я воссоздал все приложение, и оно у меня работает. Я перенес компонент с помощью свертки и импортировал его в приложение, созданное с помощью интерфейса командной строки vue.

Единственное, что меня озадачивает, - это почему вы не импортировали компонент по умолчанию?

import { MyDynamicComponent } from 'my-bundled-rollup-library';
// to
import MyDynamicComponent from 'my-bundled-rollup-library';

Вы экспортируете его по умолчанию, поэтому вам нужно импортировать его по умолчанию.

Информация. Это часть внутри vue, которая создает новый объект-прототип «sub» с прототипом «super» https://github.com/vuejs/vue/blob/dev/src/core/global-api/extend.js#L36

rollup.config.js

import vue from 'rollup-plugin-vue'

export default {
  input: 'component.vue',
  output: {
    format: 'esm',
    file: 'dist/MyComponent.js'
  },
  plugins: [
    vue()
  ]
}

dist / MyComponent.js

Это сгенерированный файл из MyComponent.vue

import { openBlock, createBlock } from 'vue';

//
//
//

var script = {
  props: {
    hello: {
      type: String,
    },
  },
  created() {
    console.warn('MY_COMPONENT', this.$example); // should work
  },
};

function render(_ctx, _cache) {
  return (openBlock(), createBlock("div", null, "hoi"))
}

script.render = render;
script.__file = "component.vue";

export default script;

App.vue (тег скрипта)

import Vue from 'vue';
import MyComponent from './dist/MyComponent'; // throws some warnings, but this is not relevant for this post

export default {
  name: 'App',
  created() {
    const DynamicComponent = Vue.extend(MyComponent);

    const instance = new DynamicComponent({
      propsData: {
        hello: 'world',
      },
    });

    console.log('instance', instance.$example);
  },
};
person Phil    schedule 26.04.2020
comment
Да, извините, это часть библиотеки компонентов из 120 частей, я написал пример как мог, но должен был написать его как именованный экспорт. - person Cade Embery; 26.04.2020

После rm -rf node_modules и переустановки и повторной попытки перекомпилировать мою библиотеку с помощью накопительного пакета, свертывание выдало ошибку, которую раньше не выдавало, вместо псевдонима для использования пакета компилятора Vue runtime +.

[!] Error: Cannot find module 'vue/dist/vue.esm.js'

В моем файле rollup.config


import vue from 'rollup-plugin-vue';

import alias from '@rollup/plugin-alias';

export default {
    plugins: {
        alias({
            entries: [
                //Removing this line fixed the problem
                //{ find: 'vue', replacement: require.resolve('vue/dist/vue.esm.js') },
            ],
        }),
        vue,
    }
}

Итак, усвоенный урок состоит в том, что когда дела идут странно, rm -rf node_modules и заново все перестраивают.

person Cade Embery    schedule 26.04.2020