Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vue using wrong component when there're global and local components with same name but registered with different naming conventions #4434

Closed
jiangfengming opened this issue Dec 10, 2016 · 14 comments

Comments

@jiangfengming
Copy link

JSFiddle: http://jsfiddle.net/fenivana/3y7hzwg8/

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <script src="https://unpkg.com/vue/dist/vue.js"></script>
  </head>

  <body>
    <div id="app">
      <x-foo/>
    </div>

    <script>
    Vue.component('x-foo', {
      template: '<div>global foo component will be used</div>'
    })

    new Vue({
      el: '#app',

      components: {
        XFoo: {
          template: '<div>local foo component won\'t show</div>'
        }
      }
    })
    </script>
  </body>
</html>
@JounQin
Copy link
Contributor

JounQin commented Dec 10, 2016

change it to:

new Vue({
    el: '#app',
    components: {
      'x-foo': {
        template: '<div>local foo component won\'t show</div>'
    }
  }
})

x-foo and XFoo are different, it seems to be just a fallback when x-foo component not found.

@fnlctrl
Copy link
Member

fnlctrl commented Dec 10, 2016

^ As above

@fnlctrl fnlctrl closed this as completed Dec 10, 2016
@jiangfengming
Copy link
Author

I exactly know changing to x-foo can solve the problem, but I think the fallback preference is wrong. It should find all naming conventions in local registered components first, If not found, then look into global components.

@jiangfengming
Copy link
Author

@yyx990803 @fnlctrl What do you think?

@jiangfengming
Copy link
Author

jiangfengming commented Dec 10, 2016

And how can I know what naming conventions the third party UI libraries are using? Will my local components with the same name conflict with theirs? Who knows.

@fnlctrl
Copy link
Member

fnlctrl commented Dec 10, 2016

And how can I know what naming conventions the third party UI libraries are using?

Why would it be relevant? You can always alias them inside the components options.

Consider the reverse scenario, where you want to override a third party component's local component x-foo, with your own globally registered component x-foo.

Anyway, you should always explicitly alias components if there is a potential naming conflict, and never rely on the fallback precedence.

@jiangfengming
Copy link
Author

jiangfengming commented Dec 10, 2016

Why would it be relevant? You can always alias them inside the components options.

The real scenario is, when we use a UI collection set. we simply import it and use it:

import SomeUI from 'some-ui'
Vue.use(SomeUI)

We don't need to care about whether it's registered with kebab-case, camelCase, or TitleCase.

If we register a local component , we simply do:

<template>
  <div>
    <tab-pane>something</tab-pane>
  </div>
</template>

<script>
import TabPane from './TabPane.vue'
export default {
  components: {
    TabPane
  }
}
</script>

But what if SomeUI also has a component named 'tab-pane', and it is registered with:

Vue.component('tab-pane', {...})

Then the local registered component will never be used.

We have to use a longer syntax:

export default {
  component: {
    'tab-pane': TabPane
  }
}

And what you said overriding a thirty UI's local component with a global component is a rare case, it's like a hack. And if it's local component is registered with kebab-case, you'd never had a chance.

And, the vue guide says:

When registering components (or props), you can use kebab-case, camelCase, or TitleCase.
Vue doesn’t care.

And you just told me vue cares about it, and we should care about it too!

@fnlctrl
Copy link
Member

fnlctrl commented Dec 10, 2016

And you just told me vue cares about it, and we should care about it too!

That's not what I said. Let me quote my words again:

You should always explicitly alias components if there is a potential naming conflict, and never rely on the fallback precedence.

In your case you're creating a component that has the same name of a 3rd party component, which should have been avoided in the first place, since it's you defining the local component and you have full control over its name.

@jiangfengming
Copy link
Author

Please don't play with words. What the fact is I registered a component with the wrong naming convention and Vue cares about it.

Please let @yyx990803 to end the dispute.

@jiangfengming
Copy link
Author

Yeah, you can say, it's not a bug, it's a feature, doc is wrong, not the code.

@ktsn
Copy link
Member

ktsn commented Dec 10, 2016

I think this is a bug, camel case and title case component name seems aliases rather than fallback. Practically, we use camel/title case to register local component (with ES6 object shorthand) since JavaScript does not allow kebab case as variable names.

And also, local component should not be overridden by global components. It can easily cause unexpected behavior and break capsulations of third party components.

@LinusBorg LinusBorg reopened this Dec 10, 2016
@defcc
Copy link
Member

defcc commented Dec 10, 2016

Sounds reasonable, but maybe it will bring a breaking change.

@JounQin
Copy link
Contributor

JounQin commented Dec 10, 2016

What about using both of them (<x-foo/> and <XFoo/>) in one template, how could it render? Are they same?

@defcc
Copy link
Member

defcc commented Dec 10, 2016

@JounQin Here is what happend internally.

const res = assets[id] ||

const res = assets[id] ||
    // camelCase ID
    assets[camelize(id)] ||
    // Pascal Case ID
    assets[capitalize(camelize(id))]

with [, it will check prototype chain, so first x-foo, then XFoo

So I think it might bring breaking change in some cases if we apply the new resolving strategy.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants