How to toggle between components in vue.js? - javascript

I developed one page called Dashboard.vue and this page contains three child components(Display,sortBooksLowtoHigh,sortBooksHightoLow). Dashboard component contains one select options also inside that it have two options "Price:High to Low and Price:Low to High ",
if i click on price:LowToHigh option then it hides the Display component and displays the sortBooksLowtoHigh component utpo this it's working fine,
Now i import one more component called sortBooksHightoLow when i click on "price:High to Low" option it should hides the DisplayComponent and displays the sortBooksHightoLow component.How to acheive this thing please help me
Dashboard.vue
<template>
<div class="main">
<div class="navbar navbar-default navbar-fixed-top">
<div class="navbar-header">
<img src="../assets/education.png" alt="notFound" class="education-image" />
</div>
<ul class="nav navbar-nav">
<li>
<p class="brand">Bookstore</p>
</li>
</ul>
<div class="input-group">
<i #click="handlesubmit();" class="fas fa-search"></i>
<div class="form-outline">
<input type="search" v-model="name" class="form-control" placeholder='search...' />
</div>
</div>
<ul class="nav navbar-nav navbar-right" id="right-bar">
<li><a> <i class="far fa-user"></i></a></li>
<p class="profile-content">profile</p>
<li><a><i class="fas fa-cart-plus"></i></a></li>
<p class="cart-content">cart</p>
</ul>
</div>
<div class="mid-body">
<h6>Books<span class="items">(128items)</span></h6>
<select class="options" #change="applyOption">
<option disabled value="">Sort by relevance</option>
<option value="HighToLow">price:High to Low</option>
<option value="LowToHigh">price:Low to High</option>
</select>
</div>
<DisplayBooks v-show="flag==='noOrder'" />
<sortBooksLowtoHigh v-show="flag==='lowToHigh'" />
<sortBooksHightoLow v-show="flag==='highToLow'" />
</div>
</template>
<script>
import service from '../service/User'
import sortBooksLowtoHigh from './sortBooksLowtoHigh.vue'
import sortBooksHightoLow from './sortBooksHightoLow.vue'
import DisplayBooks from './DisplayBooks.vue'
export default {
components: {
DisplayBooks,
sortBooksLowtoHigh,
sortBooksHightoLow
},
data() {
return {
flag: 'noOrder',
brand: 'Bookstore',
name: '',
visible:true,
books: [{
}]
}
},
methods: {
flip() {
this.flag = !this.flag;
},
applyOption(evt) {
if (evt.target.value === "HighToLow") this.flag = 'highToLow';
else this.flag = 'lowToHigh';
},
}
}
</script>
<style lang="scss" scoped>
#import "#/styles/Dashboard.scss";
</style>
sortBooksHightoLow.vue
<template>
<div class="carddisplay-section">
<div v-for="book in books" :key="book.id" class="card book">
<div class="image-section">
<div class="image-container">
<img v-bind:src="book.file" />
</div>
</div>
<div class="title-section">
{{book.name}}
</div>
<div class="author-section">
by {{book.author}}
</div>
<div class="price-section">
Rs. {{book.price}}<label class="default">(2000)</label>
<button v-if="flag" class="btn-grp" type="submit" #click="handlesubmit();Togglebtn();">close</button>
</div>
<div class="buttons">
<div class="button-groups">
<button type="button" #click="toggle(book.id);flip(book.id);" v-if="state==true" class="AddBag">Add to Bag</button>
<button v-if="state==true" class="wishlist">wishlist</button>
</div>
<div v-if="state==false" class="AddedBag">
<button class="big-btn">Added to Bag</button>
</div>
</div>
</div>
</div>
</template>
<script>
import service from '../service/User'
export default {
data() {
return {
result: 0,
authorPrefix: 'by',
pricePrefix: 'Rs.',
defaultStrikePrice: '(2000)',
buttonValue: 'close',
flag: true,
state: true,
clickedCard: '',
books: [{
id: 0,
file: 'https://images-na.ssl-images-amazon.com/images/I/41MdP5Tn0wL._SX258_BO1,204,203,200_.jpg',
name: 'High to Low',
author: 'Saioii',
price: '1500'
}, ]
}
},
methods: {
toggle(id) {
this.clickedCard = id;
// this.card.content = this.notes.filter((note) => note.id === id);
console.log(this.clickedCard);
},
flip() {
this.state = !this.state;
},
Togglebtn() {
this.flag = !this.flag;
},
handlesubmit() {
service.userDisplayBooksHightoLow().then(response => {
this.books.push(...response.data);
})
},
}
}
</script>
<style lang="scss" scoped>
#import "#/styles/DisplayBooks.scss";
</style>
sortBooksLowtoHigh.vue
<template>
<div class="carddisplay-section">
<div v-for="book in books" :key="book.id" class="card book">
<div class="image-section">
<div class="image-container">
<img v-bind:src="book.file" />
</div>
</div>
<div class="title-section">
{{book.name}}
</div>
<div class="author-section">
by {{book.author}}
</div>
<div class="price-section">
Rs. {{book.price}}<label class="default">(2000)</label>
<button v-if="flag" class="btn-grp" type="submit" #click="handlesubmit();Togglebtn();">close</button>
</div>
<div class="buttons">
<div class="button-groups">
<button type="button" #click="toggle(book.id);flip(book.id);" v-if="state==true" class="AddBag">Add to Bag</button>
<button v-if="state==true" class="wishlist">wishlist</button>
</div>
<div v-if="state==false" class="AddedBag">
<button class="big-btn">Added to Bag</button>
</div>
</div>
</div>
</div>
</template>
<script>
import service from '../service/User'
export default {
data() {
return {
result: 0,
authorPrefix: 'by',
pricePrefix: 'Rs.',
defaultStrikePrice: '(2000)',
buttonValue: 'close',
flag: true,
state: true,
clickedCard: '',
books: [{
id: 0,
file: 'https://images-na.ssl-images-amazon.com/images/I/41MdP5Tn0wL._SX258_BO1,204,203,200_.jpg',
name: 'Default Card',
author: 'Sai',
price: '..'
}, ]
}
},
methods: {
toggle(id) {
this.clickedCard = id;
// this.card.content = this.notes.filter((note) => note.id === id);
console.log(this.clickedCard);
},
flip() {
this.state = !this.state;
},
Togglebtn() {
this.flag = !this.flag;
},
handlesubmit() {
service.userDisplayBooksLowtoHigh().then(response => {
this.books.push(...response.data);
console.log(this.response);
})
},
}
}
</script>
<style lang="scss" scoped>
#import "#/styles/DisplayBooks.scss";
</style>

