vuejs / docs

📄 Documentation for Vue 3
https://vuejs.org
Other
2.82k stars 4.14k forks source link

[Tutorial-12] ESLint error "'props' is assigned a value but never used" #1845

Open Theiaz opened 1 year ago

Theiaz commented 1 year ago

Implementing the tutorial code for chapter 12 of the child component ChildComp.vue

<script setup>
// "props' is assigned a value but never used"
const props = defineProps({
  msg: String,
});
</script>

<template>
  <h2>{{ msg }}</h2>
  <!-- This would work -->
  <!-- <h2>{{ props.msg  }}</h2> -->
</template>

forces linting error 'props' is assigned a value but never used. I think this should be fixed, especially in a tutorial. If it should be fixed I can open a PR.

Example-Repository with workaround: https://github.com/Theiaz/bug-eslint-error-props-not-used

NataliaTepluhina commented 1 year ago

@Theiaz it seems rather like a problem with the linter than with the tutorial 🤔 How did you plan to fix it?

Theiaz commented 1 year ago

Yea was not sure if this is really a problem of the linter. Using <h2>{{ props.msg }}</h2> would fix the problem for this particular code. `

eslint-plugin-vue docs says, that this error should not happen since version >9.0.0 of vue-eslint-parser. My example repository is using 9.0.3. So i think that eslint should be aware of, that props.-prefix is not needed for props. However it does not?

NataliaTepluhina commented 1 year ago

@Theiaz I believe it's worthy opening an issue on eslint-plugin-vue. This error shouldn't happen indeed since 9.0.0

LinusBorg commented 1 year ago

I don't think it's a problem with the linter. The linter is right, props is not being used, the instance proxy property is being used instead.

And for that, we don't need that variable being present:

<script setup>
defineProps({
  msg: String,
});
</script>

<template>
  <h2>{{ msg }}</h2>
  <!-- The following would require to actually have a variable called props -->
  <!-- <h2>{{ props.msg  }}</h2> -->
</template>
Theiaz commented 1 year ago

I don't think it's a problem with the linter. The linter is right, props is not being used, the instance proxy property is being used instead.

And for that, we don't need that variable being present:

<script setup>
defineProps({
  msg: String,
});
</script>

<template>
  <h2>{{ msg }}</h2>
  <!-- The following would require to actually have a variable called props -->
  <!-- <h2>{{ props.msg  }}</h2> -->
</template>

So I will try to open a PR for fixing the docs.

skirtles-code commented 1 year ago

It's not immediately clear to me what the best way to fix this would be.

If this were real code, I would just remove the const props = part, as it's redundant. But for explanatory purposes it is useful to show how the return value of defineProps makes them available in the <script setup> section.

tony19 commented 1 year ago

@skirtles-code Maybe we can show both use cases.

For example:

A child component can accept input from the parent via props. First, it needs to declare the props it accepts, as seen below. Note defineProps() is a compile-time macro and doesn't need to be imported. Once declared, the msg prop can be used in the child component's template.

<!-- ChildComp.vue -->
<script setup>
defineProps({
  msg: String
})
</script>

<template>
  <h2>{{ msg || 'No props passed yet' }}</h2>
</template>

The props can also be accessed in JavaScript via the returned object of defineProps():

<!-- ChildComp.vue -->
<script setup>
const props = defineProps({
  msg: String
})

const logMessage = () => console.log(props.msg)
</script>

<template>
  <h2>{{ props.msg || 'No props passed yet' }}</h2>
  <button @click="logMessage">Log message</button>
</template>