Assign all data to all slots - vue.js

Is there a better way to assign my data to all my slots, without needing to bind this on each individual slot?
So currently i'm doing:
<slot name="header" :data="this._data">
<header>
<h2>{{ header }}</h2>
<p>{{ subtitle }}</p>
</header>
</slot>
This in order to use the data I must do this:
<finance-calculator class="app" vehicle-id="1815981">
<template #header="data">{{ data.data.header }}</template>
</finance-calculator>
I tried to use the render method to assign the data however this doesn't appear to work at all:
render() {
const data = this._data;
return this.$scopedSlots['header']({
test: 'hello'
});
},
Can someone help me out here?

You just can use $data to refer to the data object of a component. Like this:
<slot name="header" :data="$data">
<header>
<h2>{{ header }}</h2>
<p>{{ subtitle }}</p>
</header>
</slot>
<finance-calculator class="app">
<template #header="{data}">{{ data.header }}</template>
</finance-calculator>

Related

How do I take the value of my v-for and step them in mounted() and data() in vue.js, and i have a problem with combobox, i'll explain below?

basically what I'm trying to do is, I get the DateTime coming from my database along with some information of a possible meeting, if people are busy, they will have the option to extend that time through a combobox that pulls a enum in my backend which has values ​​in milliseconds, description and id. As I get these values ​​coming from my enum, I can extend the meeting, but I did this validation on the frontend through a function... where I get the value of the combobox, and add it to the dateTime coming from the BE, however, I can't change the database (legacy) to add a field to save the enum, and that's why I had to make an adapted function in the frontend, and the extension method is hardcoded and doesn't have a field in the BE it replicates the same combobox for all. pointing out that I can't pull the data still coming from my v-for to mounted() or data().
Please help me. I'm using Primevue.
i tried to catch the index/code coming from the v-for by #click the dropdown by creating the function in mounted(), but without success. When trying to manipulate this data, it returns me an undefined value enter image description here
my v-for loop
`<div
class="mt-2"
v-for="(item, index) in listaAlarme"
:key="index">
<!-- {{ item.codigo }}
{{ index }} :{{ listaAlarme[index].referencia }} -->
<Card class="cardContainer">
<template #content>
<div class="formgrid grid">
<UnoFormField
id="dateTimeReference"
:cols="4"
label="Date and Time">
<UnoFormCalendar
v-model="listAlarm[index].reference"
#click="handleAlterTime(index)"
:withTime="true" />
</UnoFormField>
<UnoFormField
id="extended"
:cols="3"
label="Extended">
<Dropdown
v-model="typeActivitiesExtend"
:options="typeActivitiesExtendList"
option-label="description"
option-value="milliSeconds"
placeholder="Extended"
:class="{
'w-full': true,
}"
class="p-dropdown-uno-trigger-black"></Dropdown>
</UnoFormField>
<UnoFormField
id="contact.name"
:cols="3">
<div class="phoneIcon">
<fa-icon
icon="phone"
#click="handleCall" />
</div>
</UnoFormField>
</div>
</template>
<template #footer>
<div class="formgrid grid">
<!-- <div class="flex"> -->
<UnoFormField
id="meeting"
:cols="3">
<Button
icon="pi pi-search"
class="p-button-uno-black"
#click="handleMeeting"></Button>
</UnoFormField>
<UnoFormField
id="description"
:cols="3">
<p class="text">
{{ listAlarm[index].shortDescription }}
</p>
</UnoFormField>
<div class="iconButtons">
<fa-icon
icon="ban"
class="banIcon"
#click="excludeItem" />
<fa-icon
icon="check"
class="checkIcon"
#click="onBtnSave" />
</div>
<!-- </div> -->
</div>
</template>
</Card>
`
the UnoFormField, is a label as you can see, that me return the label name and fied col just for display de fields with a size col in template
my function to extend the hours in methods:
i'm try to catch the value of datatime in v-for
`

How to use "v-for", for array in computed object

I am creating a website to list all of my projects. I am using Vuex and Firebase to store all my data.
I want each project to have its own "todo-list".
When I create a new project, I create an array witch is my todo-list. In Firebase it looks like this: Screenshot of Firebase
Now I want to display a list of my projects. First I get my projects as a computed prop like this:
<script>
export default {
computed: {
projects () {
return this.$store.getters.loadedProjects
}
},
created () {
this.$store.dispatch('loadProjects')
},
}
</script>
I can loop through projects and display the title for each project.
My question is: how do I loop through the todo-array inside the computed prop?
<template>
<div v-for="project in projects" :key="project.id">
<p>{{ project.title }}</p>
<!-- Looping through todos (array) in an computed prop -->
<div v-for="(todo, index) in todos" :key="todo.id">
<p>{{ project.todos[index].title }} </p>
<p>{{ project.todos[index].completed }} </p>
</div>
</div>
</template>
Tried to use the computed prop inside v-for, but that does not work.
Not sure if I understand the meaning of computed properties. Could I just define projects () inside data () ? and link the getter to the data?
<div v-for="todo in {{project.todos}} :key="todo.id>
If the second loop is inside the first one, you could access it this way:
<template>
<div v-for="project in projects" :key="project.id">
<p>{{ project.title }}</p>
<!-- Looping through todos (array) in an computed prop -->
<div v-for="todo in project.todos" :key="todo.id">
<p>{{ todo.title }} </p>
<p>{{ todo.completed }} </p>
</div>
</div>
</template>
When you create a loop, in this case, project is a single element of the array, so project.todos is the list of todos of that specific project.
https://v2.vuejs.org/v2/guide/list.html#Mapping-an-Array-to-Elements-with-v-for

Output html using a Vue template tag, but without having a nested element

My over-arching question is: In Vue, how to output inner html while iterating over a collection but without having to wrap it in an additional div or span.
Specifically: I'm iterating over an array of js objects from within a Vue template. Each object has a "render" method which outputs html.
This works:
template:
`<div id="container">
<template v-for="element in elements">
<span v-html="element.render()"></span>
</template>
</div>
`,
But I would like to do something like below, because I don't want the output to be wrapped in a div or span. This code produces no error but also produces no output:
template:
`<div id="container">
<template v-for="element in elements" v-html="element.render()">
</template>
</div>
`,
In a perfect world, I would do something like this, but mustache format can't output html:
<div id="container">
<template v-for="(element, index) in elements">
{{ element.render() }}
</template>
</div>
The desired output:
<div id="container">
(output of element.render())
(output of element.render())
(output of element.render())
etc.
</div>
Thank you for any guidance,
L
Delete the <template> tag completely and use render function in <script> tag. Something like this, but this code is not tested, demonstrational only.
export default {
...
render (h) {
return h('div', this.elements.map(function (elm) {
return h(elm.render())
})
}
}

Render HTML properly for JSON text in Vue component

I am iterating through a list of props that consists of simple HTML markup
<div class="columns medium-4 large-4" v-for="keyOffer in keyOffers">
<p>{{ keyOffer.head }}</p>
<p>{{ keyOffer.sub }}</p>
</div>
and one of the props looks like this
keyOffers: [
{
id: 'offerSecond',
head: '4G network',
sub: 'Dedicated to bringing you the <span class="u_underline">best mobile service</span>
},
]
but in the output the <span> gets printed and not applied.
Any help?
Use v-html directive:
<div class="columns medium-4 large-4" v-for="keyOffer in keyOffers">
<p>{{ keyOffer.head }}</p>
<p v-html="keyOffer.sub"></p>
</div>
Ref: RawHTML

VueJS: Is It Possible to Automatically Include One Component in Another Component

I would like to automatically include the contents of one component in a named slot of another component. I.e., something like this:
Vue.component('comp-one', {
template: `
<div class="comps>
<div class="comp-two">
<slot name="compTwo"></slot>
</div>
<div class="comp-one">
<slot></slot>
</div>
</div>
`
})
Vue.component('comp-two', {
slot: 'compTwo',
template: `
<div class="sub-comp-two">
<!-- content goes here -->
<slot></slot>
</div>
`
})
The idea is that if someone uses <comp-two>Some content</comp-two>, it will automatically get added to the slot compTwo in comp-one. Is there a way to do this?
NOTE: I made up slot: 'compTwo'. Just trying to illustrate what I'd like to accomplish.