emmmm...
HightoLow => HighToLow.

There can be several methods, in my opinion, to achieve conditional rendering of components which I think your question asks for. Two of them which are highly useful are:
Using v-if and v-else where you must define a flag that handles the logic for component rendering. Also, wrapping them in a transition tag would a good idea to make the switch with a transition.
<transition>
<component1 v-if="flag" />
<component2 v-else />
</transition>
Dynamic Components, we use the component tag and is attribute. The component can then be switched using the name of the component.
<component is="nameofComponent" />
You can read more about dynamic components in vuejs docs.
While the dynamic component looks neat, a switch with transition can be a nice addition.

Related

How to pass array length to another component (from child to parent component) in vue.js?

I have two components Dashboard.vue(parent) and DisplayBooks.vue(child). inside child component i have one array addedBooks:[] it should be incremented when user clicks on ADD TO BAG button and decremented when user clicks on ADDED TO BAG button upto this it's working fine ,Now hat my requirement is addedBooks.length (array length)should be transferred from DisplayBooks.vue to the Dashboard.vue component.how to acheive this thing please help me
Dashboard.vue
<template>
<div class="main">
<div class="navbar navbar-default navbar-fixed-top">
<div class="navbar-header">
<img src="../assets/education.png" alt="notFound" class="education-image" />
</div>
<ul class="nav navbar-nav">
<li>
<p class="brand">Bookstore</p>
</li>
</ul>
<div class="input-group">
<i #click="handlesubmit();" class="fas fa-search"></i>
<div class="form-outline">
<input type="search" v-model="name" class="form-control" placeholder='search...' />
</div>
</div>
<ul class="nav navbar-nav navbar-right" id="right-bar">
<li><a> <i class="far fa-user"></i></a></li>
<p class="profile-content">profile</p>
<!-- here i want to display the array length -->
<li><a><i class="fas fa-cart-plus"></i></a></li>
<p class="cart-content">cart</p>
</ul>
</div>
<div class="mid-body">
<h6>Books<span class="items">(128items)</span></h6>
<select class="options" #change="applyOption">
<option disabled value="">Sort by relevance</option>
<option value="HighToLow">price:High to Low</option>
<option value="LowToHigh">price:Low to High</option>
</select>
</div>
<div v-if="flam==false">
<h2>Hello</h2>
</div>
<DisplayBooks v-show="flag==='noOrder'" />
<sortBooksLowtoHigh v-show="flag==='lowToHigh'" />
<sortBooksHightoLow v-show="flag==='highToLow'" />
</div>
</template>
<script>
import sortBooksLowtoHigh from './sortBooksLowtoHigh.vue'
import sortBooksHightoLow from './sortBooksHightoLow.vue'
import DisplayBooks from './DisplayBooks.vue'
export default {
components: {
DisplayBooks,
sortBooksLowtoHigh,
sortBooksHightoLow
},
data() {
return {
flag: 'noOrder',
brand: 'Bookstore',
name: '',
flam: true,
visible: true,
books: [{
}]
}
},
methods: {
flip() {
this.flam = !this.flam;
},
applyOption(evt) {
if (evt.target.value === "HighToLow") {
this.flag = 'highToLow';
} else this.flag = 'lowToHigh';
},
}
}
</script>
DisplayBooks.vue
<template>
<div class="carddisplay-section">
<div v-for="book in books" :key="book.id" class="card book">
<div class="image-section">
<div class="image-container">
<img v-bind:src="book.file" />
</div>
</div>
<div class="title-section">
{{book.name}}
</div>
<div class="author-section">
by {{book.author}}
</div>
<div class="price-section">
Rs. {{book.price}}<label class="default">(2000)</label>
<button v-if="flag" class="btn-grp" type="submit" #click="handlesubmit();Togglebtn();">close</button>
</div>
<div class="buttons">
<div class="button-groups" v-if="!addedBooks.includes(book.id)">
<button type="submit" #click="handleCart(book.id);toggle(book.id);addedBooks.push(book.id)" class="AddBag">Add to Bag</button>
<button class="wishlist">wishlist</button>
</div>
<div class="AddedBag" v-else>
<button class="big-btn" #click="removeFromCart(book.id);addedBooks=addedBooks.filter(id=>id!==book.id)">Added to Bag</button>
</div>
</div>
</div>
</div>
</template>
<script>
import service from '../service/User'
export default {
data() {
return {
flag: true,
state: true,
addedBooks:[], // this array length should be passed to dashboard component
clickedCard: '',
books: [{
id: 0,
file: 'https://images-na.ssl-images-amazon.com/images/I/41MdP5Tn0wL._SX258_BO1,204,203,200_.jpg',
name: 'Dont Make me think',
author: 'Sai',
price: '1500'
}, ]
}
},
methods: {
flip() {
this.state = !this.state;
},
Togglebtn() {
this.flag = !this.flag;
},
handlesubmit() {
service.userDisplayBooks().then(response => {
this.books.push(...response.data);
})
},
handleCart(bookId){
let userData={
id: bookId,
}
service.userUpdateCart(userData).then(response=>{
return response;
})
},
removeFromCart(bookId){
let userData={
id:bookId,
}
service.userRemoveFromCart(userData).then(response=>{
return response;
})
}
}
}
</script>
Watch the array change and emit its length to the parent :
DisplayBooks.vue
data() {
return {
flag: true,
state: true,
addedBooks:[], // this array length should be passed to dashboard component
clickedCard: '',
books: [{
id: 0,
file: 'https://images-na.ssl-images-amazon.com/images/I/41MdP5Tn0wL._SX258_BO1,204,203,200_.jpg',
name: 'Dont Make me think',
author: 'Sai',
price: '1500'
}, ]
}
},
watch:{
addedBooks:{
handler(val){
this.$emit('update-books-count',val.length)
},
deep:true
}
}
Dashboard
<ul class="nav navbar-nav navbar-right" id="right-bar">
<li><a> <i class="far fa-user"></i></a></li>
<p class="profile-content">profile</p>
<p>{{booksCount}}</p>
<li><a><i class="fas fa-cart-plus"></i></a></li>
<p class="cart-content">cart</p>
</ul>
...
<DisplayBooks v-show="flag==='noOrder'" #update-books-count="(n)=>booksCount=n"/>
...
data() {
return {
booksCount:0,
flag: 'noOrder',
brand: 'Bookstore',
name: '',
flam: true,
visible: true,
books: [{
}]
}
},

How to pass on the array from parent component to chid component Vue 3.0?

I have a sample Vue 3.0 project where, I have few child components with app.vue as parent component. I want to pass an array from app.vue component to list-product component which accepts an array but unable to do so. Code is as follows.
Error: On mount of list-product component, I am logging the input provided array from app.vue which turned out be a string and type check failed .
Stackbliz Link
app.vue
<template>
<Navbar title="FirstCry" />
<div class="row mt-3">
<div class="col-md-4 p-3 border bordered shadow-sm">
<Addproduct />
</div>
<div class="col-md-8">
<ListProduct products={{products}} />
</div>
</div>
<ViewProduct />
</template>
<script>
import Navbar from "./components/Navbar.vue";
import Addproduct from "./components/Addproduct.vue";
import ListProduct from "./components/list-product.vue";
import ViewProduct from "./components/View-Product.vue";
export default {
name: "App",
components: {
Navbar,
Addproduct,
ListProduct,
ViewProduct,
},
data() {
return {
products: [
{
name: "Iphone",
price: "22000",
image: "https://i.imgur.com/J9yBaqj.jpg",
}
]
}
}
};
</script>
<style>
</style>
list-products.vue
<template>
<div class="row">
<div class="col-md-4 product" >
<div class="card">
<div style="overflow: hidden;" class="card-header p-0">
<img class="card-img-top img-fluid" src='https://i.imgur.com/J9yBaqj.jpg' alt="Card image cap" style="height: 300;">
</div>
<div class="card-body">
<center><h5 class="card-title">Iphone</h5></center>
<p class="card-text text-secondary">
<!-- {{products[0].name}} -->
</p>
<center><h4>
<small>
<s class="text-secondary">
22
</s>
</small>
<span class="price">22</span>
</h4>
<a class="btn btn-warning ng-star-inserted" style="margin: 20px;">Add to Cart</a>
<a class="btn btn-primary">Buy Now</a></center>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: "ListProduct",
props: {
title: String,
products: Array
},
mounted() {
console.log(this.products);
}
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.product {
margin-top: 10px;
}
.img-fluid:hover {
transform: scale(1.2);
overflow: hidden;
}
small {
font-size: 80%;
font-weight: 400;
}
.text-secondary {
color: #6c757d !important;
}
s {
text-decoration: line-through;
}
</style>
You should bind it using v-bind: or the shorthand syntax : :
<ListProduct :products="products" />

Vue modal with a router

I am new to Vue. I am building a simple app that will list all countries and when you click on a particular country it shows you more details about the country. Idea is to open country details in a modal.
I'm stuck with displaying that modal. The modal opens, but in the background. It also opens a detail page.
CountryDetail.vue:
<script>
import axios from 'axios';
export default {
name: 'country-detail',
props: [ 'isDarkTheme' ],
data () {
return {
pending: false,
error: null,
countryInfo: null,
alpha3Code: [],
alpha3CodetoString: [],
}
},
mounted () {
this.pending = true;
axios
.get(`https://restcountries.eu/rest/v2/name/${this.$route.params.country}?fullText=true`)
.then((response) => {
(this.countryInfo = response.data)
this.alpha3CodetoString = this.alpha3Code.join(';');
})
.catch(error => (this.error = error ))
.finally( () => { this.pending = false });
},
filters: {
formatNumbers (value) {
return `${value.toLocaleString()}`
}
}
}
</script>
<template>
<modal v-model="show">
<div class="modal-mask" :class="{ darkTheme : isDarkTheme }" name="modal">
<div class="modal-wrapper">
<div class="modal-container">
<div class="modal-header">
<slot name="header">
<h1 v-if="error !== null">Sorry, an error has occurred {{error}}</h1>
<div class="loaderFlex"><div v-if="pending" class="loader"></div></div>
</slot>
</div>
<div v-for="country in countryInfo" class="countryTile modal-body" v-bind:key="country.id">
<slot name="body">
<img v-bind:src="country.flag" alt="Country Flag" class="flag">
<div class="country-details">
<h1>{{country.name}}</h1>
<div class="listDiv">
<ul>
<li><span>Population:</span> {{country.population | formatNumbers }}</li>
<li><span>Capital:</span> {{country.capital}}</li>
<li><span>Iso:</span> {{country.alpha3Code}}</li>
</ul>
<ul>
<li><span>Currencies:</span> {{country.currencies['0'].name}}</li>
<li><span>Languages:</span>
<span
v-for="(language, index) in country.languages"
v-bind:key="index"
class="languages">
{{language.name}}<span v-if="index + 1 < country.languages.length">, </span>
</span>
</li>
</ul>
</div>
</div>
</slot>
</div>
<div class="modal-footer">
<slot name="footer">
<a #click="$router.go(-1)" class="backBtn"><i class="fas fa-arrow-left" />Go Back</a>
</slot>
</div>
</div>
</div>
</div>
</modal>
</template>
Home.vue:
<script>
import axios from 'axios';
export default {
name: 'home',
props: [ 'isDarkTheme' ],
data () {
return {
pending: false,
error: null,
countryInfo: null,
search: '',
darkMode: false,
}
},
mounted () {
this.pending = true;
axios
.get('https://restcountries.eu/rest/v2/all')
.then(response => (this.countryInfo = response.data))
.catch(error => (this.error = error ))
.finally( () => { this.pending = false });
},
filters: {
formatNumbers (value) {
return `${value.toLocaleString()}`
}
},
computed: {
filteredCountries: function () {
return this.countryInfo.filter((country) => {
if (this.region === '' ) {
return country.name.toLowerCase().match(this.search.toLowerCase());
} else if (this.search !== '') {
return country.name.toLowerCase().match(this.search.toLowerCase());
} else {
return ('blbla');
}
})
}
},
}
</script>
<template>
<div class="home" :class="{ darkTheme : isDarkTheme }">
<div class="searchBar">
<div class="searchContainer">
<i class="fas fa-search searchIcon"></i>
<input
class="searchInput"
type="text"
v-model="search"
aria-label="Search for a country..."
placeholder="Search for a country..."
/>
<ul class="searchResults"></ul>
</div>
</div>
<h1 v-if="error !== null">Sorry, an error has occurred {{error}}</h1>
<div class="loaderFlex"><div v-if="pending" class="loader"></div></div>
<div v-if="countryInfo" class="tileGrid" #click="showModal = true">
<div v-for="country in filteredCountries" class="countryTile" v-bind:key="country.id">
<router-link
:to="{ name: 'country-detail', params: {country: country.name }}"
class="linkTile"
>
<img v-bind:src="country.flag" alt="Country Flag" class="flag">
<div class="text">
<h1>{{ country.name }}</h1>
</div>
</router-link>
</div>
</div>
</div>
</template>
The router-link will always redirect you to another page, because its basically <a href="..."> see here. You don't need router if you just want to show the detail on a modal, you could just add the modal component inside the Home.vue component, then bind the modal and the countryName with props, then pass them in when clicking a button.
Home.vue:
<template>
<div>
<button #click="showDetail">
Show Detail
</button>
<CountryDetail :countryName="countryName" :showModal="showModal"/>
<div>
</template>
<script>
import CountryDetail from './CountryDetail.vue'
export default {
name: 'Home',
components: { CountryDetail },
data: () => ({
countryName: '',
showModal: false,
}),
methods: {
showDetail() {
this.showModal = true;
},
},
}
</script>
And instead of making request on mounted, you could use watch to do something like watching for the showModal prop, and make request everytime it has a truthy value. Like this:
CountryDetail.vue:
<template>
<modal v-model="showModal">
<!-- modal content -->
</modal>
</template>
<script>
export default {
name: 'CountryDetail',
props: ['countryName', 'showModal'],
watch: {
'showModal': {
deep: true,
handler(val) {
if (val && this.countryName !== '') {
// Make request
}
}
}
}
}
</script>

