React -> Vue Comparison

import CoreConcept from './CoreConcept.jsx';
import { CORE_CONCEPTS } from '../data.js';

export default function CoreConcepts() {
return (
<section id="core-concepts">
<h2>Core Concepts</h2>
<ul>
{CORE_CONCEPTS.map((conceptItem) => (
<CoreConcept key={conceptItem.title} {...conceptItem} />
))}
</ul>
</section>
);
}
import CoreConcept from './CoreConcept.jsx';
import { CORE_CONCEPTS } from '../data.js';

export default function CoreConcepts() {
return (
<section id="core-concepts">
<h2>Core Concepts</h2>
<ul>
{CORE_CONCEPTS.map((conceptItem) => (
<CoreConcept key={conceptItem.title} {...conceptItem} />
))}
</ul>
</section>
);
}
<template>
<section id="core-concepts">
<h2>Core Concepts</h2>
<ul>
<CoreConcept
v-for="concept in CORE_CONCEPTS"
:key="concept.title"
v-bind="concept"
/>
</ul>
</section>
</template>

<script setup>
import CoreConcept from './CoreConcept.vue'
import { CORE_CONCEPTS } from '../data.js'
</script>
<template>
<section id="core-concepts">
<h2>Core Concepts</h2>
<ul>
<CoreConcept
v-for="concept in CORE_CONCEPTS"
:key="concept.title"
v-bind="concept"
/>
</ul>
</section>
</template>

