Creating your own web-page based Vue.js + Element UI + UB Server #
In this charter we will create a web-page using Vue.js
.
Vue.js and Element UI #
Vue.js (pronounced /vjuː/, like view) is a progressive framework for building UI.
Unlike other popular frameworks, to get started, all you have to do is to drop a single script tag into the HTML file:
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
Now you can start writing Vue
code.
Element UI is a Vue based component library for developers, designers and product managers.
This library has many components, from simple buttons and input fields to carousels and collapses.
Also, present bootstrap-like grid layout system.
To use library import JavaScript and CSS files in your page. JS file must be imported after Vue.
<!-- import CSS -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<!-- import JavaScript -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<script src="https://unpkg.com/element-ui/lib/umd/locale/en.js"></script>
Creating a web-page using Vue.js #
To create a web-page with Vue.js we need to produce steps same as in JQuery lesson:
- Create a
www
subdirectory in the project folder andindex.html
in it - Add the
"inetPub"
property to the"httpServer"
section inubConfig.json
Also, create app.js
and add a link to it after closing body
tag:
...
</body>
<script src="app.js"></script>
...
And the last preparation step - add links to lodash
and UB
modules:
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
<script src="/clientRequire/@unitybase/ub-pub/dist/ub-pub.min.js"></script>
In this point the index.html
should look something like this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>
<!-- import CSS -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<!-- import JavaScript -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<script src="https://unpkg.com/element-ui/lib/umd/locale/en.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
<script src="/clientRequire/@unitybase/ub-pub/dist/ub-pub.min.js"></script>
</head>
<body>
</body>
<script src="app.js"></script>
</html>
Development of the Vue app #
The simplest Vue app #
To build the simplest Vue
app add:
<div id="app">
{{ message }}
</div>
in body
section of index.html
and
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
})
to the app.js
file.
Try to visit http://localhost:8881
to see what the code above produces.
Extending the page view using the Element UI #
We will use element components
(tags that start with el
) to declare all needed parts of page.
Put it inside div
block with app
id.
-
Header menu
<el-menu default-active="1" mode="horizontal" background-color="#545c64" text-color="#fff" active-text-color="#ffd04b"> <el-menu-item index="0"> <a href="https://unitybase.info/" target="_blank"> <img alt="Brand" src="https://unitybase.info/img/logo.svg" height="40px"></a> </el-menu-item> <el-menu-item index="1">Home</el-menu-item> <el-menu-item index="2"> <a href="https://git-pub.intecracy.com/unitybase/samples/tree/master/courses/tutorial-v5" target="_blank">Tutorials</a> </el-menu-item> <el-menu-item index="3" v-if="!isLogIn"> <el-button @click="logInFormVisible = true" type="primary">Log in</el-button> </el-menu-item> <el-menu-item index="3" v-else> <el-button @click="logout" type="primary">Log out</el-button> </el-menu-item> </el-menu>
v-if
directive used to dynamically show or hide element based on condition (user logged or not) -
Log in dialog
<el-dialog title="Log in to City Portal" :visible.sync="logInFormVisible"> <el-dialog width="30%" title="Failed to log in" :visible.sync="failedToLogInDialogVisible" append-to-body> </el-dialog> <el-form size="medium"> <el-form-item label="Login"> <el-input v-model="form.login" placeholder="Login"></el-input> </el-form-item> <el-form-item label="Password"> <el-input type="password" v-model="form.pass" placeholder="Password" @keyup.enter.native="login"></el-input> </el-form-item> <el-button :loading="isLoading" type="primary" @click="login">Continue</el-button> </el-form> </el-dialog>
Dialog visible if variable
logInFormVisible
is true. Also, we declare sub dialog to show it after wrong login credentials. -
Header
<el-row type="flex" class="row-bg" justify="center"> <el-col> <div style="display: flex;justify-content: center"> <h1>{{isLogIn?"Requests":"Welcome to CITY PORTAL!"}}</h1> </div> </el-col> </el-row>
-
Table
<el-table v-show="isLogIn" :data="tableData"> <el-table-column prop="ID" label="ID"> </el-table-column> <el-table-column prop="reqDate" label="Request Date"> </el-table-column> <el-table-column prop="applicantPhone" label="Applicant Phone"> </el-table-column> <el-table-column prop="applicantInfo" label="Applicant Info"> </el-table-column> <el-table-column prop="status" label="Status"> </el-table-column> <el-table-column prop="reqText" label="Request Text"> </el-table-column> <el-table-column prop="answer" label="Answer"> </el-table-column> </el-table>
:data="tableData"
is bind to array of data. If data update, table update automatically.
Extending the page functionality #
Add the following code to app.js
:
// if you reload page after login, this variable is true
const wasLogInBeforeReload = localStorage.getItem(location.origin + '/:storedSession') !== null;
const REQ_ENTITY = 'req_reqList';
const REQ_ATTRS = ['ID', 'reqDate', 'applicantPhone', 'applicantInfo', 'status', 'reqText', 'answer'];
//english localisation to element library
ELEMENT.locale(ELEMENT.lang.en);
let Main = {
data() {
return {
form: {
login: "",
pass: ""
},
logInFormVisible: false,
failedToLogInDialogVisible: false,
isLogIn: wasLogInBeforeReload,
isLoading: false,
tableData: []
}
},
methods: {
login: function () {
this.isLoading = true;
UB.connect({
host: window.location.origin,
allowSessionPersistent: true,
onCredentialRequired: function (conn, isRepeat) {
if (isRepeat) {
return Promise.reject(new UB.UBAbortError('invalid password or username'))
} else {
return Promise.resolve({authSchema: 'UB', login: this.form.login, password: this.form.pass})
}
}.bind(this),
onAuthorizationFail: function (reason) {
this.isLoading = false;
this.failedToLogInDialogVisible = true;
UB.showErrorWindow(reason);
}.bind(this),
}).then(function (conn) {
this.isLoading = false;
this.isLogIn = true;
this.logInFormVisible = false;
window.$conn = conn;
this.getRequests()
}.bind(this))
},
logout: function () {
if (window.$conn) window.$conn
.logout()
.then(function () {
this.isLogIn = false;
this.logInFormVisible = true;
}.bind(this))
},
getRequests: function () {
window.$conn.Repository(REQ_ENTITY).attrs(REQ_ATTRS).select()
.then(function (data) {
this.tableData = data.map(req => {
req.reqDate = req.reqDate.toLocaleDateString('ru-RU');
return req;
});
}.bind(this))
}
},
//this part execute after page load
mounted: function () {
//auto login and show requests after reload logged page
if (wasLogInBeforeReload) {
UB.connect({
host: window.location.origin,
allowSessionPersistent: true,
onAuthorizationFail: function (reason) {
UB.showErrorWindow(reason)
}
}).then(function (conn) {
window.$conn = conn;
this.getRequests();
}.bind(this))
}
}
};
let Ctor = Vue.extend(Main);
new Ctor().$mount('#app');
Now project is available at http://localhost:8881
.