Getting Started with Vue.js and Element UI for Modern Web Development
Vue.js Overview
Vue.js is a progressive frontend framework designed for building user interfaces. It focuses exclusively on the view layer, making it remarkably easy to learn and integrate with other libraries or existing projects. Vue achieves reactive data binding and composable view components through a straightforward API.
Key Characteristics
- Simplicity: Built on HTML, CSS, and JavaScript fundamentals for rapid adoption
- Flexibility: Compact core with progressive technology stack suitable for projects of any scale
- Performance: ~20kb minified and gzipped, virtual DOM for efficient rendering, automatic optimization
Your First Vue Application
Development Workflow
- Include the Vue.js library in your project
- Create the view layer with HTML and CSS
- Implement business logic in the script section
Basic Implementation
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>First Vue App</title>
</head>
<body>
<div id="app">
{{message}}
</div>
</body>
<script src="js/vue.js"></script>
<script>
const app = new Vue({
el: "#app",
data: {
message: "Hello Vue"
}
});
</script>
</html>
Vue Instance Structure
Every Vue application starts with a Vue instance containing configuration options:
const vm = new Vue({
el: "selector", // Mounts to DOM element
data: {}, // Holds reactive state
methods: {} // Defines component methods
});
| Option | Purpose |
|---|---|
| el | Specifies which DOM element the instance controls |
| data | Stores reactive data properties |
| methods | Defines functions accessible within the component |
Enhanced Example
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Enhanced Vue App</title>
</head>
<body>
<div id="app">
<div>Name: {{studentName}}</div>
<div>Campus: {{campusName}}</div>
<button onclick="greetStudent()">Greet</button>
<button onclick="changeCampus()">Update Campus</button>
</div>
</body>
<script src="js/vue.js"></script>
<script>
const vm = new Vue({
el: "#app",
data: {
studentName: "Alice",
campusName: "Tech Institute"
},
methods: {
study() {
alert(this.studentName + " studying at " + this.campusName);
}
}
});
function greetStudent() {
vm.study();
}
function changeCampus() {
vm.campusName = "Innovation Hub";
}
</script>
</html>
Vue Directives Reference
Directives are special attributes with the v- prefix that apply reactive behavior to HTML elements.
Text Interpolation
The v-html directive renders content as raw HTML:
<div id="app">
<div>{{rawText}}</div>
<div v-html="rawText"></div>
</div>
<script>
new Vue({
el: "#app",
data: {
rawText: "<strong>Bold Text</strong>"
}
});
</script>
Attribute Binding
The v-bind directive binds attributes dynamically. The colon shorthand is common used:
<div id="app">
<a v-bind:href="linkUrl">Search Engine</a>
<br>
<a :href="linkUrl">Search Engine</a>
<br>
<div :class="customClass">Styled Container</div>
</div>
<script>
new Vue({
el: "#app",
data: {
linkUrl: "https://www.google.com",
customClass: "highlight"
}
});
</script>
Conditional Rendering
Use v-if, v-else-if, and v-else for conditional DOM manipulation. The v-show directive toggles visibility via CSS display property:
<div id="app">
<div v-if="score % 3 === 0">Block A</div>
<div v-else-if="score % 3 === 1">Block B</div>
<div v-else>Block C</div>
<div v-show="isVisible">Toggle Panel</div>
</div>
<script>
new Vue({
el: "#app",
data: {
score: 4,
isVisible: true
}
});
</script>
List Rendering
The v-for directive iterates over arrays and objects:
<div id="app">
<ul>
<li v-for="item in fruits">
{{item}}
</li>
<li v-for="val in user">
{{val}}
</li>
</ul>
</div>
<script>
new Vue({
el: "#app",
data: {
fruits: ["Apple", "Banana", "Orange"],
user: {
username: "Alice",
age: 25
}
}
});
</script>
Event Handling
The v-on directive attaches event listeners. The @ shorthand is preferred:
<div id="app">
<div>{{title}}</div>
<button v-on:click="updateTitle()">Click Me</button>
<button v-on:dblclick="updateTitle()">Double Click</button>
<button @click="updateTitle()">Short Syntax</button>
</div>
<script>
new Vue({
el: "#app",
data: {
title: "Default Title"
},
methods: {
updateTitle() {
this.title = "Updated Title";
}
}
});
</script>
Two-Way Data Binding
The v-model directive creates bidirectional binding between form inputs and application state:
<div id="app">
<form autocomplete="off">
Full Name: <input type="text" v-model="fullName">
<br>
Age: <input type="number" v-model="userAge">
</form>
</div>
<script>
new Vue({
el: "#app",
data: {
fullName: "Alice",
userAge: 25
}
});
</script>
Understanding MVVM Architecture
The Model-View-ViewModel pattern separates concerns in frontend applications:
- Model: JavaScript objects containing application data
- View: HTML templates displaying the user interface
- ViewModel: Bridges Model and View, synchronizing data changes bidirectionally
Element UI Componant Library
Element UI is a Vue-based component library providing ready-to-use UI components for rapid application development.
Prerequisites
Element UI requires Vue as a dependency. Official documentation is available at https://element.eleme.cn/#/en-US
Quick Start
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Element UI Demo</title>
<link rel="stylesheet" href="element-ui/lib/theme-chalk/index.css">
<script src="js/vue.js"></script>
<script src="element-ui/lib/index.js"></script>
</head>
<body>
<button>Native Button</button>
<br>
<div id="app">
<el-row>
<el-button>Default</el-button>
<el-button type="primary">Primary</el-button>
<el-button type="success">Success</el-button>
<el-button type="info">Info</el-button>
<el-button type="warning">Warning</el-button>
<el-button type="danger">Danger</el-button>
</el-row>
<br>
<el-row>
<el-button plain>Plain</el-button>
<el-button type="primary" plain>Primary Plain</el-button>
<el-button type="success" plain>Success Plain</el-button>
<el-button type="info" plain>Info Plain</el-button>
<el-button type="warning" plain>Warning Plain</el-button>
<el-button type="danger" plain>Danger Plain</el-button>
</el-row>
<br>
<el-row>
<el-button round>Round</el-button>
<el-button type="primary" round>Round Primary</el-button>
<el-button type="success" round>Round Success</el-button>
<el-button type="info" round>Round Info</el-button>
<el-button type="warning" round>Round Warning</el-button>
<el-button type="danger" round>Round Danger</el-button>
</el-row>
<br>
<el-row>
<el-button icon="el-icon-search" circle></el-button>
<el-button type="primary" icon="el-icon-edit" circle></el-button>
<el-button type="success" icon="el-icon-check" circle></el-button>
<el-button type="info" icon="el-icon-message" circle></el-button>
<el-button type="warning" icon="el-icon-star-off" circle></el-button>
<el-button type="danger" icon="el-icon-delete" circle></el-button>
</el-row>
</div>
</body>
<script>
new Vue({
el: "#app"
});
</script>
</html>
Layout Components
Basic Grid System
Element UI divides the layout into 24 columns. Combine el-row and el-col for responsive designs:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Grid Layout</title>
<link rel="stylesheet" href="element-ui/lib/theme-chalk/index.css">
<script src="js/vue.js"></script>
<script src="element-ui/lib/index.js"></script>
<style>
.el-row {
margin-bottom: 20px;
}
.section-dark { background: #ff6b6b; }
.section-mid { background: #4ecdc4; }
.section-light { background: #45b7d1; }
.grid-box {
border-radius: 4px;
min-height: 36px;
}
</style>
</head>
<body>
<div id="app">
<el-row>
<el-col :span="24"><div class="grid-box section-dark"></div></el-col>
</el-row>
<el-row>
<el-col :span="12"><div class="grid-box section-mid"></div></el-col>
<el-col :span="12"><div class="grid-box section-light"></div></el-col>
</el-row>
<el-row>
<el-col :span="8"><div class="grid-box section-mid"></div></el-col>
<el-col :span="8"><div class="grid-box section-light"></div></el-col>
<el-col :span="8"><div class="grid-box section-mid"></div></el-col>
</el-row>
<el-row>
<el-col :span="6"><div class="grid-box section-mid"></div></el-col>
<el-col :span="6"><div class="grid-box section-light"></div></el-col>
<el-col :span="6"><div class="grid-box section-mid"></div></el-col>
<el-col :span="6"><div class="grid-box section-light"></div></el-col>
</el-row>
<el-row>
<el-col :span="4"><div class="grid-box section-mid"></div></el-col>
<el-col :span="4"><div class="grid-box section-light"></div></el-col>
<el-col :span="4"><div class="grid-box section-mid"></div></el-col>
<el-col :span="4"><div class="grid-box section-light"></div></el-col>
<el-col :span="4"><div class="grid-box section-mid"></div></el-col>
<el-col :span="4"><div class="grid-box section-light"></div></el-col>
</el-row>
</div>
</body>
<script>
new Vue({
el: "#app"
});
</script>
</html>
Container Layout
Structure pages with header, sidebar, main content, and footer sections:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Container Layout</title>
<link rel="stylesheet" href="element-ui/lib/theme-chalk/index.css">
<script src="js/vue.js"></script>
<script src="element-ui/lib/index.js"></script>
<style>
.app-header, .app-footer {
background-color: #d18e66;
color: #333;
text-align: center;
height: 100px;
}
.app-sidebar {
background-color: #55e658;
color: #333;
text-align: center;
height: 580px;
}
.app-main {
background-color: #5fb1f3;
color: #333;
text-align: center;
height: 520px;
}
</style>
</head>
<body>
<div id="app">
<el-container>
<el-header class="app-header">Header</el-header>
<el-container>
<el-aside width="200px" class="app-sidebar">Sidebar</el-aside>
<el-container>
<el-main class="app-main">Main Content</el-main>
<el-footer class="app-footer">Footer</el-footer>
</el-container>
</el-container>
</el-container>
</div>
</body>
<script>
new Vue({
el: "#app"
});
</script>
</html>
Form Cmoponents
Build complex forms with validation support:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Form Components</title>
<link rel="stylesheet" href="element-ui/lib/theme-chalk/index.css">
<script src="js/vue.js"></script>
<script src="element-ui/lib/index.js"></script>
</head>
<body>
<div id="app">
<el-form :model="formData" :rules="validationRules" ref="formRef" label-width="100px">
<el-form-item label="Event Name" prop="name">
<el-input v-model="formData.name"></el-input>
</el-form-item>
<el-form-item label="Region" prop="region">
<el-select v-model="formData.region" placeholder="Select region">
<el-option label="Region A" value="regionA"></el-option>
<el-option label="Region B" value="regionB"></el-option>
</el-select>
</el-form-item>
<el-form-item label="Event Date" required>
<el-col :span="11">
<el-form-item prop="date1">
<el-date-picker type="date" placeholder="Pick date" v-model="formData.date1" style="width: 100%;"></el-date-picker>
</el-form-item>
</el-col>
<el-col class="line" :span="2">-</el-col>
<el-col :span="11">
<el-form-item prop="date2">
<el-time-picker placeholder="Pick time" v-model="formData.date2" style="width: 100%;"></el-time-picker>
</el-form-item>
</el-col>
</el-form-item>
<el-form-item label="Instant Delivery" prop="delivery">
<el-switch v-model="formData.delivery"></el-switch>
</el-form-item>
<el-form-item label="Event Type" prop="type">
<el-checkbox-group v-model="formData.type">
<el-checkbox label="Online Promotion" name="type"></el-checkbox>
<el-checkbox label="Offline Campaign" name="type"></el-checkbox>
<el-checkbox label="Theme Event" name="type"></el-checkbox>
<el-checkbox label="Brand Exposure" name="type"></el-checkbox>
</el-checkbox-group>
</el-form-item>
<el-form-item label="Resources" prop="resource">
<el-radio-group v-model="formData.resource">
<el-radio label="Sponsor Funding"></el-radio>
<el-radio label="Free Venue"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="Description" prop="desc">
<el-input type="textarea" v-model="formData.desc"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm('formRef')">Create</el-button>
<el-button @click="resetForm('formRef')">Reset</el-button>
</el-form-item>
</el-form>
</div>
</body>
<script>
new Vue({
el: "#app",
data: {
formData: {
name: '',
region: '',
date1: '',
date2: '',
delivery: false,
type: [],
resource: '',
desc: ''
},
validationRules: {
name: [
{ required: true, message: 'Please enter event name', trigger: 'blur' },
{ min: 3, max: 5, message: 'Length between 3 and 5 characters', trigger: 'blur' }
],
region: [
{ required: true, message: 'Please select a region', trigger: 'change' }
],
date1: [
{ type: 'date', required: true, message: 'Please select a date', trigger: 'change' }
],
date2: [
{ type: 'date', required: true, message: 'Please select a time', trigger: 'change' }
],
type: [
{ type: 'array', required: true, message: 'Select at least one type', trigger: 'change' }
],
resource: [
{ required: true, message: 'Please select resources', trigger: 'change' }
],
desc: [
{ required: true, message: 'Please provide description', trigger: 'blur' }
]
}
},
methods: {
submitForm(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
alert('Form submitted successfully!');
} else {
console.log('Validation failed');
return false;
}
});
},
resetForm(formName) {
this.$refs[formName].resetFields();
}
}
});
</script>
</html>
Table Components
Display structured data with built-in styling:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Table Component</title>
<link rel="stylesheet" href="element-ui/lib/theme-chalk/index.css">
<script src="js/vue.js"></script>
<script src="element-ui/lib/index.js"></script>
</head>
<body>
<div id="app">
<el-table :data="records" style="width: 100%">
<el-table-column prop="date" label="Date" width="180"></el-table-column>
<el-table-column prop="name" label="Name" width="180"></el-table-column>
<el-table-column prop="address" label="Address"></el-table-column>
<el-table-column label="Actions" width="180">
<el-button type="warning">Edit</el-button>
<el-button type="danger">Delete</el-button>
</el-table-column>
</el-table>
</div>
</body>
<script>
new Vue({
el: "#app",
data: {
records: [{
date: '2024-01-15',
name: 'John Smith',
address: '123 Main Street, City'
}, {
date: '2024-01-16',
name: 'Jane Doe',
address: '456 Oak Avenue, Town'
}, {
date: '2024-01-17',
name: 'Bob Wilson',
address: '789 Pine Road, Village'
}, {
date: '2024-01-18',
name: 'Alice Brown',
address: '321 Elm Boulevard, Metropolis'
}]
}
});
</script>
</html>
Navigation Components
Horizontal Navigation Bar
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Horizontal Navigation</title>
<link rel="stylesheet" href="element-ui/lib/theme-chalk/index.css">
<script src="js/vue.js"></script>
<script src="element-ui/lib/index.js"></script>
</head>
<body>
<div id="app">
<el-menu
:default-active="activeIndex"
class="el-menu-horizontal"
mode="horizontal"
background-color="#545c64"
text-color="#fff"
active-text-color="#ffd04b">
<el-menu-item index="1">Dashboard</el-menu-item>
<el-submenu index="2">
<template slot="title">Workspace</template>
<el-menu-item index="2-1">Option 1</el-menu-item>
<el-menu-item index="2-2">Option 2</el-menu-item>
<el-menu-item index="2-3">Option 3</el-menu-item>
<el-submenu index="2-4">
<template slot="title">Option 4</template>
<el-menu-item index="2-4-1">Suboption 1</el-menu-item>
<el-menu-item index="2-4-2">Suboption 2</el-menu-item>
</el-submenu>
</el-submenu>
<el-menu-item index="3" disabled>Notifications</el-menu-item>
<el-menu-item index="4">
<a href="https://example.com" target="_blank">Orders</a>
</el-menu-item>
</el-menu>
</div>
</body>
<script>
new Vue({
el: "#app",
data: {
activeIndex: "1"
}
});
</script>
</html>
Vertical Sidebar Navigation
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Sidebar Navigation</title>
<link rel="stylesheet" href="element-ui/lib/theme-chalk/index.css">
<script src="js/vue.js"></script>
<script src="element-ui/lib/index.js"></script>
</head>
<body>
<div id="app">
<el-col :span="6">
<el-menu
default-active="2"
class="el-menu-vertical"
background-color="#545c64"
text-color="#fff"
active-text-color="#ffd04b">
<el-submenu index="1">
<template slot="title">
<i class="el-icon-location"></i>
<span>Department A</span>
</template>
<el-menu-item-group>
<template slot="title">Group 1</template>
<el-menu-item index="1-1">Item 1</el-menu-item>
<el-menu-item index="1-2">Item 2</el-menu-item>
</el-menu-item-group>
<el-menu-item-group title="Group 2">
<el-menu-item index="1-3">Item 3</el-menu-item>
</el-menu-item-group>
<el-submenu index="1-4">
<template slot="title">Item 4</template>
<el-menu-item index="1-4-1">Subitem 1</el-menu-item>
</el-submenu>
</el-submenu>
<el-menu-item index="2">
<i class="el-icon-menu"></i>
<span slot="title">Department B</span>
</el-menu-item>
<el-menu-item index="3" disabled>
<i class="el-icon-document"></i>
<span slot="title">Department C</span>
</el-menu-item>
<el-menu-item index="4">
<i class="el-icon-setting"></i>
<span slot="title">Settings</span>
</el-menu-item>
</el-menu>
</el-col>
</div>
</body>
<script>
new Vue({
el: "#app"
});
</script>
</html>
Complete Example: Student Management Interface
Header Implementation
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Student Management</title>
<link rel="stylesheet" href="element-ui/lib/theme-chalk/index.css">
<script src="js/vue.js"></script>
<script src="element-ui/lib/index.js"></script>
<style>
.main-header {
background-color: #545c64;
}
.brand-logo {
width: 100px;
margin-top: 20px;
}
</style>
</head>
<body>
<div id="app">
<el-container>
<el-header class="main-header">
<el-container>
<div>
<el-image src="img/export.png" class="brand-logo"></el-image>
</div>
<el-menu
mode="horizontal"
background-color="#545c64"
text-color="white"
active-text-color="#ffd04b"
style="margin-left: auto;">
<el-menu-item index="1">Dashboard</el-menu-item>
<el-submenu index="2">
<template slot="title">My Workspace</template>
<el-menu-item index="2-1">Option 1</el-menu-item>
<el-menu-item index="2-2">Option 2</el-menu-item>
<el-menu-item index="2-3">Option 3</el-menu-item>
</el-submenu>
<el-menu-item index="3">
<a href="index.html" target="_self">Home</a>
</el-menu-item>
</el-menu>
</el-container>
</el-header>
</el-container>
</div>
</body>
<script>
new Vue({
el: "#app"
});
</script>
</html>
Sidebar with Navigation Menu
<el-container style="height: 580px; border: 1px solid #eee">
<el-aside width="200px" style="background-color: rgb(238, 241, 246)">
<el-menu :default-openeds="['1']">
<el-submenu index="1">
<template slot="title">
<i class="el-icon-menu"></i>Student Affairs
</template>
<el-menu-item-group>
<el-menu-item index="1-1">
<i class="el-icon-help"></i>Current Students
</el-menu-item>
<el-menu-item index="1-2">
<i class="el-icon-help"></i>Promotion Records
</el-menu-item>
<el-menu-item index="1-3">
<i class="el-icon-help"></i>Employment Stats
</el-menu-item>
</el-menu-item-group>
</el-submenu>
<el-submenu index="2">
<template slot="title">
<i class="el-icon-menu"></i>Admissions
</template>
<el-menu-item-group>
<el-menu-item index="2-1">
<i class="el-icon-help"></i>Prospective Students
</el-menu-item>
<el-menu-item index="2-2">
<i class="el-icon-help"></i>Pending Applications
</el-menu-item>
<el-menu-item index="2-3">
<i class="el-icon-help"></i>Enrolled Students
</el-menu-item>
</el-menu-item-group>
</el-submenu>
<el-submenu index="3">
<template slot="title">
<i class="el-icon-menu"></i>Curriculum
</template>
<el-menu-item-group>
<el-menu-item index="3-1">
<i class="el-icon-help"></i>Existing Courses
</el-menu-item>
<el-menu-item index="3-2">
<i class="el-icon-help"></i>Developing Courses
</el-menu-item>
<el-menu-item index="3-3">
<i class="el-icon-help"></i>Emerging Technologies
</el-menu-item>
</el-menu-item-group>
</el-submenu>
</el-menu>
</el-aside>
</el-container>
Main Content Area with Data Table
<el-container>
<el-main>
<b style="color: red; font-size: 20px;">Student Records</b>
<div style="float: right;">
<el-button type="primary">Add Student</el-button>
</div>
<el-table :data="studentData" style="width: 100%; margin-top: 20px;">
<el-table-column prop="date" label="Enrollment Date" width="140"></el-table-column>
<el-table-column prop="name" label="Name" width="120"></el-table-column>
<el-table-column prop="address" label="Address"></el-table-column>
<el-table-column label="Actions" width="180">
<el-button type="warning">Edit</el-button>
<el-button type="danger">Delete</el-button>
</el-table-column>
</el-table>
</el-main>
</el-container>
Vue Data Configuration
new Vue({
el: "#app",
data: {
studentData: [
{
date: "2024-03-01",
name: "Alice Chen",
address: "Beijing Chaoyang District"
},
{
date: "2024-03-02",
name: "Bob Liu",
address: "Beijing Haidian District"
},
{
date: "2024-03-03",
name: "Carol Wang",
address: "Beijing Xicheng District"
}
]
}
});