bekwam courses

Vue.js Computed Fields

February 1, 2019

This article demonstrates computed fields in Vue.js. An Oracle JDBC URL is a formatted string. The user enters values for driver, host, port, and database name. Changing any of these automatically changes the URL.

This video shows the application handling different values. The Thin driver selection sets the host, port, and database name segments of the Oracle URL. The OCI selection specifies only the database name.

HTML

dataBinding.html contains a single div "app" which is the target element of the Vue instance. The HTML loads a stylesheet using a <link> tag and it loads the Javascript files for Vue.js and for this app.

dataBinding.html


<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Data Binding Demo</title>
<link rel="stylesheet" type="text/css" href="dataBinding.css">
</head>
<body>
	<div id="app"></div>
	<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
	<script src="dataBinding.js"></script>
</body>
</html>

Javascript

The app's Javascript is stored alongside the HTML in a file "dataBinding.js". A Vue instance is created with a template that is a fieldset of HTML inputs. The Vue instance has data fields that map to the input controls. There's a computed function which forms the databse URL by concatenating the field values and inserting delimiters and other tokens where needed.

dataBinding.js


const app = new Vue({
    el: '#app',
    template: `
    <div id="wrapper">
    <h2>Data Binding Demo</h2>
    <fieldset>
        <legend>Form an Oracle JDBC URL</legend>
        <div>
            <label for="driver">Driver</label>
            <select v-model="driver" id="driver">
                <option>Thin</option>
                <option>OCI</option>
            </select>
        </div>
        <div>
            <label for="host">Host</label>
            <input v-model="host" type="text" id="host">
        </div>
        <div>
            <label for="port">Port</label>
            <input v-model="port" type="text" id="port">
        </div>
        <div>
            <label for="db" id="db">Database</label>
            <input v-model="db" type="text" id="db">
        </div>
        <hr>
        <div>
            <label for="url" id="url">URL</label>
            <input v-model="url" type="text" id="url" readonly>
        </div>
    </fieldset>
    </div>
`,
    data: {
        driver: 'Thin',
        host: 'localhost',
        port: '1521',
        db: 'SID'
    },
    computed: {
        url() {
            if( this.driver === 'Thin' ) { 
                return "jdbc:oracle:" + this.driver.toLowerCase() + "@" + this.host + ":" + this.port + ":" + this.db
            } else {
                return "jdbc:oracle:" + this.driver.toLowerCase() + ":@" + this.db
            }
        }
    }
})

The Vue data fields are bound to the input controls using the v-model attribute. The URL control has an additional "readonly" HTML attribute since the app won't break apart the URL into its host/port/db values.

CSS

The CSS is plain CSS, not involving any of Vue.js bindings.

dataBinding.css


#wrapper {
    width: 960px;
    margin: 0 auto;
}

fieldset div {
    display:  flex;
    align-items: center;
    padding: 1em;
}

label {
    order: 1;
    width: 10em;
    padding-right: 0.5em;
}

input, select {
    order: 2;
    flex: 1 1 auto;
}

If you're running the Vue plugin in your browser, you can see the runtime structure of the Vue instance. These items will change as you manipulate the UI and can be used to troubleshoot. For instance, if you forget a v-model on one of the inputs, you'll notice that it's absent in the list of fields.

Browser Screenshot with Vue Extension
Vue Extension Showing Runtime Instance

This article showed a use of computed fields as implemented by Vue.js. The computed fields are enabled by data binding which is an important feature of Vue. While certainly feasible to write DOM event listeners by hand that pack and unpack input controls into global variables, this can greatly increase the number of bugs in an application. Without Vue, the app would contain lots of trivial code that could be written differently across the development team. Vue gives you a consistent way to manage data and also to synthesize new data using computed fields.


Headshot of Carl Walker

By Carl Walker

President and Principal Consultant of Bekwam, Inc