I have an App.vue with the property "clicked" that I'm trying to pass to child components.
App.vue
<template>
<NavBar :clicked="clicked"/>
<BackDrop :clicked="clicked"/>
<SideDrawer :clicked="clicked" />
<router-view></router-view>
</template>
<script>
import { ref } from "vue";
import NavBar from "./components/Navbar/NavBar.vue";
import BackDrop from "./components/Backdrop/BackDrop.vue";
import SideDrawer from "./components/Sidedrawer/SideDrawer.vue";
export default {
name: "App",
components: { NavBar, BackDrop, SideDrawer },
setup() {
const clicked = ref(false);
return { clicked };
},
};
</script>
export default App;
so the child components can be rendered conditionally like:
SideDrawer.vue
<template v-if="clicked">
<div ></div>
</template>
<script setup>
</script>
Did I pass the "clicked" ref properly in the "App.vue"?
If I did, how do you access them in the child component? I've already googled and looked at a bunch of StackOverflow posts but the majority of them seem to use, "defineProps()", like this code:
const props = defineProps({
msg: String,
user: Object,
});
// Destructuring props
let { name, lastname } = props.user;
</script>
but I'm not using Typescript so this won't work for me.
What is the "non-typescript" way of passing props? Do you need to use Typescript to pass props?
EDIT:
Even when I implement Typescript and use this code:
SideDraw.vue
<template v-if="clicked">
<div >
<h1>{{ props.clicked }}</h1>
</div>
</template>
<script setup>
const props = defineProps({
clicked: boolean,
});
</script>
I get the errors:
'defineProps' is not defined.eslintno-undef
'boolean' is not defined.eslintno-undef
...
I gathered from this Github thread to set global variables so I did this, but it still doesn't work.
babel.config.js
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
],
globals: {
defineProps,
defineEmits,
defineExpose,
withDefaults
}
}
}
CodePudding user response:
In JavaScript you have two common ways of defining props, either with just array of prop names like so:
const props = defineProps([ 'clicked', 'someOtherProp' ]);
Or much more preferred(due to saving between hours and days of troubleshooting) is to define each prop with object as so:
const props = defineProps({
clicked: { type: Boolean, default: false, required: true },
});
Here is the relevant section of docs: https://vuejs.org/guide/components/props.html#prop-validation
CodePudding user response:
No, you do not need TypeScript when defining props. TypeScript is a superset of JavaScript so any TypeScript is also valid JavaScript.
When using <script setup>
, you use defineProps to define which props a component can accept. You do not need to declare or import it anywhere as it is a compiler macro. If ESlint is complaining, then it is not configured properly. Add the following to your eslint configuration file.
module.exports = {
env: {
'vue/setup-compiler-macros': true
}
}
In each of your child components you need to accept "clicked" as a property.
<script setup>
const props = defineProps(['clicked'])
</script>
or (using runtime types - this is not Typescript as pointed out by @Estus);
<script setup>
const props = defineProps({
clicked: Boolean
})
</script>
In your App.vue, you need to pass a value to the prop as follows;
<script setup>
import { ref } from "vue";
const clicked = ref(false);
</script>
<template>
<NavBar :clicked="clicked"/>
<BackDrop :clicked="clicked"/>
<SideDrawer :clicked="clicked" />
<router-view></router-view>
</template>
If you are not going to use <script setup>
, then you can define which props to accept as follows;
export default {
name: "NavBar",
props: ['clicked']
};
or (using runtime types - this is not Typescript as pointed out by @Estus);
export default {
name: "NavBar",
props: {
clicked: Boolean
}
};