How to use conditionals without attaching it to an element? - vue.js

In vue, we have got directives v-if which needs to be attached to element.
Is there a way to use conditionals without attaching them to anything like the mustachejs way?
I am looping through an array of words and it is adding div's in every word which is annoying
Here is my template
<div v-for="(str, index) in reference" :key="index">
<div v-if="patternIncluded(str)">
<input type="text" v-model="remarks[index]">
</div>
<div v-else>
{{str}}
</div>
</div>
I would be nice if i could do it like this:|
{{if true}}
something goes here
{{else}}
other thing goes here
{{\if}}

Here is your code but using the < template > tag
<template v-if="patternIncluded(str)">
<input type="text" v-model="remarks[index]">
</template>
<template v-else>
{{str}}
</template>
Here is a example from the official Vue documentation:
<template v-if="loginType === 'username'">
<label>Username</label>
<input placeholder="Enter your username">
</template>
<template v-else>
<label>Email</label>
<input placeholder="Enter your email address">
</template>
More informations: https://v2.vuejs.org/v2/guide/conditional.html#Controlling-Reusable-Elements-with-key
You can also use a Method and use normal Javascript into the < script > at the bottom of your file
Hope this helped, cheers

you could use the 'template' like so:
<template v-if=patternIncluded(str)>
//code
</template
<template v-else>
//code
</template>
UPDATE so like this
<div-for="(str, index) in reference" :key="index">
<template v-if="patternIncluded(str)">
<input type="text" v-model="remarks[index]">
</template>
<template v-else>
{{str}}
</template>
</div>

Related

use v-slot to pass property to slots component - Vue 3

I´m struggeling with passing properties into a slots component.
Here some code to explain my problem:
App template:
<template>
<ModalContainer v-model="visibleModal">
<create-dir-modal />
</ModalContainer>
</template>
ModalContainer:
<template>
<div class="modal-container" v-if="modelValue" #click.self="close">
<slot :close="close" />
</div>
</template>
(close is a defined method here)
CreateDirModal:
<template v-slot="slot">
<div class="create-dir-modal-container">
<i class="button" #click="slot.close">close</i>
<div>
<i>folder</i>
<input placeholder="Name" v-model="name" />
<span></span>
<i class="button">done</i>
</div>
</div>
</template>
I am trying to execute the close method from the ModalContainer in the CreateDirModal.
Here is my problem: slot is not defined in CreateDirModal template.
Am I just using it wrong or is there a way to fix my problem?

Is this the right approach to create a component?

I made a view to show some contact information for the user:
<template>
<div v-for="user in users" class="user">
<div class="userInformation">
<img :src="user.photo" />
<div class="userName">
<h3>{{ user.age }}</h3>
<p>{{ user.gender }}</p>
</div>
</div>
<div class="button-wrapper">
<a href="#">
<button #click="$router.push(`/user/${user.id}`)">User Profile</button>
</a>
</div>
</div>
</template>
<style>
</style>
users is an array that holds all users which I fetch from the backend.
I want to create a component so that I can re-use the user card in other classes and don´t have to include the markup. I tried it the following way but I'm stuck at the button to redirect the user and the img because I don´t know how to use named slots there.
<template>
<div class="user">
<div class="userInformation">
<img />
<div class="userName">
<h3>{{ age }}</h3>
<p>{{ gender }}</p>
</div>
</div>
<div class="button-wrapper">
<a href="#">
<button>User Profile</button>
</a>
</div>
</div>
</template>
<script>
export default {
name: "UserCard",
props: [
"age",
"gender"
]
};
</script>
Another problem is that I have to re-create the fetch method for my users in other classes to access the user information. Would there be a better way of doing this?
// fetch user data from backend and create users array
...
<div v-for="user in users" :key="user.name">
<UserCard
:age="`${user.age}`"
:gender="`${user.gender}`"
/>
</div>
Is this the right approach to create a reusable component?
You're headed in the right direction for your component. If you wanted a named slot for the button you could use something like this.
Child Component
<template>
...
<slot name="button">
<!-- default/fallback content can be provided, if the parent does
not provide slot content the button-wrapper div will appear -->
<div class="button-wrapper">
<a href="#">
<button>Default Button</button>
</a>
</div>
</slot>
</div>
</template>
Parent
<div v-for="user in users" :key="user.name">
<UserCard
:age="user.age"
:gender="user.gender">
<template v-slot:button>
<div>some custom button here {{ user.phone }}</div>
</template>
</UserCard>
</div>
Also compilation scope (Vuejs v2 guide) is an important thing to keep in mind with slots - "Everything in the parent template is compiled in parent scope; everything in the child template is compiled in the child scope."
In terms of fetching your users, that's a separate issue. Look into something like Vuex or other ways of managing shared state if you find yourself constantly having to fetch users in various components

