📕
TIC
  • Tehnologii ale InformaÅ£iei ÅŸi ComunicaÅ£iilor (TIC)
  • Basic web principles
    • How web pages work
    • The pillars of a web page
    • Extra: Getting Started with GitHub
  • Basic HTML
    • Description and Basic Syntax
    • Extra resources
  • Basic CSS
    • Description and Basic Syntax
    • Advanced Positioning
    • Extra Resources
  • Basic Javascript
    • Description and basic syntax
    • The Document Object Model
    • Extra Resources
    • Basic assignment
    • The Color Game
  • Advanced Javascript
    • Runtime Engine, Callstack, Scope
    • ES6
  • Advanced Javascript 2
  • Programming paradigms
  • OOP Javascript
  • Functional Programming
  • OOP vs. Functional Programming
  • Asynchronous Javascript
  • Backend Javascript
    • NodeJS
    • ExpressJS
    • REST APIs
    • Authentication and Authorization
  • Firebase
    • NoSQL Databases
    • Database as a Service
    • Google Cloud Firestore
    • CRUD operations
    • Securing your database
  • Basic VueJS
  • Agenda: VueJS and Frontend Frameworks
  • Single Page Applications
  • VueJS basic syntax
  • Vue Components
  • Advanced VueJS
  • Advanced apps with Vue CLI
  • Vue Router
  • SPA State Management - Vuex
  • Composition API
  • Evaluation
    • Final Individual assignment
Powered by GitBook
On this page
  • Single File Components
  • Practical example: Making HTTP requests
  • Practical Example: Working with Forms

Was this helpful?

Advanced apps with Vue CLI

PreviousVue ComponentsNextVue Router

Last updated 4 months ago

Was this helpful?

Vue CLI (Command Line Interface) is a full system for rapid Vue.js development.

#installing Vue CLI
npm install -g @vue/cli

#creating a project scaffold
vue create my-project
# OR using the Graphical User Interface
vue ui

You can manually select what packages or features to be installed, options that are likely needed for more production-oriented projects.

Adding plugins to the project.

vue add eslint

Single File Components

When a project is created, a structured folder hierarchy is created.

Also Single File Components are in place (with the .vue extension), meaning we'll be able to access the logic, the layout and the style within the same file.

What About the Separation of Concerns?

One important thing to note is that separation of concerns is not equal to the separation of file types. In modern UI development, instead of dividing the codebase into three huge layers that interweave with one another, it makes much more sense to divide them into loosely-coupled components and compose them. Inside a component, its template, logic and styles are inherently coupled, and collocating them actually makes the component more cohesive and maintainable.

MySinglePageComponent.vue
<template>
  <div>
    <h1>My Single Page Component</h1>
    <img :src="imageUrl" alt="My Image">
  </div>
</template>

<script>
export default {
  name: 'MySinglePageComponent',
  data() {
    return {
      imageUrl: 'https://example.com/my-image.png',
    };
  },
};
</script>

<style>
img {
  width: 100%;
  height: auto;
}
</style>

Parent component
<template>
  <div>
    <my-single-page-component></my-single-page-component>
  </div>
</template>

<script>
import MySinglePageComponent from './MySinglePageComponent.vue';

export default {
  components: {
    MySinglePageComponent,
  },
};
</script>

In Vue.js, a view is a component.

There's no fundamental difference between a "view" and a "component" in terms of how Vue.js treats them. Both are built using the same component structure (with a template, script, and optional style).

So, why the distinction?

The distinction between "views" and "components" is primarily a matter of convention and organization within a Vue.js project. It's a way to structure your code and make it easier to understand.

Here's how the convention usually works:

  • Components: These are generally smaller, reusable UI elements that can be used across multiple parts of your application. Think of things like buttons, input fields, modals, or lists. They often focus on a specific piece of functionality or visual element.

  • Views: These are typically the top-level components that represent different "pages" or "screens" in your application. They are usually associated with specific routes and are responsible for composing and displaying multiple components to create the overall layout of a page.

Example:

Imagine an e-commerce application:

  • Components: ProductCard.vue, ShoppingCart.vue, AddToCartButton.vue

  • Views: HomePage.vue, ProductDetailsPage.vue, CheckoutPage.vue

Folder Structure

To reinforce this convention, Vue.js projects often have separate folders:

  • src/components/: For reusable components.

  • src/views/: For top-level view components.

