same component with different background-color - css

I've created a component and use it multiple times on one of my vue pages.
Now I wanna change the background-color for each use of this component.
This is my component:
<template>
<div class="project-card" :style="{backgroundColor: color}">
<h2>{{ title }}</h2>
<p>{{ description }}</p>
</div>
</template>
<script>
export default {
name: 'ProjectCard',
props: {
title: String,
description: String
},
data: function() {
return {
color: "#000"
}
}
}
</script>
and this is my vue page, where I use the component:
<template>
<div class="projects">
<ProjectCard
title="Projekt 01"
description="Lorem Ipsum"
/>
<ProjectCard
title="Projekt 02"
description="Lorem Ipsum"
/>
</template>
<script>
import ProjectCard from '#/components/ProjectCard.vue'
export default {
name: 'projects',
components: {
ProjectCard
}
}
</script>
Is it now possible to change the color data of the project-card component on my projects page, like I changed the text props?
Thanks for your help!

Pass color also as a prop:
<ProjectCard
title="Projekt 02"
description="Lorem Ipsum"
color= "#000F"
/>
<ProjectCard
title="Projekt 02"
description="Lorem Ipsum"
color= "#00FF00"
/>
and in script:
<script>
export default {
name: 'ProjectCard',
props: {
title: String,
description: String,
color:String
},
data: function() {
return {
color: "#000"
}
}
}
</script>

Related

Vue.3 does not render Vuetify components when using at tag attribute in transition-group

I want to animate some cards using gsap for the following components in Vue.js 3.
<script setup lang="ts">
import gsap from 'gsap'
import { useTranslate } from '#/#core/composable/useTranslate'
import TimeLineItem from './TimeLineItem.vue'
interface ITimeLine {
icon: string
title: string
description: string
color: string
}
const timeLines = ref<ITimeLine[]>([
{
title: 'PadvishInstall',
description: 'timeline-welcome',
icon: 'material-symbols:looks-one-outline',
color: 'warning',
},
{
title: 'InsertingToken',
description: 'timeline-step1',
icon: 'ic:outline-looks-two',
color: 'error',
},
{
title: 'ContactInfo',
description: 'timeline-step2',
icon: 'ph:number-square-three-bold',
color: 'info',
},
])
const { translate } = useTranslate()
/**
* Functions
*/
const beforeEnter = (el: Element) => {
const he = el as HTMLElement
he.style.opacity = '0'
he.style.transform = 'translateX(100px)'
}
const enter = (el: Element, done: () => void) => {
const he = el as HTMLElement
gsap.to(el, {
opacity: 1,
x: 0,
duration: 0.8,
onComplete: done,
delay: Number((el as HTMLElement).dataset.index) * 0.5,
})
}
</script>
<template>
<VCard class="text-center" variant="text" title="card title">
<VCardText>
<transition-group
align="start"
justify="center"
truncate-line="both"
:density="$vuetify.display.smAndDown ? 'compact' : 'default'"
appears
#before-enter="beforeEnter"
#enter="enter"
tag="v-timeline"
>
<TimeLineItem
v-for="(item, index) in timeLines"
:key="index"
:data-index="index"
:title="translate(item.title)"
:description="translate(item.description)"
:icon="item.icon"
:color="item.color"
/>
</transition-group>
</VCardText>
</VCard>
</template>
TimeLineItem component :
<script setup lang="ts">
interface Props {
icon: string
title: string
description: string
color: string
}
const props = defineProps<Props>()
</script>
<template>
<VTimelineItem size="x-small" fill-dot>
<template #icon>
<div class="v-timeline-avatar-wrapper rounded-circle">
<VAvatar size="small">
<VIcon size="100" :icon="icon" :color="color" />
</VAvatar>
</div>
</template>
<VCard>
<VCardText>
<!-- 👉 Header -->
<div class="d-flex justify-space-between">
<h6 class="text-base font-weight-semibold mb-1 me-3">
{{ title }}
</h6>
</div>
<!-- 👉 Content -->
<p class="mb-1">
{{ description }}
</p>
</VCardText>
</VCard>
</VTimelineItem>
</template>
<style lang="scss" scoped>
.v-timeline-avatar-wrapper {
background-color: rgb(var(--v-theme-background));
}
</style>
For animating each element of v-timeline, I used transition-group and set the value of tag to v-timeline. But, when using transition-group, the Vue does not recognize the 'v-timeline' is a vuetify component and must render a component!.
This is a limitation of transition-group or can be considered as a bug in Vue.3?

How to use <i18n-t> in Web component?

I'm creating a Vue web component using i18n
And I wanna put a span tag with color in
here is my code demo.
I wanna know how to import
<!-- custom-element.ce.vue -->
<script setup>
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
const locale = ref('en')
defineProps({
locale: String,
})
</script>
<template>
<div classs="custom-ele-wrap">
<i18n-t keypath="title" tag="span">
<template #text>
<span :class="['locale-text', locale']"> {{ localeText }} </span>
</template>
</i18n-t>
</div>
</template>
<style scoped>
.locale-text.en {
color: blue;
}
.local-text.zh-TW {
color: red;
}
</style>
// <!-- i18n json -->
{
"en": {
"title": "{text} language",
},
"zh-TW": {
"title": "這是{text}語言",
}
}
but it shows
enter image description here

