Set default selection option with props - vue.js

I'm having some trouble setting a default value I have tried the following:
add selected in an option
<option value="1" selected>option A</option>
This did not work, below is an example of my code
<template>
<div>
<div>
<div class="sm:col-span-3">
<label
for="outside_state"
class="block text-sm font-medium text-gray-700 dark:text-white"
>
Option List
</label>
<div class="mt-1">
<select
v-model="selector.options"
id="outside_state"
name="outside_state"
class="shadow-sm focus:ring-indigo-500 focus:border-indigo-500 block w-full sm:text-sm border-gray-300 rounded-md dark:text-gray-900"
>
<option value="1">Value A</option>
<option value="1">Value B</option>
</select>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: ['selector'],
};
</script>
How could I set Value A as a default value?
Now when the page loads nothing is selected.

You can set default value for props if the props is not being passed it will automatically get that value.
props:{
selector: {
type: Object,
default: () => ({ options: 1 })
}
}
You can read more about props here:
https://v2.vuejs.org/v2/guide/components-props.html#Prop-Types

Related

Pass component as prop in object param

I have the following Card Grid set up in Vue3:
<template>
<div class="max-w-5xl mx-auto">
<div class="ml-20 pr-72">
<h2 class="text-4xl pb-8">{{ title }}</h2>
<p class="font-normal text-base pb-20">{{ description }}</p>
</div>
<div class="grid grid-cols-2 gap-5">
<div
v-for="card in cards"
:key="card.title"
class="rounded-xl py-6 px-5 bg-cover bg-center flex flex-col justify-between items-start h-60"
:style="{ backgroundImage: `url(${card.imageUrl})` }"
>
<div
class="rounded-full p-4 bg-gradient-to-r from-prospire-blue to-prospire-light-blue"
>
{{ card.icon }}
</div>
<p class="text-white font-light text-2xl">{{ card.title }}</p>
</div>
</div>
</div>
</template>
<script setup lang="ts">
const props = defineProps<{
title: string;
description: string;
cards: any[];
}>();
</script>
<style scoped></style>
Which i call using:
<CardGrid
:title="$t('aboutUs.cardGrid.title')"
:description="$t('aboutUs.cardGrid.description')"
:cards="[
{
title: $t('aboutUs.cardGrid.cards[0].title'),
imageUrl:
'https://images.pexels.com/photos/5595573/pexels-photo-5595573.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1',
icon: <BeakerIcon />,
},
]"
/>
This however gives me a BeakerIcon' refers to a value, but is being used as a type here. Did you mean 'typeof BeakerIcon'? error.. Is it possible to pass a 3rd party component (icon in this case), to a component in a way?
One option is to pass card.icon as a string, such as 'BeakerIcon' and do
<div class="rounded-full p-4 bg-gradient-to-r from-prospire-blue to-prospire-light-blue">
<component :is="card.icon" />
</div>
...granted the icon you pass has been registered as a component.
It also work without registering the component globally.
Here is an example on sfc.vuejs.org passing the imported components in the props.

Vue is not rendering on right tags component

The way i am defining my props;
<template>
<div>
<vinput id="login_name" label="Phone number"></vinput>
<div class="flex flex-col">
<label for="email-phone">School slug</label>
<input type="text" id="email-phone" class="border py-2 rounded">
</div>
</div>
</template>
<script>
import vinput from '../../components/Input.vue'
export default {
components:{
vinput
}
}
</script>
The way i am passing the props
<vinput id="login_name" label="Phone number"></vinput>
Please why is the browser rendering it this way:
<div class="mt-4">
<div class="flex flex-col" id="login_name" label="Phone number">
<label></label>
<input type="tex" class="border py-2 rounded">
</div>
<div class="flex flex-col"><label for="email-phone">School slug</label><input type="text"
id="email-phone" class="border py-2 rounded"></div></div>
I was expecting interpolation in the label and input not in the div
====Edited====
vinput component
<template>
<div class="flex flex-col">
<label :for="id">{{ label }}</label>
<input :type="type ? type : 'tex'"
:class="classes ? classes :''" class="border py-2 rounded"/>
</div>
</template>
<script>
export default {
data(){
return {
props:['label', 'id','type', 'classes']
}
}
}
</script>
Move your props:['label', 'id','type', 'classes'] away from data.
Those are totally different things.
<script>
export default {
props: ['label', 'id','type', 'classes'],
data(){
return {};
},
};
</script>

Bind data with router-link in the vue

I have declared a data variable inside my component. There is a select box that dynamically changes this data value. what I want to use this data value inside my router-link. but somehow it is not working.
Here is my code for the same:
<template>
<div class="row bg-blue content-padding pdt-70 relative d-flex">
<div class="col-md-8">
<div class="row mgb-60">
<form>
<div class="col-8 form-group mgb-30">
<label for="work-profile" class="color-white">Work Profile*</label>
<select id="work-profile" v-model="page" name="work-profile" class="form-control">
<option value="self-employed">Self Employed</option>
<option value="salaried">Salaried</option>
</select>
</div>
<div class="col-12 form-group">
<router-link :to=["/"+page]>
<button type="submit" class="btn form-button button-blue d-flex-inline justify-content-center align-items-center color-white bg-blue">Get Started</button>
</router-link>
</div>
</form>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: "LandingPage",
data: function()
{
return{
page:'salaried'
}
},
components: {
},
};
</script>
Replace <router-link :to=["/"+page]> to <router-link :to="'/'+page"> you do not need [] with binding to