Important Notes

  • Flexibility: This is just a convention, not a strict rule. You can structure your project in a way that makes sense to you.

  • Router Views: Vue Router (the official routing library for Vue.js) uses a special component called <router-view> to dynamically display the component associated with the current route. This is where your "view" components are typically rendered.

Practical example: Making HTTP requests

We can use the default fetch API or we can use a popular library such as Axios.

// First we need to install the Axios as a Vue CLI Plugin
vue add axios

// or
npm install axios

This Vue component, named AxiosExample, fetches a list of posts from the JSONPlaceholder API upon mounting. It uses Axios to make an asynchronous GET request and manages three states in its template: "Loading data..." while the request is in progress, "Error fetching data..." if the request fails, and a list of post titles and bodies if the request is successful. The component updates its posts, loading, and error data properties to control which state is displayed to the user, ensuring a clear and informative UI during the data fetching process.

<template>
  <div>
    <h1>Fetching Data with Axios in Vue</h1>

    <div v-if="loading">
      Loading data...
    </div>

    <div v-else-if="error">
      Error fetching data: {{ error }}
    </div>

    <div v-else>
      <h2>Posts from JSONPlaceholder API</h2>
      <ul>
        <li v-for="post in posts" :key="post.id">
          <h3>{{ post.title }}</h3>
          <p>{{ post.body }}</p>
        </li>
      </ul>
    </div>
  </div>
</template>

<script>

// 1. Import Axios
import axios from 'axios';

export default {
  name: 'AxiosExample',
  
  data() {
    return {
      posts: [],
      loading: false,
      error: null,
    };
  },
  
  mounted() {
    this.fetchPosts(); // Call the method to fetch data when component is mounted
  },
  
  methods: {
    async fetchPosts() {
      this.loading = true; // Set loading state to true when fetching starts
      this.error = null;   // Reset error state

      try {
        // 2. Use Axios to make a GET request
        const response = await axios.get('https://jsonplaceholder.typicode.com/posts');
        // 3. Handle successful response and store data
        this.posts = response.data;
      } catch (e) {
        // 4. Handle errors
        console.error('Error fetching posts:', e);
        this.error = e.message || 'Something went wrong'; // Display error message
      } finally {
        this.loading = false; // Set loading state to false after request (success or error)
      }
    },
  },
};
</script>

<style scoped>
/* Component-specific styles (optional) */

ul {
  list-style-type: none;
  padding: 0;
}

li {
  margin-bottom: 20px;
  padding: 15px;
  border: 1px solid #ddd;
  border-radius: 5px;
  background-color: #f9f9f9;
}

h3 {
  margin-top: 0;
  color: #333;
}

p {
  color: #555;
}

.error {
  color: red;
}

.loading {
  font-style: italic;
  color: gray;
}
</style>

Practical Example: Working with Forms

This Vue component, SimpleFormExample, showcases basic form handling by using v-model for two-way data binding on text inputs and a textarea, linking them to the formData data object. Upon form submission (preventing default page reload), the handleSubmit method copies the form data to submittedData for display, clears the input fields by resetting formData, and shows a basic submission alert.

<template>
  <div>
    <h1>Simple Vue Form Example</h1>

    <form @submit.prevent="handleSubmit">
      <div>
        <label for="name">Name:</label>
        <input type="text" id="name" v-model="formData.name">
      </div>

      <div>
        <label for="email">Email:</label>
        <input type="email" id="email" v-model="formData.email">
      </div>

      <div>
        <label for="message">Message:</label>
        <textarea id="message" v-model="formData.message"></textarea>
      </div>

      <button type="submit">Submit</button>
    </form>

    <div v-if="submittedData">
      <h2>Submitted Data:</h2>
      <p><strong>Name:</strong> {{ submittedData.name }}</p>
      <p><strong>Email:</strong> {{ submittedData.email }}</p>
      <p><strong>Message:</strong> {{ submittedData.message }}</p>
    </div>
  </div>
</template>

<script>
export default {
  name: 'SimpleFormExample',
  
  data() {
    return {
      formData: {
        name: '',
        email: '',
        message: ''
      },
      submittedData: null // To store the submitted data for display
    };
  },
  
  methods: {
    handleSubmit() {
      // In a real application, you would likely send this data to a server.
      // For this simple example, we'll just store it in 'submittedData' to display.
      this.submittedData = { ...this.formData }; // Create a copy to avoid direct mutation
      this.formData = { name: '', email: '', message: '' }; // Clear the form after submission
      alert('Form submitted!'); // Basic feedback
    }
  }
};
</script>