1👍
You could set a property in the data object for currency and use that across all components and have a function alter it.
data() {
return {
currency: "USD",
...
}
},
methods: {
changeCurrency(newCurrency){
this.currency = newCurrency;
}
}
and in the template
<span @click=changeCurrency('Euro')> Change currency </span>
1👍
I don’t know if I got the logic of your problem but maybe you can use the vue props like this:
<FruitPrices fruit="apple" :currency="newCurrency || 'USD'"></FruitPrices>
<FruitPrices fruit="banana" :currency="newCurrency || 'GBP'"></FruitPrices>
<FruitPrices fruit="orange" :currency="newCurrency || 'USD'"></FruitPrices>
you can define the props currency
inside the component FruitPrices
. If the currency
prop is not defined then the second currency is going to be taken as default (for example "newCurrency || 'GBP'"
if newCurrency
is null then the currency GBP is taken as default).
Vue docs for props: https://v2.vuejs.org/v2/guide/components-props.html
Then in the main template component, you define the variable newCurrency
and you pass that variable to the prop currency
of the component FruitPrices
:
data: () => {
newCurrency: null
},
methods: {
setNewCurrency() {
this.newCurrency = this.someFieldOfYourForm;
}
}
- [Vuejs]-UseInfiniteScroll utility of Vueuse is fetching same items again
- [Vuejs]-Why isn't this list render working in Vue 3?
1👍
Let’s use this component to pass the currency, price and fruit to each component FruitPrices component:
<template>
<div>
<!-- USD is selected by default, once the option change, the prices will be updated -->
<select v-model="currency">
<!-- allows to select one currency at time, it shows all the currencies
that exist in the currencies array data property -->
<option
v-for="(currencyOption, index) in currencies"
:key="index"
:value="currencyOption"
>
<!-- show only the currency name as option -->
{{ currencyOption.name }}
</option>
</select>
<div v-for="(fruit, fruitIndex) in fruitsWithPrices" :key="fruitIndex">
<!-- if everything is working fine, you don't need close tags for empty
custom component, you can use '/' at the end of the first tag to self close it-->
<FruitPrices :name="fruit.name" :convertedPrice="fruit.convertedPrice" />
</div>
</div>
</template>
<script>
import FruitPrices from '../somePlace/FruitPrices'
export default {
name: "FruitPricesContainer",
components: { FruitPrices },
data: () => ({
fruits: [
{
name: 'Apple',
price: 0.2
},
{
name: 'Banana',
price: 0.3
},
{
name: 'Orange',
price: 0.25
}
],
currency: {
// Base currency, exchangeRate = 1
exchangeRate: 1,
name: 'USD'
},
// Used exchange rates only for demo purpose, not are the real and valid exchange rates
currencies: [
{
exchangeRate: 1,
name: 'USD'
},
{
exchangeRate: 1.2,
name: 'EUR'
},
{
exchangeRate: 0.7,
name: 'SGD'
},
{
exchangeRate: 700,
name: 'MXN'
},
{
exchangeRate: 3700,
name: 'COP'
}
]
}),
computed: {
// The fruitsWithPrices listen for changes in both, the fruit and
// the currency, so once you change it by selecting a different currency
// the prices will be updated automatically (nice)
fruitsWithPrices() {
return this.fruits.map((fruit) => {
return {
...fruit, // Add name and original price to the returned object
convertedPrice: fruit.price * this.currency.exchangeRate // Add the price based on the exchange rate
}
})
}
}
}
</script>
Now, let’s create the FruitPrices component:
<template>
<div>
<p>{{ name }}: {{ convertedPrice }}</p>
</div>
</template>
<script>
export default {
name: "FruitPrices",
props: {
name: {
type: String,
required: true
},
convertedPrice: {
type: Number,
required: true
}
}
}
</script>
And it’s ready! (Tbh, I didn’t test it, please let me know if you have errors or problems).