Display FontAwesome icon in Vue 3 with JavaScript array - html

I am trying to display FontAwesomeicon
<font-awesome-icon icon="fa-solid fa-shop" />
with JavaScript array to be dynamic but it's not working it displays as text
<div class="aboutme-card" v-for="(item,index) in servicesArr" :key="index">
<div class="service-card-icon">{{item.icon}}</div> <!--but its display as text not as icon svg-->
<div class="service-card-title">{{item.title}}</div>
<p class="service-card-desc">{{item.description}}</p>
</div>
<script>
export default {
data() {
return {
servicesArr: [
{
icon: `<font-awesome-icon icon="fa-solid fa-shop" />`,
title: "E-commerce",
}
]
}
}
}
</script>

Isn't something like this conceivable in your case?
<template>
<div class="aboutme-card" v-for="item in servicesArr" :key="item.icon">
<div class="service-card-icon">
<font-awesome-icon :icon="item.icon" />
</div>
</div>
</template>
<script>
export default {
data() {
return {
servicesArr: [
{
icon: "fa-solid fa-shop",
title: "E-commerce",
}
]
}
}
}
</script>
Even if v-html exists, it's usually not the way to go.
Especially in such a simple use-case where dynamic props are totally fine.
Overall, I still recommend that solution for overall ease of use + flexibility.

Related

How can I use v-html to pass a text with props and images?

