Mastering Core Vue.js Concepts and Architecture

Initialization and MVVM Pattern

To initialize a Vue application, start by creating a DOM mount point and instantiating the Vue constructor. The ViewModel serves as the bridge between the data (Model) and the view (DOM). Below is a basic setup demonstrating two-way data binding using the v-model directive and interpolation syntax.

<div id="root">
  <input type="text" v-model="greeting" />
  <p>{{ greeting }}</p>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
  const app = new Vue({
    el: '#root',
    data: {
      greeting: 'Welcome to Vue.js'
    }
  });
</script>

Template Syntax and Directives

Vue templates use an HTML-based syntax that allows you to declaratively bind the rendered DOM to the underlying component instance's data. All Vue templates are valid HTML that can be parsed by spec-compliant browsers and HTML parsers.

  • Interpolation: Use double mustaches {{ }} for text content.
  • Directives: Special attributes with the v- prefix (e.g., v-bind, v-on). Shorthand syntax exists for common directives (: for bind, @ for on).
<div id="app">
  <!-- Text Interpolation -->
  <h2>{{ message.toUpperCase() }}</h2>

  <!-- Attribute Binding (v-bind) -->
  <a :href="url">Visit Link</a>

  <!-- Event Handling (v-on) -->
  <button @click="handleClick">Click Me</button>
</div>

<script>
  new Vue({
    el: '#app',
    data: {
      message: 'Hello World',
      url: 'https://example.com'
    },
    methods: {
      handleClick() {
        alert('Button clicked!');
      }
    }
  });
</script>

Computed Properties and Watchers

Computed properties allow you to define a property that is derived from other data properties. They are cached based on their dependencies and will only re-evaluate when a dependency changes. Watchers, on the other hand, are more imperative and are useful for performing asynchronous operations or expensive logic in response to changing data.

<div id="compute-demo">
  Price: <input type="number" v-model.number="price">
  Tax: <input type="number" v-model.number="taxRate">
  <p>Total: ${{ total }}</p>
  <p>Formatted Total: {{ formattedTotal }}</p>
</div>

<script>
  new Vue({
    el: '#compute-demo',
    data: {
      price: 100,
      taxRate: 0.1
    },
    computed: {
      total() {
        return this.price * (1 + this.taxRate);
      },
      formattedTotal() {
        return this.total.toFixed(2);
      }
    },
    watch: {
      total(newVal) {
        console.log(`Total changed to: ${newVal}`);
      }
    }
  });
</script>

Class and Style Bindings

Manipulating CSS classes and inline styles dynamically is common. Vue provides special enhancements for v-bind when used with class and style. Expressions can accept objects or arrays.

<style>
  .active { color: green; font-weight: bold; }
  .error { color: red; text-decoration: line-through; }
</style>

<div id="style-demo">
  <!-- Object Syntax -->
  <div :class="{ active: isActive, error: hasError }">
    Dynamic Class Object
  </div>

  <!-- Array Syntax -->
  <div :class="[isActive ? 'active' : '', hasError ? 'error' : '']">
    Dynamic Class Array
  </div>

  <!-- Inline Style Object -->
  <div :style="{ color: textColor, fontSize: fontSize + 'px' }">
    Dynamic Styles
  </div>
</div>

Conditional Rendering

Conditional directives allow you to render elements based on conditions. Use v-if for conditional block rendering (which removes elements from the DOM) and v-show for toggling visibility via CSS display styles. v-if has higher toggle cost, while v-show has higher initial render cost.

<div id="cond-demo">
  <button @click="isLoggedIn = !isLoggedIn">Toggle Login</button>

  <div v-if="isLoggedIn">
    <p>Welcome back, User!</p>
  </div>
  <div v-else>
    <p>Please log in.</p>
  </div>

  <hr>

  <p v-show="isVisible">This text toggles visibility efficiently.</p>
</div>

List Rendering and Filtering

The v-for directive is used to render a list of items based on an array. It is recommended to provide a unique key attribute for each item to help Vue track identities for efficient DOM updates.

<div id="list-demo">
  <input type="text" v-model="search" placeholder="Search items...">
  
  <ul>
    <li v-for="(item, index) in filteredItems" :key="item.id">
      {{ index + 1 }}. {{ item.name }} - ${{ item.price }}
      <button @click="removeItem(index)">X</button>
    </li>
  </ul>
</div>

