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
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?
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
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
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',
}
}
}
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!