I'm trying to pass different texts to a component list. Each text has a different title and also different content, but the same style. To do this I'm using another component that takes a v-html. I need to pass an image inside this v-html and also several props. However, the image does not appear and the props do not work. How can I solve this? I don't want to change my "message" component because I'm using it in other areas of my website and it's working fine.
App.Vue:
<template>
<div id="app" class="raleway">
<link href='https://fonts.googleapis.com/css?family=Raleway' rel='stylesheet'>
<section class="container grid">
<div
v-for="metadata in this.metadatas"
:key="metadata.id"
class="steps-wrapper text"
>
<Team :metadata="metadata"/>
</div>
</section>
</div>
</template>
<script>
import Team from "./components/Team.vue";
export default {
name: "App",
components: {
Team,
},
data() {
return {
metadatas: [
{
id: 1,
name: "Title1",
country: "Brazil"
},
{
id: 2,
name: "Title2",
country: "England"
},
],
};
},
};
</script>
Component (Team):
<template>
<div id="app" class="raleway">
<section>
<div class="steps-wrapper text">
<Step/>
<div class="image-cropper">
<img src="../assets/me.jpg" alt="" class="profile-pic">
</div>
<Message v-html="content" />
</div>
</section>
</div>
</template>
<script>
import Step from "./CreationView";
import Message from "./Message";
export default {
name: "App",
components: {
Step,
Message
},
props: {
metadata: Object,
},
data() {
return {
content:
"<h2>{{metadata.name}}</h2>\
<h2><img src='../assets/discord.svg' alt=''>Head</h2>\
<p id='country'> {{metadata.country}} </p>\
};
},
};
</script>
Component (Message):
<template>
<div class="container">
<section>
</section>
</div>
</template>
<script>
export default {
name: 'Message',
}
</script>

how to conditionally style links in Nuxt/Vue

I'm building a Nuxt app and am having trouble with conditional styling. What I'm trying to do is apply a different background color to the active link depending on what page it is. I know I can use .nuxt-link-exact-active to style the active link, but I'm stuck on how to make that different on each page.
I have the links in a component that gets rendered on each page. I've tried using .nuxt-link-exact-active at the page level, but it doesn't get picked up.
Here's what I've got so far, which does change the styling depending on the page, but it does it for all the links, and I only want it on the active link. Please let me know if I can clarify anything. Thanks!
<template>
<nav class="flex-container flex-column mt-1">
<NuxtLink to="/about" class="link" :class="classObject">about</NuxtLink>
<div class="mt-1 flex-container">
<NuxtLink to="/projects" class="link" :class="classObject"
>projects</NuxtLink
>
</div>
<div class="mt-1 flex-container">
<NuxtLink to="/contact" class="link" :class="classObject"
>contact</NuxtLink
>
</div>
</nav>
</template>
<script>
export default {
// apply current route name as a class to the matching div
computed: {
classObject() {
return {
about: this.$route.name === 'about',
projects: this.$route.name === 'projects',
contact: this.$route.name === 'contact',
}
},
},
}
</script>
<style lang="scss" scoped>
.about {
background-color: $near-white;
}
.projects {
background-color: $blue;
}
.contact {
background-color: $yellow;
}
</style>
illustration of what I'm trying to do
Instead of changing .nuxt-link-exact-active at the page level, change it in the layout.
So for example, in layouts/default.vue:
<style>
.nuxt-link-exact-active {
background: red;
}
</style>
I came up with a solution— not sure if it's the best way, but it works. Each link is now preceded by a div that only gets rendered on the corresponding page, otherwise a link is rendered.
<template>
<nav class="flex-container flex-column mt-1">
<div v-if="currentPageName === 'about'" class="box about">
<h2>about</h2>
</div>
<div v-else>
<NuxtLink to="/about" class="link">about</NuxtLink>
</div>
<div v-if="currentPageName === 'projects'" class="box projects">
<h2>projects</h2>
</div>
<div v-else>
<NuxtLink to="/projects" class="link">projects</NuxtLink>
</div>
<div v-if="currentPageName === 'contact'" class="box contact">
<h2>contact</h2>
</div>
<div v-else>
<NuxtLink to="/contact" class="link">contact</NuxtLink>
</div>
</nav>
</template>
<script>
export default {
computed: {
currentPageName() {
return this.$route.name
},
},
}
</script>
<style lang="scss" scoped>
.box {
width: 150px;
height: 150px;
}
.about {
background-color: $near-white;
}
.projects {
background-color: $blue;
}
.contact {
background-color: $yellow;
}
</style>
I think the easiest way to check if the path is active or not is $nuxt.$route.path.
<template>
<ul>
<li>
<nuxt-link :to="links[0].path" :class="{'bg-black text-white': links[0].path == path }">{{ links[0].name }}</nuxt-link>
<nuxt-link :to="links[1].path" :class="{secondStyle: links[1].path == path }">{{ links[1].name }}</nuxt-link>
</li>
</ul>
</template>
<script>
export default {
name: "Header",
data() {
return {
path: null,
links: [
{path: "/link1", name: "Link 1"},
{path: "/link2", name: "Link 2"}
],
};
},
mounted() {
this.path = $nuxt.$route.path;
},
};
</script>

How can I give transition effect for this code?

import React from "react";
import "./About.css";
import About_Main from "../components/About_Main";
import About_Data1 from "../components/About_Data1";
import About_Data2 from "../components/About_Data2";
class About extends React.Component {
state = {
main: {
display:"block",
opacity:1
},
data: {
display:"none",
opacity:0
}
};
changeSelect = id => {
if (id === "select1") {
this.setState({
main: {
display:"block",
opacity:1
},
data: {
display:"none",
opacity:0
}});
} else if (id === "select2") {
this.setState({
main: {
display:"none",
opacity:0
},
data: {
display:"block",
opacity:1
}});
}
};
clickHandler = event => {
event.preventDefault();
this.changeSelect(event.target.id);
};
render() {
return (
<div>
<section className="selects">
<div
id="select1"
className="select"
onClick={this.clickHandler}
></div>
<div
id="select2"
className="select"
onClick={this.clickHandler}
></div>
</section>
<section className="about">
<div
className="about_div"
style={{ display: this.state.main.display, opacity: this.state.main.opacity }}
>
<About_Main></About_Main>
</div>
<div
className="about_data"
style={{ display: this.state.data.display, opacity:this.state.data.opacity }}
>
<About_Data1></About_Data1>
<About_Data2></About_Data2>
</div>
</section>
</div>
);
}
}
export default About;
By clicking 2 different buttons, I want to show only one out of two.
Also, I like to give a transition effect so I used opacity. But it is not working!
Is this the only way to set style property using javascript in react?
Can't I use querySelector or something else?
I feel like javascript is much easier than react 😭😭

Tried to apply css to a component conditionally using prop but its not working

.storyMobile{
color:green;
}
.storyWeb{
color:red;
}
<div class="storyMobile">
hii
</div>
<div class="storyWeb">
hii
</div>
//main view
<div>
<story :story="stories[0]"/>
</div>
//here it prints stories in red colour but I want it to be displayed in green colour - how can I do this?
This is my component where I have 2 divs with 2 different classes one will be active for mobile and one will be active for web.
<div class="storyMobile">
//code
</div>
<div class="storyWeb">
//code
</div>
//this is my main view where I am importing this component
<div class="body-frame">
<Header></Header>
<section class="content-section-bar" v-if="stories && stories.length">
<div>
<story :story="stories[0]"/>
</div>
</section>
</div>
By default the story component is in web so "storyweb" class is getting applied to it but I want the "storyweb" class to get applied on it.
How should I do it in vue.js I tried using the props but didn't get the desired output.
Is it what you want?
your component:
<div :class="className"></div>
script:
export default {
props: {
className: {
default: 'storyWeb'
}
}
}
usage:
<story :story="stories[0]"/>
<story :story="stories[0]" class-name="storyMobile"/>
Vue.component('story',{
template: `<div :class="className">test</div>`,
props: {
className: {
type: String,
default: 'storyWeb'
},
story: {
type: Object,
required: true
}
}
})
var app = new Vue({
el: '#app',
data () {
return {
stories: [
{content: 'sotry1 content'},
{content: 'story2 content'}
]
}
}
})
.storyMobile{
color:green;
}
.storyWeb{
color:red;
}
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
<story :story="stories[0]" class-name="storyMobile"></story>
<story :story="stories[1]"></story>
</div>

Vue 2 raw HTML bind to textarea

I'm creating an online text editor. I need to be able to get the users text from the textarea's tag, manipulate this text and bind it back to the textarea, but with HTML in it.
Example:
<textarea v-model="someText"></textarea>
Where someText is set to:
someText: '<b>bold</b>.. not bold'
and should display like:
bold.. not bold
instead of: <b>bold</b>.. not bold
I have a feeling this isn't possible with the textarea tag, but what would be a way to do this?
Typically you would use v-html, but you are correct, inside <textarea> the value will be raw, not processed (will not be bold).
To achieve what you want, maybe you could leverage the contenteditable property to create a <html-textarea>, as below.
Vue.component('html-textarea',{
template:'<div contenteditable="true" #input="updateHTML"></div>',
props:['value'],
mounted: function () {
this.$el.innerHTML = this.value;
},
methods: {
updateHTML: function(e) {
this.$emit('input', e.target.innerHTML);
}
}
});
new Vue({
el: '#app',
data: {
message: 'H<b>ELLO</b> <i>editable</i> Vue.js!'
}
});
div[contenteditable] { border: 1px solid lightblue; }
<script src="https://unpkg.com/vue"></script>
<div id="app">
<html-textarea v-model="message"></html-textarea>
<hr>
<div>
Raw message:
<pre>{{ message }}</pre>
</div>
</div>
I'd have done it this way.
<template>
<div id="app">
<form name="yourform">
<textarea v-model="someText"></textarea>
</form>
</div>
</template>
<script>
export default {
name: 'app',
data () {
return {
someText: 'bold'
}
}
}
</script>
<style scopped>
textarea
{
font-weight:bold;
}
</style>