<script>
  new Vue({
    el: '#list-demo',
    data: {
      search: '',
      inventory: [
        { id: 1, name: 'Laptop', price: 999 },
        { id: 2, name: 'Phone', price: 699 },
        { id: 3, name: 'Tablet', price: 299 }
      ]
    },
    computed: {
      filteredItems() {
        const query = this.search.toLowerCase();
        return this.inventory.filter(item => 
          item.name.toLowerCase().includes(query)
        );
      }
    },
    methods: {
      removeItem(index) {
        // In a real app, use unique ID to find item
        this.inventory.splice(index, 1);
      }
    }
  });
</script>

Event Handling

Vue provides event modifiers to handle common DOM event tasks directly in the template. Modifiers like .prevent, .stop, and .enter can be chained.

<div id="event-demo">
  <!-- Prevent default submission -->
  <form @submit.prevent="onSubmit">
    <button type="submit">Submit</button>
  </form>

  <!-- Stop propagation -->
  <div @click="outerClick" style="padding: 20px; background: #eee;">
    Outer
    <div @click.stop="innerClick" style="padding: 20px; background: #ddd;">
      Inner (No Bubbling)
    </div>
  </div>

  <!-- Key modifier -->
  <input @keyup.enter="submitMessage" placeholder="Press Enter">
</div>

Form Input Bindings

The v-model directive creates a two-way binding on form input, textarea, and select elements. It automatically picks the correct way to update the element based on the input type.

<div id="form-demo">
  <form>
    <label>Username:</label> <input v-model="user.username">
    <br>
    <label>Subscribe?</label> <input type="checkbox" v-model="user.subscribed">
    <br>
    <label>Role:</label>
    <select v-model="user.role">
      <option value="admin">Admin</option>
      <option value="editor">Editor</option>
      <option value="viewer">Viewer</option>
    </select>
    <br>
    <button type="button" @click="logForm">Log Data</button>
  </form>
</div>

Instance Lifecycle

Every Vue instance goes through a series of initialization steps when it is created. For example, it needs to set up data observation, compile the template, mount the instance to the DOM, and update the DOM when data changes. Along the way, it runs lifecycle hooks like created, mounted, updated, and destroyed.

new Vue({
  data: { status: 'Init' },
  created() {
    console.log('Instance created. Data observed, but DOM not mounted.');
  },
  mounted() {
    console.log('Instance mounted to DOM. Element accessible via this.$el');
  },
  updated() {
    console.log('Virtual DOM re-rendered and patched.');
  },
  beforeDestroy() {
    console.log('Teardown: Clean up timers or event listeners here.');
  }
});

Transitions and Animations

Vue provides a transition wrapper component that allows you to apply transition effects to elements when they are inserted, updated, or removed from the DOM.

<style>
  .fade-enter-active, .fade-leave-active { transition: opacity 0.5s; }
  .fade-enter, .fade-leave-to { opacity: 0; }
</style>

<div id="transition-demo">
  <button @click="show = !show">Toggle</button>
  <transition name="fade">
    <p v-if="show">This text fades in and out.</p>
  </transition>
</div>

Custom Directives

Besides the built-in directives, Vue allows you to register custom directives. Directives provide a mechanism to map data changes to arbitrary DOM behavior.

<!-- Registering a global focus directive -->
<script>
Vue.directive('focus', {
  inserted: function (el) {
    el.focus();
  }
});

// Usage
<input v-focus>
</script>

Plugins

Plugins add global-level functionality to Vue. There is no strictly defined scope for a plugin, but common scenarios include:

  • Adding some global methods or properties.
  • Adding one or more global assets: directives/filters/transitions.
  • Adding some component options by global mixin.
  • Adding Vue instance methods by attaching them to Vue.prototype.
const MyPlugin = {
  install(Vue, options) {
    // 1. Add global method or property
    Vue.myGlobalMethod = function () {
      console.log('Global method called');
    };

    // 2. Add a global asset
    Vue.directive('my-directive', {
      bind(el, binding, vnode, oldVnode) {
        el.style.color = binding.value;
      }
    });

    // 3. Inject some component options
    Vue.mixin({
      created: function () {
        console.log('Component mixed in');
      }
    });

    // 4. Add an instance method
    Vue.prototype.$myMethod = function (methodOptions) {
      console.log('Instance method called');
    };
  }
};

// Use the plugin
Vue.use(MyPlugin);

Tags: Vue.js Frontend Development javascript web development Tutorial

Posted on Fri, 03 Jul 2026 17:18:16 +0000 by christillis