Skip to content

5. Project [vuejs-03]: Event Handling

The [vuejs-03] project introduces two concepts:

  • handling a [click] event on a button;
  • the [v-if] directive, which allows you to display an HTML block conditionally;

The project directory structure is as follows:

Image

5.1. The main script [main.js]

The [main.js] script remains unchanged:


// imports
import Vue from 'vue'
import App from './App.vue'

// plugins
import BootstrapVue from 'bootstrap-vue'
Vue.use(BootstrapVue);

// Bootstrap
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'

// configuration
Vue.config.productionTip = false

// instantiate the [App] project
new Vue({
  render: h => h(App),
}).$mount('#app')

5.2. The main component [App.vue]

The main component [App.vue] uses the [ClickOnMe] component instead of the [HelloBootstrap] component:


<template>
  <b-container>
    <b-card>
    <!-- Bootstrap Jumbotron -->
    <b-jumbotron>
      <!-- line -->
      <b-row>
        <!-- 4-column width -->
        <b-col cols="4">
          <img src="./assets/logo.jpg" alt="Cherry Blossoms" />
        </b-col>
        <!-- 8-column width -->
        <b-col cols="8">
          <h1>Calculate your taxes</h1>
        </b-col>
      </b-row>
    </b-jumbotron>
    <!-- component -->
    <ClickOnMe msg="Information..." />
    </b-card>
  </b-container>
</template>


<script>
import ClickOnMe from "./components/ClickOnMe.vue";

export default {
  name: "app",
  components: {
    ClickOnMe
  }
};
</script>

5.3. The [ClickOnMe] component

The [ClickOnMe] component introduces the following new concepts:


<template>
  <div>
    <!-- message on green background -->
    <b-alert show variant="success" align="center">
      <h4>[vuejs-03]: @click event, v-if directive, methods</h4>
    </b-alert>
    <!-- message on yellow background -->
    <b-alert show variant="warning" align="center" v-if="show">
      <h4>{{msg}}</h4>
    </b-alert>
    <!-- blue button -->
    <b-button variant="primary" @click="change">{{buttonTitle}}</b-button>
  </div>
</template>

<script>
  export default {
    name: "ClickOnMe",
    // component settings
    props: {
      msg: String
    },
    // component attributes
    data() {
      return {
        // button title
        buttonTitle: "Hide",
        // controls whether the message is displayed
        show: true
      };
    },
    // methods
    methods: {
      // show / hide the message
      change() {
        if (this.show) {
          // hide the message
          this.show = false;
          this.buttonTitle = "Show";
        } else {
          // show the message
          this.show = true;
          this.buttonTitle = "Hide";
        }
      }
    }
  };
</script>

Comments

  • lines 4–6: a Bootstrap green alert. The number of columns used is not specified. Therefore, Bootstrap’s 12 columns are used;
  • lines 8–10: a Bootstrap yellow alert:
    • line 8: the [v-if] directive from [Vue.js] controls the visibility of an HTML block. The alert is controlled here by a Boolean [show] (line 29). If [show==true], then the alert will be visible; otherwise, it will not be;
    • line 9: the alert displays a message [msg], which is a property (lines 20–22) of the component;
  • line 12: a blue button that you click to hide/show the [warning] alert;
  • lines 16–48: the component’s JavaScript code. This code controls the component’s dynamic behavior:
  • lines 20–22: the component’s properties;
  • lines 24–31: the component’s attributes;

What is the difference between a component’s [properties] and [attributes], and between the [props] and [data] fields of the object exported by the component in lines 17–47?

  • As we have already seen, a component’s [props] are its parameters. Their values are set from outside the component. A component A using a component B with properties [prop1, prop2, ..., propn] will use it as follows: <B :prop1='val1' :prop2='val2' ...>;
  • The object returned by the [data] function in lines 24–31 represents the component’s state or attributes. This state is manipulated by the component’s methods (lines 33–46). The <template> in lines 1–14 uses both [properties] and [attributes]:
    • property values are set by a parent component;
    • Attribute values are initially set by the [data] function and can then be modified by methods;
    • In both cases, the visual rendering reacts immediately to changes in a property (parent component) or an attribute (component method). This is referred to as a reactive interface;

In a component’s [template], there is no difference between a [prop] and an [data] attribute. To determine whether dynamic data in the [template] should be placed in the [props] attribute or in the object returned by the [data] function, simply ask who sets the value of that data:

  • if the answer is the parent component, then the data goes into the [props] attribute;
  • if the answer is the component’s method handling that event, then the data goes into the object returned by the [data] function;

The [template] uses the following dynamic data here:

  • [show], line 8. This data is handled internally by the [changer] method, which manages the [click] event on the button in line 12. It is therefore an attribute constructed by the [data] function (line 29);
  • [msg], line 9. This is a message set by the parent component. We therefore place it in the [props] attribute (line 21);
  • [buttonTitle], line 12. This data is handled internally by the [changer] method, which manages the [click] event on the button in line 12. It is therefore an attribute created by the [data] function (line 27);
  • The names of the attributes [name, props, data, methods] of the object exported by the component are predefined. You cannot use other names;
  • line 12: the button’s [@click] attribute is used to specify the method that should respond to a click on the button. This method must be located in the component’s [methods] property;
  • line 33: the component’s [methods] attribute contains all of its methods. Most of the time, these are functions that respond to a component event;
  • lines 35–46: the [changer] method is called when the user clicks the button:
    • if the [warning] alert is displayed, it is hidden and the button text changes to [Show] (line 39);
    • if the [warning] alert is hidden, it is displayed and the button text changes to [Hide] (line 43);
    • to show/hide the [warning] alert, we change the value of the boolean [show] (lines 38 and 42);
    • when a method needs to reference the [attr] attribute returned by the [data] function, we write [this.attr] (lines 38 and 42). This means that the attributes of the object returned by the [data] function are direct attributes of the [this] component;

5.4. Running the project

Image

The result is as follows:

Image

Image