VueJS - Examples
Vue 3 - Practical Examples
Section titled “Vue 3 - Practical Examples”This section provides practical examples demonstrating common Vue 3 features like computed properties, data binding, loops, and component communication.
Example 1: Dynamic Currency Converter
Section titled “Example 1: Dynamic Currency Converter”This example uses computed properties to create a real-time currency converter. It demonstrates v-model, v-for, and dynamic calculations based on user input.
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Vue 3 Currency Converter</title> <script src="https://unpkg.com/vue@3"></script> <style> #currency-converter { padding: 20px; margin: 20px; background-color: #f0f0f0; border-radius: 8px; } label, select, input, span { font-size: 1.1em; margin-right: 10px; margin-bottom: 10px; display: inline-block; /* Better layout */ } select { min-width: 150px; } .result { margin-top: 20px; font-weight: bold; font-size: 1.2em; } </style></head><body> <div id="currency-converter"> <h1>Currency Converter</h1> <div> <label for="amount">Amount:</label> <input id="amount" type="number" v-model.number="amount" placeholder="Enter amount" /> </div> <div> <label for="from">From:</label> <select id="from" v-model="convertFrom"> <option v-for="currency in currencies" :key="currency.code" :value="currency.code"> {{ currency.name }} ({{ currency.code }}) </option> </select> </div> <div> <label for="to">To:</label> <select id="to" v-model="convertTo"> <option v-for="currency in currencies" :key="currency.code" :value="currency.code"> {{ currency.name }} ({{ currency.code }}) </option> </select> </div> <div class="result" v-if="amount > 0"> <span>{{ amount }} {{ convertFrom }} = {{ convertedAmount }} {{ convertTo }}</span> </div> <div class="result" v-else> <span>Enter an amount to see the conversion.</span> </div> </div>
<script> const { createApp, ref, computed } = Vue;
const app = createApp({ setup() { const amount = ref(1); // Default amount const convertFrom = ref('USD'); const convertTo = ref('EUR');
// In a real app, fetch these rates from an API const rates = ref({ 'USD': 1, 'EUR': 0.92, 'INR': 83.3, 'GBP': 0.79 });
const currencies = ref([ { code: 'USD', name: 'US Dollar' }, { code: 'EUR', name: 'Euro' }, { code: 'INR', name: 'Indian Rupee' }, { code: 'GBP', name: 'British Pound' } ]);
const convertedAmount = computed(() => { if (!amount.value || !rates.value[convertFrom.value] || !rates.value[convertTo.value]) { return 0; } // Convert 'from' amount to base currency (USD in this case) const amountInBase = amount.value / rates.value[convertFrom.value]; // Convert base amount to 'to' currency const finalAmount = amountInBase * rates.value[convertTo.value]; // Format to 2 decimal places return finalAmount.toFixed(2); });
return { amount, convertFrom, convertTo, currencies, convertedAmount }; } });
app.mount('#currency-converter'); </script></body></html>Explanation
Section titled “Explanation”- Uses Composition API (
setup,ref,computed). amount,convertFrom,convertToare reactive refs bound to form elements usingv-model.currenciesis an array used withv-forto populate the select dropdowns.ratesholds the conversion rates (relative to a base currency, here USD). Important: In a real application, these rates should be fetched from a reliable API.convertedAmountis acomputedproperty. It automatically recalculates wheneveramount,convertFrom, orconvertTochanges.- The conversion logic first converts the input amount to a base currency (USD) and then converts that base amount to the target currency.
.toFixed(2)formats the result to two decimal places.- Basic styling is added for better presentation.
This example highlights how computed properties simplify reactive calculations, making the template cleaner and the logic easier to manage.
Example 2: Simple Customer List with Components
Section titled “Example 2: Simple Customer List with Components”This example demonstrates creating a list of customers, adding new customers via a form, and deleting customers. It introduces basic component usage, props, and event emission ($emit) for child-to-parent communication.
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Vue 3 Customer List</title> <script src="https://unpkg.com/vue@3"></script> <style> #customer-app { padding: 20px; margin: 20px; background-color: #f9f9f9; border-radius: 8px; } .customer-form input, .customer-form button { margin-right: 10px; margin-bottom: 15px; padding: 8px; font-size: 1em; } .customer-list { margin-top: 20px; } .customer-item { display: flex; justify-content: space-between; align-items: center; padding: 10px; border: 1px solid #eee; margin-bottom: 5px; background-color: white; } .customer-item span { flex-grow: 1; margin-right: 10px; } .customer-item button { padding: 5px 10px; background-color: #ff4d4d; color: white; border: none; cursor: pointer; border-radius: 4px; } .customer-item:nth-child(even) { background-color: #fdfdfd; } </style></head><body> <div id="customer-app"> <h1>Customer Management</h1>
<!-- Form to add new customers --> <div class="customer-form"> <input type="text" v-model="newCustomer.firstName" placeholder="First Name" /> <input type="text" v-model="newCustomer.lastName" placeholder="Last Name" /> <input type="text" v-model="newCustomer.address" placeholder="Address" /> <button @click="addCustomer">Add Customer</button> </div>
<!-- List of customers --> <div class="customer-list" v-if="customers.length > 0"> <h2>Customer List</h2> <!-- Customer Item Component --> <customer-item v-for="(customer, index) in customers" :key="customer.id" :customer-data="customer" @delete-customer="deleteCustomer(index)"> </customer-item> </div> <p v-else>No customers added yet.</p>
</div>
<script> const { createApp, ref, reactive } = Vue;
const app = createApp({ setup() { const customers = ref([ { id: 1, firstName: 'John', lastName: 'Doe', address: '123 Main St' }, { id: 2, firstName: 'Jane', lastName: 'Smith', address: '456 Oak Ave' } ]); const newCustomer = reactive({ firstName: '', lastName: '', address: '' }); let nextId = 3; // Simple ID generation
function addCustomer() { if (newCustomer.firstName && newCustomer.lastName) { // Basic validation customers.value.push({ id: nextId++, // Assign and increment ID firstName: newCustomer.firstName, lastName: newCustomer.lastName, address: newCustomer.address }); // Clear the form newCustomer.firstName = ''; newCustomer.lastName = ''; newCustomer.address = ''; } }
function deleteCustomer(index) { customers.value.splice(index, 1); }
return { customers, newCustomer, addCustomer, deleteCustomer }; } });
// Define the Customer Item Child Component app.component('customer-item', { props: { customerData: { // Use camelCase for JS prop name type: Object, required: true } }, emits: ['delete-customer'], // Declare emitted events // Use kebab-case for HTML attribute: :customer-data template: ` <div class="customer-item"> <span>{{ customerData.firstName }} {{ customerData.lastName }}</span> <span>{{ customerData.address }}</span> <button @click="$emit('delete-customer')">Delete</button> </div> ` // Note: The alternating background color is handled by CSS :nth-child selector });
app.mount('#customer-app'); </script></body></html>Explanation
Section titled “Explanation”- The main app uses
reffor thecustomersarray andreactivefor thenewCustomerform object. - The
addCustomerfunction pushes a new customer object (with a unique ID) to thecustomersarray and clears the form. - The
v-fordirective iterates over thecustomersarray to display each customer. - A child component
customer-itemis defined usingapp.component. - Props (
customerData): The parent app passes customer data down to eachcustomer-itemcomponent using:customer-data="customer". Inside the component definition, the prop is declared usingprops: { customerData: {...} }. - Event Emission (
$emit): When the ‘Delete’ button insidecustomer-itemis clicked, it emits a custom event nameddelete-customerusing$emit('delete-customer'). - Listening to Events (
@delete-customer): The parent listens for this event on the component tag using@delete-customer="deleteCustomer(index)". When the event is received, the parent’sdeleteCustomermethod is called with the index of the customer to remove. :keyattribute is crucial for Vue’s list rendering performance and state management, usingcustomer.idprovides a stable key.- The
emits: ['delete-customer']option in the child component explicitly declares the events it can emit, which is good practice in Vue 3.
This example illustrates fundamental Vue concepts: managing lists, handling user input, component creation, passing data down with props, and communicating events up with $emit.