In vuejs, is there a way to set the same content for multiple slots without copy pasting?
So this:
<base-layout>
<template slot="option">
<span :class="'flag-icon-' props.option.toLowerCase()" />{{ countriesByCode[props.option] }}
</template>
<template slot="singleLabel">
<span :class="'flag-icon-' props.option.toLowerCase()" />{{ countriesByCode[props.option] }}
</template>
</base-layout>
Could be written that way:
<base-layout>
<template slot="['option', 'singleLabel']">
<span :class="'flag-icon-' props.option.toLowerCase()" />{{ countriesByCode[props.option] }}
</template>
</base-layout>
Thanks a lot.
You could try using v-for for that.
<base-layout>
<template :slot="slotName" v-for="slotName in ['option', 'singleLabel']">
<span :class="'flag-icon-' props.option.toLowerCase()" />{{ countriesByCode[props.option] }}
</template>
</base-layout>
See working example.
Related
I can not loop through the $slots object in Vue 3 to pass all slots from parent to child, the $slots object seems empty in the child component.
How can I loop through the $slots object to pass all parent slots to the child component?
I get this error when I run the code:
TypeError: Cannot read properties of null (reading 'key')
Here is a sandbox about my problem and you can uncomment line 5 to see the complete result:
https://codesandbox.io/s/blazing-bush-g7c9h?file=/src/pages/Index.vue
GitHub sample:
https://github.com/firibz/vue3slots
parent:
<system-input filled v-model="text" label="input">
<template v-slot:before>
<q-icon name="mail" />
</template>
</system-input>
child:
<div class="row justify-center">
<q-input v-model="componentValue" v-bind="$attrs" style="width: 250px">
<template v-for="(_, slot) of $slots" v-slot:[slot]="scope">
<slot :name="slot" v-bind="scope"/>
</template>
</q-input>
<q-separator class="full-width" color="secondary" />
<div class="bg-negative full-width q-pa-lg">slots: {{ $slots }}</div>
<div class="bg-warning full-width q-pa-lg">slots: {{ $slots.before }}</div>
</div>
You have to use Object.keys($slots) in order to use slots on v-for.
<q-input v-model="componentValue" v-bind="$attrs" style="width: 250px">
<template v-for="(slot, index) of Object.keys($slots)" :key="index" v-slot:[slot]>
<slot :name="slot"></slot>
</template>
</q-input>
Quasar File Picker component to change the text color of selected file name in <q-file>.
the text file selected is test.odt, how can I change it's text color for example Red?
<q-file
standout
class="registration-field text-red"
bg-color="blue-2"
v-model="registrationNumber"
color="red"
>
<template v-slot:prepend>
<q-icon name="o_insert_photo" size="24px" color="blue" />
</template>
<template v-slot:append>
<div class="attachment text-grey-14">File</div>
</template>
</q-file>
I've tried using style props color="red" and it's not working.
anyone know how?
You can Use the file slot and add text-red class and it works.
<q-file
standout
class="registration-field text-red"
bg-color="blue-2"
v-model="registrationNumber"
color="red"
>
<template v-slot:prepend>
<q-icon name="photo" size="24px" color="blue"/>
</template>
<template v-slot:append>
<div class="attachment text-grey-14">File</div>
</template>
<template v-slot:file="{ index, file }">
<div class="ellipsis text-red relative-position">
{{ file.name }}
</div>
<q-tooltip>
{{ file.name }}
</q-tooltip>
</template>
</q-file>
Codepen- https://codepen.io/Pratik__007/pen/wvWzOoV
I have several datatable with server-side pagination, search fields and filterable fields
However, I would like to be able to generate a component and use the props to avoid modifying the same thing three times
Is there a way to loop around template with datatable from vuetify (with v-slot dynamic) ?
for example :
<template v-slot:header.id="{ header }">
<div class="pointer border-right pa-2">
<span class="title" #click.prevent="sortBy('id')">
ID
<v-icon class="ml-2">{{icon.id}}</v-icon>
</span>
<v-text-field v-model="searcher.ticket_id.value" type="text"
label="Rechercher..."></v-text-field>
</div>
</template>
<template v-slot:header.name="{ header }">
<div class="pointer border-right pa-2">
<span class="title" #click.prevent="sortBy('name')">
Nom du ticket
<v-icon class="ml-2">{{icon.name}}</v-icon>
</span>
<v-text-field v-model="searcher.ticket_name.value" type="text"
label="Rechercher..."></v-text-field>
</div>
</template>
Become (not functional) :
<template v-for="(item, i) in headers" v-slot:item.text="{ header }">
<div class="pointer border-right pa-2">
<span class="title" #click.prevent="sortBy(item.name)">
{{item.name}}
<v-icon class="ml-2">{{icon[item.name]}}</v-icon>
</span>
<v-text-field v-model="item.searcher" type="text"
label="Rechercher..."></v-text-field>
</div>
</template>
If i add the key , i have '<template>' cannot be keyed. Place the key on real elements instead
and if i remove this i have Elements in iteration expect to have 'v-bind:key' directives
However I came across several sources that demonstrate the opposite
https://v2.vuejs.org/v2/guide/list.html#v-for-on-a-lt-template-gt
Fix: require-v-for-key shouldn't be raised on slots
vue-language-server : Elements in iteration expect to have 'v-bind:key' directives
Thank you
Edit 20/12 :
https://github.com/vuejs/eslint-plugin-vue/issues/1006
How can I make the v-slot attribute dynamically with the vuetify data table ?
Here is my code :
<template v-for="(head, i) in headers" v-slot:header[header.value]="{header}">
<div :key="i" class="pointer border-right pa-2">
<span class="title" #click.prevent="sortBy('id')">
{{head}} <br> {{header}}
<v-icon class="ml-2">{{icon.id}}</v-icon>
</span>
<v-text-field v-model="searcher.ticket_id.value" type="text"
label="Rechercher..."></v-text-field>
</div>
</template>
It cannot be mounted on the table column
I need to use v-slot:header.id="{header}" for the mounted on the id column but I have to make id dynamic according to my loop
how to do ?
Thank you
I find it
I added head: 'header.id' in my list so i can use <template v-for="(head, i) in headers" v-slot:[headers[i].head]="{header}">
I had to do
<template v-for="(col, i) in filters" v-slot:[`header.${i}`]="{ header }">
in my case
filters: { 'name': [], 'calories': [] },
I want to use this dropdown menue for my webproject based on vue.js.
Everything with vue.js worked fine so far.
Unfortunately in the following example the template part does (i guess) not get rendered. There is no error message in the console and i don't know what i need to do to use <template> properly in my webproject.
<div>
<label class="typo__label">Simple select / dropdown</label>
<multiselect v-model="value" :options="options" :multiple="true" :close-on-select="false" :clear-on-select="false" :preserve-search="true" placeholder="Pick some" label="name" track-by="name" :preselect-first="true">
<template slot="selection" slot-scope="{ values, search, isOpen }"><span class="multiselect__single" v-if="values.length && !isOpen">{{ values.length }} options selected</span></template>
</multiselect>
<pre class="language-json"><code>{{ value }}</code></pre>
</div>
Any hint is highly appreciated!
In the link, he says that
<template slot="tag" slot-scope="props"><Your code></template>
so update your code to
<template slot="selection" slot-scope="{ values, search, isOpen }">
<div>
<label class="typo__label">Simple select / dropdown</label>
<multiselect v-model="value" :options="options" :multiple="true" :close-on-select="false" :clear-on-select="false" :preserve-search="true" placeholder="Pick some" label="name" track-by="name" :preselect-first="true">
<span class="multiselect__single" v-if="values.length && !isOpen">{{ values.length }} options selected</span>
</multiselect>
<pre class="language-json"><code>{{ value }}</code></pre>
</div>
</template>
because Vue read from <template> tag so don't use it inside codes
Since the template tag is within the mulitselect, I'd suggest you check the documentation for vue-multiselect and check out their slot scopes. This should help
https://vue-multiselect.js.org/#sub-getting-started
I am rewriting a page that is currently using an Angular 1 framework to polymer 1 (or 2). I don't know what the equivalent of ng-repeat is in polymer. This is what I have right now in Angular 1.
<div class="consultant" ng-repeat="consultant in consultants | limitTo:i">
<p>{{consultant.displayName}}</p>
<p ng-if="consultant.phoneNumber != undefined" >☎ {{consultant.phoneNumber}}</p>
<br ng-if="consultant.phoneNumber == undefined" />
<p class="email" ng-if="consultant.email != undefined" ><span class="icon-envelope"></span> {{consultant.email}}</p>
<br ng-if="consultant.email == undefined" />
</div>
What you are looking for is dom-repeat and probably dom-if
In your case this could look something like this:
<template is="dom-repeat" items="[[consultants]]" as="consultant">
<div class="consultant">
<p>[[consultant.displayname]]</p>
<template is="dom-if" if="[[consultant.phoneNumber]]">
<p>☎ [[consultant.phoneNumber]]</p>
</template>
<template is="dom-if" if="[[!consultant.phoneNumber]]"><br></template>
<template is="dom-if" if="[[consultant.email]]">
<p class="email">
<span class="icon-envelope"></span>
[[consultant.email]]
</p>
</template>
<template is="dom-if" if="[[!consultant.email]]"><br></template>
</div>
</template>