I'm using Vue3 on a Rails app and struggle with passing the props using composition api:
Rails part:
<% props = {
id: @estimate.document_no_f
}.to_json
%>
<div id="invoice_app" data="<%= props %>"></div>
main.js
const element = document.getElementById("invoice_app")
const data = JSON.parse(element?.getAttribute('data') || '')
console.log(data); <-- {id: 'A-00014'}
if (element != null) {
const app = createApp(
DragDropZone, <-- Component
{
props: ['id']
},
{
id: data.id
}
).mount('#invoice_app');
}
DragDropZone component:
props: {
id: String,
},
setup(props) {
console.log(props); <- undefined
How would I pass the props to the component in the createApp function properly?
CodePudding user response:
You have passed DragDropZone
as the first argument to createApp
method, which is wrong. The first argument is props
& second is your prop
data. Components need to be registered separately, like I've shown below. You can refer to component registration page to learn more about component registrations in vue3
Coming to your issue of not being able to receive the props in child component, you need to first pass the props to the child component in order to get them in the composition
api.
ex. <drap-drop-zone :id="this.id"></drap-drop-zone>
Only then you will be able to get this in the child component like this:
setup(props){ console.log(props); }
So correct the following line from this:
<div id="invoice_app" data="<%= props %>"></div>
To this:
<div id="invoice_app">
<drap-drop-zone :id="this.id"></drap-drop-zone>
</div>
Sample implementation
const data = {
id: 'A-00014'
};
const app = Vue.createApp({ props: ["id"],}, data);
app.component('drap-drop-zone', {
template: `
<div>
Output from drap-drop-zone: {{ this.id }}
</div>
`,
props: {
id: String
},
setup(props){
console.log(props);
}
});
/**
// or require it from a file
import drapDrop from '/../.../DragDropZone.vue';
app.component('drap-drop-zone', drapDrop);
**/
app.mount("#app");
<script src="https://unpkg.com/vue@next"></script>
<div id="app">
<drap-drop-zone :id="this.id"></drap-drop-zone>
</div>