<script setup>
import CoreConcept from './CoreConcept.vue'
import { CORE_CONCEPTS } from '../data.js'
</script>
29 Replies
Rägnar O'ock
Rägnar O'ock4mo ago
what does data.js look like ?
CDL
CDLOP4mo ago
for the CoreConcepts object it's
export const CORE_CONCEPTS = [
{
image: componentsImg,
title: 'Components',
description:
'The core UI building block - compose the user interface by combining multiple components.'
},
{
image: jsxImg,
title: 'JSX',
description:
'Return (potentially dynamic) HTML(ish) code to define the actual markup that will be rendered.'
},
export const CORE_CONCEPTS = [
{
image: componentsImg,
title: 'Components',
description:
'The core UI building block - compose the user interface by combining multiple components.'
},
{
image: jsxImg,
title: 'JSX',
description:
'Return (potentially dynamic) HTML(ish) code to define the actual markup that will be rendered.'
},
Rägnar O'ock
Rägnar O'ock4mo ago
hum, you've found yourself in one of the very few instances where v-bind: can be usefull...
CDL
CDLOP4mo ago
hahaha I was only aware of :id :class to be honest, I didn't think v-bind was used outside of that
Rägnar O'ock
Rägnar O'ock4mo ago
tho, for readability I would advise you to do something like :
<CoreConcept
v-for="{image, title, description} in CORE_CONCEPTS"
:key="title"
:image
:title
:description
/>
<CoreConcept
v-for="{image, title, description} in CORE_CONCEPTS"
:key="title"
:image
:title
:description
/>
that way it's both easier to see what is in CORE_CONCEPTS and you don't risk having weird error when you add something else in your data.js or rename something (and you should avoid using id= in components unless you need some outside code to access it, it will cause problems if you get to reuse your component)
CDL
CDLOP4mo ago
ah sure, that makes sense, similar visual to
export default function CoreConcept({ title, image, description }) {
return (
<li>
<img src={image} alt={title} />
<h3>{title}</h3>
<p>{description}</p>
</li>
);
}
export default function CoreConcept({ title, image, description }) {
return (
<li>
<img src={image} alt={title} />
<h3>{title}</h3>
<p>{description}</p>
</li>
);
}
Rägnar O'ock
Rägnar O'ock4mo ago
yeah well... yes and no yes in the sense that both use destructuring no in the sens that one is the component's usageand the other is the component's definition
CDL
CDLOP4mo ago
yeah meant the destructuring I'm a wee bit confused on this part.. how is variantImage working with variant.image?
<script setup>
import { ref } from 'vue';
import socksGreenImage from './assets/images/socks_green.jpeg';
import socksBlueImage from './assets/images/socks_blue.jpeg';

const product = ref('Socks');
const image = ref(socksGreenImage);
const inStock = true;

const details = ref(['50% cotton', '30% wool', '20% polyester']);

const variants = ref([
{ id: 2234, color: 'green', image: socksGreenImage },
{ id: 2235, color: 'blue', image: socksBlueImage }
]);

const cart = ref(0);

const addToCart = () => {
cart.value += 1;
};

const updateImage = (variantImage) => {
image.value = variantImage;
};
</script>

<template>
<div class="nav-bar"></div>
<div class="cart">Cart({{ cart }})</div>
<div class="product-display">
<div class="product-container">
<div class="product-image">
<img v-bind:src="image" />
</div>
<div class="product-info">
<h1>{{ product }}</h1>
<p v-if="inStock">In Stock</p>
<p v-else>Out of Stock</p>
<ul>
<li v-for="detail in details">{{ detail }}</li>
</ul>
<div v-for="variant in variants" :key="variant.id" @mouseover="updateImage(variant.image)">
{{ variant.color }}
</div>
<button @click="addToCart" class="button">Add to Cart</button>
</div>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue';
import socksGreenImage from './assets/images/socks_green.jpeg';
import socksBlueImage from './assets/images/socks_blue.jpeg';

const product = ref('Socks');
const image = ref(socksGreenImage);
const inStock = true;

const details = ref(['50% cotton', '30% wool', '20% polyester']);

const variants = ref([
{ id: 2234, color: 'green', image: socksGreenImage },
{ id: 2235, color: 'blue', image: socksBlueImage }
]);

const cart = ref(0);

const addToCart = () => {
cart.value += 1;
};

const updateImage = (variantImage) => {
image.value = variantImage;
};
</script>

<template>
<div class="nav-bar"></div>
<div class="cart">Cart({{ cart }})</div>
<div class="product-display">
<div class="product-container">
<div class="product-image">
<img v-bind:src="image" />
</div>
<div class="product-info">
<h1>{{ product }}</h1>
<p v-if="inStock">In Stock</p>
<p v-else>Out of Stock</p>
<ul>
<li v-for="detail in details">{{ detail }}</li>
</ul>
<div v-for="variant in variants" :key="variant.id" @mouseover="updateImage(variant.image)">
{{ variant.color }}
</div>
<button @click="addToCart" class="button">Add to Cart</button>
</div>
</div>
</div>
</template>
ah.. because you set image to the value of variantImage, ignore me. and then you use it here
@mouseover="updateImage(variant.image)
@mouseover="updateImage(variant.image)
because it's using the parameter
const updateImage = (variantImage) => {
const updateImage = (variantImage) => {
Rägnar O'ock
Rägnar O'ock4mo ago
yeah, it's just a function call no magic happening here
CDL
CDLOP4mo ago
ya how odd, first time I've encountered something forcing me to use ' ' and not " " (naturally find " " easier)
<img :class="{ 'out-of-stock-img': !inStock }" v-bind:src="image" />
<img :class="{ 'out-of-stock-img': !inStock }" v-bind:src="image" />
Rägnar O'ock
Rägnar O'ock4mo ago
it's a personal taste, but I like using simple quotes '' in JS/TS and double quotes "" with HTML for this exact reason
Rägnar O'ock
Rägnar O'ock4mo ago
'cause the whole code is encoded in it
CDL
CDLOP4mo ago
lmao I couldn't figure out how to turn add vue to codepen
Rägnar O'ock
Rägnar O'ock4mo ago
just... use the provided template...
Rägnar O'ock
Rägnar O'ock4mo ago
avoid using disabled on buttons, it's bad for a11y (it's as if you had display: none on it) use aria-disabled="true" instead. other than that it's nice could use a bit of // #region in the script to group up the related stuff, but overall it's good (you might also wantto replace that v-on:click by @click
CDL
CDLOP4mo ago
Forgot about the aria-disabled! I'm stumped on this part, and google sucked at helping..
const onSale = ref(true)
const onSale = ref(true)
whilst that's true, I need a message to appear showing "brand + product is on sale" which I think is something such as....
const saleMessage = computed(() => {
return onSale.value + ' ' + product.value + ' ' + "is on sale"
})
const saleMessage = computed(() => {
return onSale.value + ' ' + product.value + ' ' + "is on sale"
})
with
<p v-if="onSale">{{ saleMessage }}</p>
<p v-if="onSale">{{ saleMessage }}</p>
However... how do I get it to check whether onSale is true or false lol
Rägnar O'ock
Rägnar O'ock4mo ago
what do you mean ?
CDL
CDLOP4mo ago
oh hold on I think I'm just being dumb
Rägnar O'ock
Rägnar O'ock4mo ago
might be that
CDL
CDLOP4mo ago
my computed property isn't checking the value of onSale, but my v-if is, I guess That's enough of that for 1 night, that was very refreshing though!
CDL
CDLOP4mo ago
Am I being dumb or is this question harder than it seems? https://vuejs.org/tutorial/#step-7
Vue.js
Vue.js - The Progressive JavaScript Framework
Rägnar O'ock
Rägnar O'ock4mo ago
what do you mean by that ? it's just asking you to implement the list updating methods
CDL
CDLOP4mo ago
Perhaps I need to brush up on my js 😂 seems it’s just a push method to add and a filter method to remove.
Rägnar O'ock
Rägnar O'ock4mo ago
yup
CDL
CDLOP4mo ago
It’s the only part of the tutorial I get stuck on when I go back through it, weird
Rägnar O'ock
Rägnar O'ock4mo ago
that's because "it's just JS bro" (that's not really true tho)
CDL
CDLOP4mo ago
I think it’s a combo of me forgetting .value is for changing the state values, and the ({ id… }) threw me off as I don’t see it often

Did you find this page helpful?