Slots ignored for CoreUI's CInput

I guess, that I'm misunderstanding something. According to this documentation, I came up with the following prototype code to replace the old classic syntax. But it doesn't work at all.
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text">
<CIcon name="cil-lock-locked" />
</span>
</div>
<input type="password"
class="form-control"
placeholder="Passwort"
:isValid="false"
invalidFeedback="hdhdh"
v-model="enteredPassword" />
</div>
<!-- ---------------------------------------------- -->
<CInput value="lll">
<prepend>ppp</prepend>
<prepend-content>
dddd
</prepend-content>
<label>
dkjdjdj
</label>
</CInput>
The bottom code just displays a complete empty text box. But why?
Slots are referenced with v-slot or # prefix. Try
<CInput value="lll">
<template #prepend>ppp</template>
<template #prepend-content>
dddd
</template>
<template #label>
dkjdjdj
</template>
</CInput>
You have used unknown custom element (and html label) instead of slot.

Vue data binding for b-input in b-table using bootstrap-vue

I'm trying to bind data to b-input inside a b-table however, changes to the input value will not propagate to the items of the table.
Here is my code so far:
<template>
<div :class="`col-${fields.length}`">
<h6 class="text text-center">{{header}}</h6>
<b-table
:items="items"
:fields="fields"
>
<template v-for="field in fields"
:slot="field.key" slot-scope="data">
<b-form-input class="border-0 no-shadow p-1" type="number" v-model="data.value"
></b-form-input>
</template>
</b-table>
</div>
</template>
<script>
export default {
props: [ "header", "fields", "items"]
}
</script>
Basically all I want, is to change the values of items everytime I change the corresponding value of a b-input.
But itemswill never change...
What am I doing wrong here?
The solution is to use the items directly instead of using the data.value.
<template v-for="field in fields"
:slot="field.key" slot-scope="data">
<b-form-input class="border-0 no-shadow p-1" type="number" v-model="data.item[field.key]"></b-form-input>
</template>

How to use custom template for label in selected option in v-select?

I have used <template slot="option" slot-scope="option"> for custom label in v-select. Here, everything is working fine. The custom label is working fine when the options are opened as shown in the screenshot here: http://prntscr.com/kluu7p but the custom label is not working for selected option or when the select is closed: http://prntscr.com/kluudy .
Here is the snippet I have used to use custom template in v-select:
<v-select #input="updateShippingCharge"
v-model="selected"
:options="options">
<template slot="option" slot-scope="option">
<span :class="['flag-icon', `flag icon-${option.value.toLowerCase()}`]"></span>
{{ option.label }}
</template>
</v-select>
Add another template with attribute slot="selected-option".
<template slot="selected-option" slot-scope="option"></template>
The final code should look like this:
<v-select #input="updateShippingCharge"
v-model="selected"
:options="options">
<template slot="option" slot-scope="option">
<span :class="['flag-icon', `flag icon-${option.value.toLowerCase()}`]"></span>
{{ option.label }}
</template>
<template slot="selected-option" slot-scope="option">
<span :class="['flag-icon', `flag icon-${option.value.toLowerCase()}`]"></span>
{{ option.label }}
</template>
</v-select>