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

Incorrectly treating the component tag name as a function with the same name and unexpected calling the function twice #9303

Open
Wayne831 opened this issue Sep 27, 2023 · 3 comments
Labels
🍰 p2-nice-to-have Priority 2: this is not breaking anything but nice to have it addressed. has workaround A workaround has been found to avoid the problem

Comments

@Wayne831
Copy link

Vue version

3.3.4

Link to minimal reproduction

https://play.vuejs.org/#eNqNU8Fu2zAM/RXBl7RAbWHoTplrdCt62A7bsG43XzyZidXalCDRaYAi/15KblzXToECAWKR1HuPT+RT8tXabNdDsk5ygs62FUFRohB586mgRnvBP64RynTWICDlkjOxwlPlKFUGd+B8RdpgkcsTwVgc7nM6/pWYywkZH71y2pLwQH1Ia+ZyJO4C1s0ESmyc6cQqk4tM6GH1Zbx5wzRjcTgc8yWyNM9MC+grcXYurgrxFOSGItNC1prt2eofwt6CIqiFqtpW41ZselTh1uq8xAPDct+xgyK5SAYJaVfZ7N4bZGcjZPmS8GWyHkhCjGWFc5k0RNavpVQ18rUaWr1zGQJJtJ285jLpeiTdQVqb7voyu8w+y1p7moYz8F3635lHD45ByuRiQiM5yN2mDrAGB+6jtLNrU+pZakEf2A9sEJtCni3d6O3MkjAOugX3ywY331rDVpvHHzFGroexF9WAejgRv/f7oaffDqKySf/82lugIX179xP2/D0mO1P37cszvJP8AzwOfdA4lH3rsWbZk7qo9nt8YR6Qv/52T4D+2FQQGt2I9fE9wlS+1/qrXHZ74uLJsV+sLm+bHXd3uY9CNbrlUX5d6NlGMtFxZU5gH4ErNNSAm6O9RTo8A7y8gtQ=

Steps to reproduce

In the same Vue file (For example: App.vue):
First you import another Vue component as its child component, assuming the name of the child component is StartConversation, like this:
import StartConversation from './StartConversation.vue';
And in template, we can use this component name with kebeb-case "start-conversation" as html tag.

Then, you have a function that has the same name as the child components mentioned aboved, like this:
const startConversation = () => {console.log('Unexpected call the func')};

When you start the Vue project, you can see "Unexpected call the func" printed twice in the console. In the case of Vue SFC playground (link to minimal reproduction provided before), the start-conversation child component will not be rendered.

What is expected?

Vue child component file name should be distinguished from the function name. Notice that the component tag name is kebeb-case, the file name and the registered component name is PascalCase, and the function name is camelCase.

What is actually happening?

The function is incorrectly executed twice due to the component tag name "start-conversation" and "/start-conversation". Although we can use self-closing tag "start-conversation /" in Vue3, the function will also be executed twice.

System Info

No response

Any additional comments?

No response

@baiwusanyu-c
Copy link
Member

I think this is the design of script setup
1.

<template>
  <start-conversation></start-conversation>
  <start-conversation/>
  <startConversation/>
  <StartConversation/>
</template>

<script setup>
import StartConversation from './StartConversation.vue';
const startConversation = () => {
};
</script>
return (_ctx, _cache) => {
  return (_openBlock(), _createElementBlock(_Fragment, null, [
    _createVNode(startConversation),
    _createVNode(startConversation),
    _createVNode(startConversation),
    _createVNode(StartConversation)
  ], 64 /* STABLE_FRAGMENT */))
}
}
<template>
  <start-conversation></start-conversation>
  <start-conversation/>
  <startConversation/>
  <StartConversation/>
</template>

<script setup>
// import StartConversation from './StartConversation.vue';
const startConversation = () => {
};
</script>
return (_ctx, _cache) => {
  const _component_StartConversation = _resolveComponent("StartConversation")

  return (_openBlock(), _createElementBlock(_Fragment, null, [
    _createVNode(startConversation),
    _createVNode(startConversation),
    _createVNode(startConversation),
    _createVNode(_component_StartConversation)
  ], 64 /* STABLE_FRAGMENT */))
}
}
<template>
  <start-conversation></start-conversation>
  <start-conversation/>
  <startConversation/>
  <StartConversation/>
</template>

<script setup>
import StartConversation from './StartConversation.vue';
//const startConversation = () => {
//};
</script>
return (_ctx, _cache) => {
  return (_openBlock(), _createElementBlock(_Fragment, null, [
    _createVNode(StartConversation),
    _createVNode(StartConversation),
    _createVNode(StartConversation),
    _createVNode(StartConversation)
  ], 64 /* STABLE_FRAGMENT */))
}
}

By comparison, it can be seen that for 1 and 2, vue will convert

  <start-conversation></start-conversation>
  <start-conversation/>
  <startConversation/>

into lowerCamelCase.
So for case 1, I think it is necessary to strictly follow the imported component variable names when writing templates。

@baiwusanyu-c
Copy link
Member

The reason why the console prints 'Unexpected call the func' is because when the function parameter passed to createVNode is a function, the parameter will be processed as a functional component.

@posva posva added the has workaround A workaround has been found to avoid the problem label Sep 28, 2023
@posva
Copy link
Member

posva commented Sep 28, 2023

Using PascalCase in your component is a workaround

@posva posva added the 🍰 p2-nice-to-have Priority 2: this is not breaking anything but nice to have it addressed. label Sep 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🍰 p2-nice-to-have Priority 2: this is not breaking anything but nice to have it addressed. has workaround A workaround has been found to avoid the problem
Projects
None yet
Development

No branches or pull requests

3 participants