Vue Conditional Classes from Prop Variable

So, currently, I have a set of radio buttons on my home.vue page and binding to a child component like so -
<div class="radio-toolbar prev-selector">
<input type="radio" id="one" value="Default" v-model="preview" />
<label for="one">Default</label>
<input type="radio" id="two" value="Padded" v-model="preview" />
<label for="two">Padded</label>
<input type="radio" id="three" value="Full" v-model="preview" />
<label for="three">Full</label>
<span>Picked: {{ preview }}</span>
</div>
<div class="media-wrapper">
<CardStyle
v-bind:card="this.preview"
/>
</div>
Which is then passing that "preview" data to the CardStyle Prop.
The prop is receiving it as ['card'] and I can use the data within my component.
However, am wondering how I can use the potential value of "this.preview" (which could be 'default', 'padded' or 'full') as a dynamic class to my child component without having to convert them to a true/false outcome and use -
:class="{ default: isDefault, padded: isPadded, full: isFull }"
(I have classes called .default, .padded and .full ready to use if it is as simple as passing the data in somehow.)
As long as this.preview has a value of the class name you want to use, just use :class="this.preview".
I built a couple of sample components that demonstrate how to solve your problem.
Parent.vue
<template>
<div class="parent">
<h5>Select Card Style</h5>
<div class="row">
<div class="col-md-6">
<div class="form-check">
<input class="form-check-input" type="radio" id="one" value="default" v-model="preview" />
<label class="form-check-label" for="one">Default</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" id="two" value="padded" v-model="preview" />
<label class="form-check-label" for="two">Padded</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" id="three" value="full" v-model="preview" />
<label class="form-check-label" for="three">Full</label>
</div>
</div>
</div>
<card-style :preview="preview" />
</div>
</template>
<script>
import CardStyle from './CardStyle.vue'
export default {
components: {
CardStyle
},
data() {
return {
preview: 'default'
}
}
}
</script>
CardStyle.vue
<template>
<div class="card-style">
<hr>
<div class="row">
<div class="col-md-6">
<span :class="preview">{{ preview }} Card Style</span>
</div>
</div>
</div>
</template>
<script>
export default {
props: {
preview: {
type: String,
required: true
}
},
}
</script>
<style scoped>
.default {
background-color: burlywood;
}
.padded {
background-color:lightskyblue
}
.full {
background-color:lightcoral
}
</style>
You can build a computed variable for your field class in your component. This will allow you to select or define what classes to use based on your conditions or case.
computed: {
myclasses() {
return [
'class1',
'class2',
[this.condition ? 'class3' : 'class4'],
{ class5: this.othercondition },
];
},
},
Then, just use it your template:
<div :class="myclasses"></div>

Is there a way to get the data from multiple selects as array?

I'm currently stuck on a task on VueJS. Basically I'm trying to create an array from multiple select inside a form to get all the data as an array or Object to process it further. I just searched but got no results or an idea on how to solve my issue.
Parent Component
<template>
<div id="product" class="mt-12">
<div class="flex flex-wrap mb-4">
<div class="w-1/2 pr-12">
<img src="https://placehold.it/800" alt="">
</div>
<div class="w-1/2">
<div class="flex justify-between content-center h-12 mb-4">
<div class="text-gray-700 py-2">
<h2 v-if="product.brand" class="leading-none font-bold text-sm">{{ product.brand }}</h2>
<h1 class="text-xl leading-snug">{{ product.name }}</h1>
</div>
<div class="text-gray-700 py-2">
<p class="text-xl font-bold leading-none">{{ product.price }}</p>
<p class="text-xs text-right leading-none">Inkl. 19% MwSt.</p>
</div>
</div>
<div class="divider bg-gray-400 mt-4 mb-4" />
<div id="variations">
<form action="">
<ProductVariation v-for="(variations, type) in product.variations" :type="type" :variations="variations" :key="type" v-model="form.variation"/>
<div class="flex w-full">
<button class="w-full leading-none bg-blue-500 hover:bg-blue-600 text-white py-2 rounded" type="submit">Add to cart</button>
</div>
</form>
</div>
</div>
</div>
</div>
</template>
<script>
import ProductVariation from '#/components/products/ProductVariation'
export default {
data () {
return {
product: null,
form: {
variation: null
}
}
},
components: {
ProductVariation
},
async asyncData({ params, app }) {
let response = await app.$axios.$get(`products/${params.slug}`)
return {
product: response.data
}
}
}
</script>
ProductVariation Component
<template>
<div class="flex mb-4">
<div class="w-full">
<label class="block text-gray-700 w-full text-sm font-bold">{{ type }}</label>
<select class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight" :name="type">
<option value="0">Please select</option>
<option v-for="variation in variations" :key="variation.id" :value="variation.id">{{ variation.name }} <span>( +{{ variation.price }} )</span></option>
</select>
</div>
</div>
</template>
<script>
export default {
props: {
type: {
required: true,
type: String
},
variations: {
required: true,
type: Array
}
},
}
</script>