Vue function fires multiple time

I'm using vue cli and I have function that updates text #click but it keeps running multiple times:
User.vue
<div #click="newText('Volume')">
<Chart :text=text ></Chart>
volume
</div>
<div #click="newText('Temperature')">
<Chart :text=text ></Chart>
temp
</div>
<div #click="newText('Weight')">
<Chart :text=text ></Chart>
weight
</div>
<script>
newText: function(argT) {
const text = argT;
this.text = text;
console.log('text', this.text);
</script>
},
In Chart component when I console.log it ran 9 times!
props: ['text'],
text1(){
console.log('text', this.text)
},
It seems that since my User component is displayed 3 times(intentionally due to an array of 3 users I have) and there is a box for each measurement(temp, vol and weight), that's why it's 9 times. But I'm not sure why it runs each time.
I would like it to run only once for the box I clicked.
Any help would be great, thanks!
Update (additional code)
User.vue
<template >
<div class="user">
<div v-for="(item, index) in users" :key="item.id">
<div>
<div #click.stop="myFunction(index); newData(index, item.Vol); newText('Volume')">
<v-touch v-on:doubletap="isOpen = !isOpen;" >
<transition name="modal">
<div v-if="isOpen">
<div class="overlay" #click.self="isOpen = false;">
<div class="modal">
<Chart :text=text :dat=dat ></Chart>
</div>
</div>
</div>
</v-touch>
volume </div>
<div #click.stop="myFunction(index);newData(index, item.Temp); newText('Temperature')">
<v-touch v-on:doubletap="isOpen = !isOpen;" >
<transition name="modal">
<div v-if="isOpen">
<div class="overlay" #click.self="isOpen = false;">
<div class="modal">
<Chart :text=text :dat=dat ></Chart>
</div>
</div>
</div>
</v-touch>
temp </div>
<div #click.stop="myFunction(index); newData(index, item.Weight); newText('Weight')">
<v-touch v-on:doubletap="isOpen = !isOpen;" >
<transition name="modal">
<div v-if="isOpen">
<div class="overlay" #click.self="isOpen = false;">
<div class="modal">
<Chart :text=text :dat=dat ></Chart>
</div>
</div>
</div>
</v-touch>
weight</div>
</div>
</div>
</div>
</template>
<script>
/* eslint-disable */
import Charts from './Charts'
export default {
name: 'User',
components: {
Charts,
},
methods:{
newData: function(arrIndex, event) {
const dat = event;
this.dat = dat;
},
newText: function(argT) {
const text = argT;
this.text = text;
console.log('text', this.text);
},
myFunction: function (arrIndex) {
const name = this.users[arrIndex].name;
this.name = name;
},
},
}
</script>
Charts.vue
<div class="tabs">
<a v-on:click="activetab=1" v-bind:class="[ activetab === 1 ? 'active' : '' ]">Settings</a>
<a v-on:click="activetab=2" v-bind:class="[ activetab === 2 ? 'active' : '' ]">Chart</a>
</div>
<div class="content">
<div v-if="activetab === 1" class="tabcontent">
<Settings></Settings>
</div>
<div v-if="activetab === 2" class="tabcontent">
<Chart :dat=dat :text=text ></Chart >
</div>
</template>
<script>
import Chart from './Chart'
import Settings from './Settings'
/* eslint-disable */
export default {
name: 'Charts',
props: ['activetab', 'dat','text' ],
components: {
Settings,
Chart,
},
methods: {
text1(){
console.log('text', this.text)
},
</script>
and finally I pass text to a chart:
<template>
<div id="container" ref="chart"></div>
</template>
<script>
title: {
text: this.text,
}
series: [ {
name: this.text,
data: this.dat,
}],
In my case browser-sync was the problem.

How do I change the color of only the props from another component

I want to change only the color of the string in 'subMsg'. I don't want the color to affect the 'HomeContent' too.
<template>
<div class="submit">
<HomeContent v-bind:style="{ color: color }" subMsg="* Required"/>
<div id="buttons">
<button type="button" class="btn btn-light"><router-link to="/about">Back</router-link></button>
<button type="button" class="btn btn-primary" id="submit">Submit</button>
</div>
</div>
</template>
I alocated a different string to the same subMsg in another component but in this component. I want the color to the different for only this subMsg component.
import HomeContent from "#/components/HomeContent.vue";
export default {
name: "Submit",
components: {
HomeContent
},
data() {
return {
color: "red"
}
}
}
Is it possible to change the color?
you can do something like this:
parent component:
//HTML part
<HomeContent :subMsg="{color:subMsgColor,message:'* Required'}"/>
// script part
data() {
return {
subMsgColor: "red"
}
HomeContent component:
<template>
<div class="hello">
<div class="card">
<div class="card-content">
<h1>{{ msg }}</h1>
<p :style="{color:subMsg.color}">{{ subMsg.message }}</p>
</div>
</div>
</div>
</template>
<script>
export default {
name: "hello",
data() {
return {
msg: "Data Collection"
};
},
props: {
subMsg: {
type:Object,
default:null
}
}
}
</script>

Categories