Children Component HTML not visible in VueJS

I have create Home Component which is imported into App.vue
App.vue
<template>
<img alt="Vue logo" src="./assets/logo.png" />
<home></home>
</template>
<script>
import home from "./components/home.vue";
export default {
name: "App",
components: {
home
},
};
</script>
And header component is imported into Home.vue
Home.vue
<template>
<header></header>
</template>
<script>
import header from "./header.vue";
export default {
name: "home",
components: {
header: header,
},
};
</script>
Header.vue
<template>
<div class="new-component">
<h1>A New Component</h1>
<p>This is a text inside the NewComponent.</p>
</div>
</template>
<script>
export default {
name: 'header',
}
</script>
When I check in browser I don't see HTML of header.vue
Use multi word names. Your component is conflicting with HTML's default header tag.
VueHeader.vue
<template>
<div class="new-component">
<h1>A New Component</h1>
<p>This is a text inside the NewComponent.</p>
</div>
</template>
<script>
export default {
name: "vue-header",
};
</script>
Home.vue
<template>
<vue-header></vue-header>
</template>
<script>
import VueHeader from "./VueHeader.vue";
export default {
name: "home",
components: {
VueHeader,
},
};
</script>
You can find more information about this and other minor issues in here Vue style guide

How to change component css with props with Nuxt Js Vue js

I'm new to Nuxt and Vue, thanks for being indulgent ;).
I have a "Subtitle" component that I use in another "Main" component (names are for the example).
How can I change the css of the "subtitle" component from the "Main" component ?
Here "Subtitle" component :
<template>
<div>
<h1 :class="data">{{ title }}</h1>
</div>
</template>
<script>
export default {
name: 'subtitle',
props: {
title: String,
}
}
</script>
And here my "Main" component :
<template>
<div class="container">
<Subtitle :title="title""></Subtitle>
</div>
</template>
I searched with the props etc.... But now I've been on it for a while and I'm blocking.
Thanks for your help!
You can do it using the combination of props and computed
Subtitle Component
<template>
<div>
<h1 :style="getStyle">{{ title }}</h1>
</div>
</template>
<script>
export default {
name: 'subtitle',
props: {
stylings: Object,
},
computed: {
getStyle() {
return this.stylings;
}
}
}
</script>
Main Component
<template>
<div class="container">
<Subtitle :stylings="customStyle"></Subtitle>
</div>
</template>
export default {
name: 'subtitle',
data() {
return {
customStyle: {
'font-weight': 'Bold',
}
}
}

How to pass parameter of a function with v-for in Vue?

I am trying to pass a parameter to a function by looping through an the array items with v-for.
<template>
<v-app>
<v-app-bar app>
<v-app-bar-nav-icon #click="drawer = !drawer"></v-app-bar-nav-icon>
<v-spacer></v-spacer>
<h1 ref="y"></h1>
</v-app-bar>
<v-content>
<router-view />
<v-navigation-drawer v-model="drawer" class="x">
<v-list-item
v-for="item in items"
:key="item.unidade"
:to="item.link"
:#click="change(item.method)"
>{{item.unidade}}</v-list-item>
</v-navigation-drawer>
</v-content>
</v-app>
</template>
<script>
export default {
name: "App",
data: () => ({
items: [
{ unidade: "IPE", link: "/ipe", method: "IPE" },
{ unidade: "DCSI", link: "/dcsi", method: "DCSI" },
{ unidade: "RT", link: "/rt", method: "RT" }
],
drawer: false
}),
methods: {
change(val) {
console.log(val);
this.$refs.y.innerText = val;
}
}
};
</script>
<style lang="stylus" scoped>
.x {
position: absolute;
}
</style>
I want the parameter in items arrray to be passed to change(val) method giving each v-list-item a distinct event listener.
Then I want h1 with the ref="y" to change it's text based on the v-list-item I click. But so far I am getting the browser error of "Error in render: "TypeError: Cannot set property 'innerText' of undefined""
Instead of setting the innerText of the <h1> you could instead bind the innerText to a reactive variable. You could create a variable in data that could store the selected method and then bind that to the innerText using {{}} syntax. Doing it this way would be more inline with Vue best practices. Let me show you what I mean.
<template>
<v-app>
<v-app-bar app>
<v-app-bar-nav-icon #click="drawer = !drawer"></v-app-bar-nav-icon>
<v-spacer></v-spacer>
<h1 ref="y">{{ selectedMethod }}</h1>
</v-app-bar>
<v-content>
<router-view />
<v-navigation-drawer v-model="drawer" class="x">
<v-list-item
v-for="item in items"
:key="item.unidade"
:to="item.link"
:#click="change(item.method)"
>{{item.unidade}}</v-list-item>
</v-navigation-drawer>
</v-content>
</v-app>
</template>
<script>
export default {
name: "App",
data: () => ({
items: [
{ unidade: "IPE", link: "/ipe", method: "IPE" },
{ unidade: "DCSI", link: "/dcsi", method: "DCSI" },
{ unidade: "RT", link: "/rt", method: "RT" }
],
selectedMethod: '', // Initially blank
drawer: false
}),
methods: {
change(val) {
this.selectedMethod = val; // Update the value of selectedMethod
}
}
};
</script>
<style lang="stylus" scoped>
.x {
position: absolute;
}
</style>
Hope this helps!

Resources