vuejs / vue

This is the repo for Vue 2. For Vue 3, go to https://github.com/vuejs/core
http://v2.vuejs.org
MIT License
208k stars 33.69k forks source link

Using provide and inject in components from local file system #11938

Closed relief-melone closed 3 years ago

relief-melone commented 3 years ago

Version

2.6.12

Reproduction link

https://gitlab.com/rm-issues/vue-external-components-provide-inject

Steps to reproduce

Use a parent component and Child component from a folder in your local file system that is not in your current project folder.

This would be the case e.g. for testing reusable components located in their own project folder and wanting to debug them.

In the Repo this is already present. To reproduce there

npm install in project root folder npm install in src/external-folder (representing an external vue project somewhere on your file system) npm run serve

What is expected?

EP_foo (provided variable in external module) should be provided and injected to it's child component just like it's the case with P_foo (provided variable in the project internal component)

What is actually happening?

While the providing and injecting works just fine with components in the project. in projects that are imported from somewhere else on the drive the injected variable is not found in the child component.

Additional Comments

Debugging vues src/core/instance/inject.ts it seems like the external child components parent derived from vm.$options.source.$parent points to the external components root app instead of the parent used in the app. However if the childs parent is determined by vm.$options.vm.$parent the correct parent with the data seems to be present. Now I'm not too familiar with vue.js' source code and using ...vm.$parent might come with other implications but I just wanted to point out the finding

posva commented 3 years ago

You had a typo EP_FOO and EP_foo.


Please, next time consider using the forum, the Discord server or StackOverflow for questions first. But feel free to come back and open an issue if it turns out to be a bug 🙂

relief-melone commented 3 years ago

Hmm, OK. That's kind of embarrassing. Thanks for the reply. I'll keep investigating. With my life project it definately works with the rollup built component but doesn't if you import from source. But that's a little too much for an issue repo. I will open up a new issue if it turns out to be a bug or at least report a follow up if it was a configuration mistake. Thanks again for the quick reply

relief-melone commented 3 years ago

Ok i was able to reproduce it but wanted to clarify before just spammig up your issues. So the problem was this and I didn't think it was necessary to reproduce the error. I am using Typescript for my project and to get Type support my external Component is insantiated like this

Parent,vue

import Vue from "vue";

export default Vue.extend({
  data: () => ({
    foo: 'bar'
  }),
  provide(){
    return {
      EP_FOO: this.foo,
    }
  }
})

Now the problem is that it seems that if you do this. Parent and child seem to end up in different Vue instances. However if I don't use Vue.extend I loose type support and if I go back to declaring this as any it kind of defeats the purpose of TypeScript.

So my next thought was, great. Finally a reason to do this component with the composition API. However if you are using the composition API in your internal project as well as the external one you run into a similar issue again. So before I open a new TypeScript specific issue I wanted to clarify

posva commented 3 years ago

You have to mark Vue as an external dependency when bundling your component libraries. (Same for @vue/composition-api)

relief-melone commented 3 years ago

After beeing bundled it is usually no problem. But while I use the source version to debug I have this problem.