Learn Vue step by step (viii)
This completes the following scenario.
1、The system contains three modules: home page, customer information inquiry and login
2, default to enter the system home page, if you want to make user queries, you need to login authorization
3、After checking the user, click the list item, then enter the details page
Based on the above scenario requirements description, in the client side we consider that we need to design the following components: Home component, customer list component, customer details component, login component
On the server side consider the need for: user authentication service; customer list query service, customer detail query service.
OK, now let's start by creating our basic directory structure from top to bottom.
The current directory structure is as follows.
app.js node web startup file
node_modules node module files (no more on node module installation here)
public Stores static files such as index.html Browser-side execution of css or js files, images, text, etc. Currently contains two files index.html,app.js (component definition and other files)
router backend routing file, for example, you can abstract the portal section to the routing folder
middleware middleware folder, we will define the forensic middleware
package.json npm package configuration file
Starting with our client design, building our components.
First Home component, Home component, simple potal information display, here for demonstration purposes, just display a string of basic information directly, add the following code in public/app.js.
var HomeComponent = { template: `<div> <h1>Home pages,portal leaf</h1> <h2> The following data is from the server side</h2> {{stat}} </div>`, data:function(){ return { stat:''// Representation of relevant statistical information, etc. } }, methods:{ getStat:function(){ return axios.get('/portal'); } }, created:function(){ this.getStat().then(res=>{ this.stat=JSON.stringify(res.data); }).catch(err=>{ console.log(err); }) } }
Here a new knowledge axios, which is a vue Ajax library, as vue-resource is no longer updated, the official recommendation to use axios; the logic of the above code is simple, in the initialization of the component, requesting back-end data, return after a simple data binding; the corresponding back-end interface (the data is just simulated), add the following code under /app.js.
var express = require("express"); var app = express(); app.use(express.static('public')); app.get('/portal',function(req,res){ res.json({ data:[ { visits:12, clicks:100 }, { location:'BeiJing', total:17 } ] }) }) app.listen(8110,function(){ console.log("port 8110 is listenning!!!"); });
Here is the most basic express code, it just does two things, first, set the static directory to public and set the route/portal, corresponding to the front-end request.
To get the program to work, we modify our /public/index.html code as follows.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>demo3</title> <script src="https://cdn.bootcss.com/vue/2.4.1/vue.js"></script> <script src="https://cdn.bootcss.com/vue-router/2.7.0/vue-router.js"></script> <script src="https://unpkg.com/axios/dist/axios.min.js"></script> </head> <body> <div id="app"> </div> <script src="./app.js"></script> </body> </html>
Set up routing for the component Home in public/app.js and enable the routing configuration at
var router = new VueRouter({ //TODO: Various routing definitions; routes: [{ name: 'home', path: '/home', component: HomeComponent } ] }); var app = new Vue({ router: router, template: ` <div> <router-view></router-view> </div> `, el: '#app' });
Open the console, go to the root of the project, execute node app.js to start the backend service, and open http://localhost:8110/#/home ,in the browser, you can see the following effect.
Next, add our other three components: the customer list component, the details component and the login component to the public/app.js file and configure the routing, with the final code as follows.
var LoginComponent = { template: ` <div class="login" > username:<input type="text" v-model="user.username" /> password:<input type="password" v-model="user.password" /> <input type="button" @click="login()" value="login" /> </div> `, data: function () { return { user: { username: '', password: '' } } }, methods: { login: function () { axios.post('/login',{params: this.user}) .then(function (res) { if (res.success) { localStorage.setItem('token', res.token); } }) .catch(function (error) { console.log(error); }); } } } var CustomerListComponent = { template: ` <div> <div> <input type="text" v-model="keyword" /> <input type="button" @click="getCustomers()" value="search" /> </div> <ul> <router-link v-for="c in customers" tag="li" :to="{name:'detail',params:{id:c.id}}" :key="c.id">{{c.name}}</router-link> </ul> </div> `, data: function () { return { customers: [], keyword: '' } }, created: function () { this.getCustomers(); }, methods: { getCustomers: function () { axios.get('/api/getCustomers', { params: { keyword: this.keyword } }) .then(res => { this.customers = res.data; console.log(res) }) .catch(err => console.log(err)); }, } } var CustomerComponent = { template: ` <div> {{customer}} </div> `, data: function () { return { customer: {} } }, created: function () { var id = this.$route.params.id; this.getCustomerById(id); }, watch: { '$route': function () { console.log(this.$route.params.id); } }, methods: { getCustomerById: function (id) { axios.get('/api/customer/'+id) .then(res => this.customer = res.data) .catch(err => console.log(err)); } } } var HomeComponent = { template: `<div> <h1>Home pages,portal leaf</h1> <h2> The following data is from the server side</h2> {{stat}} </div>`, data: function () { return { stat: ''// Representation of relevant statistical information, etc. } }, methods: { getStat: function () { return axios.get('/portal'); } }, created: function () { this.getStat().then(res => { this.stat = JSON.stringify(res.data); }).catch(err => { console.log(err); }) } } var router = new VueRouter({ //TODO: Various routing definitions; routes: [{ name: 'home', path: '/home', component: HomeComponent }, { name: 'customers', path: '/customers', component: CustomerListComponent, }, { name: 'detail', path: '/detail/:id', component: CustomerComponent, }, { name: 'login', path: '/login', component: LoginComponent } ] }); // Registering global event hooks //TODO: Will be analyzed in detail in the next post // router.beforeEach(function (to, from, next) { // if (to.matched.some(r => r.meta.auth)) { // if (!localStorage.getItem('token')) { // console.log(" Login required"); // next({ // path: '/login', // query: { to: to.fullPath } // }) // } else { // next(); // } // } else { // next() // } // }); var app = new Vue({ router: router, template: ` <div> <router-link :to="{name:'home'}" >Home</router-link> <router-link :to="{name:'customers'}" >Customers</router-link> <router-view></router-view> </div> `, el: '#app' });
Add the following routes in the backend based on the interface, and in the router folder, add the customers.js file with the following code.
var router = require("express").Router(); var db = require('./fakeData'); router.get('/getCustomers', function (req, res) { var list = db.data; list = list.filter(v => v.name.indexOf(req.query.keyword) !== -1); res.json(list); }); router.get('/customer/:id',function(req,res){ var list=db.data; var obj=list.filter(v=>v.id==req.params.id)[0]; res.json(obj); }) module.exports = router;
Also change the code in /app.js to read as follows.
var express = require("express"); var authMiddleware=require('./middleware/authMiddleware'); var customerRouter=require('./router/customers'); var app = express(); app.use(express.static('public')); app.get('/portal',function(req,res){ res.json({ data:[ { visits:12, clicks:100 }, { location:'BeiJing', total:17 } ] }) }) //TOOD: More on that in the next post., Ignore for now. // app.use(authMiddleware); app.use('/api',customerRouter); app.listen(8110,function(){ console.log("port 8110 is listenning!!!"); });
Re-execute node app.js, refresh the browser and see the final result as follows.
The above code for vue, which we have mentioned in the previous few posts, is not in an unfamiliar format, so you can mention COMMENT if you have questions. Authorization will be added in the next post, including front-end routing control as well as back-end interface access control, that's it for today, I've been busy lately and the update progress is a bit slow, next post refine the permissions, todo markup has been added in this part of the code, consider it if you are interested().
The complete code for this piece is as follows.
public/index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>demo3</title> <script src="https://cdn.bootcss.com/vue/2.4.1/vue.js"></script> <script src="https://cdn.bootcss.com/vue-router/2.7.0/vue-router.js"></script> <script src="https://unpkg.com/axios/dist/axios.min.js"></script> </head> <body> <div id="app"> </div> <script src="./app.js"></script> </body> </html>
public/app.js
var LoginComponent = { template: ` <div class="login" > username:<input type="text" v-model="user.username" /> password:<input type="password" v-model="user.password" /> <input type="button" @click="login()" value="login" /> </div> `, data: function () { return { user: { username: '', password: '' } } }, methods: { login: function () { axios.post('/login', this.user) .then(function (res) { if (res.success) { localStorage.setItem('token', res.token); } }) .catch(function (error) { console.log(error); }); } } } var CustomerListComponent = { template: ` <div> <div> <input type="text" v-model="keyword" /> <input type="button" @click="getCustomers()" value="search" /> </div> <ul> <router-link v-for="c in customers" tag="li" :to="{name:'detail',params:{id:c.id}}" :key="c.id">{{c.name}}</router-link> </ul> </div> `, data: function () { return { customers: [], keyword: '' } }, created: function () { this.getCustomers(); }, methods: { getCustomers: function () { axios.get('/api/getCustomers', { params: { keyword: this.keyword } }) .then(res => { this.customers = res.data; console.log(res) }) .catch(err => console.log(err)); }, } } var CustomerComponent = { template: ` <div> {{customer}} </div> `, data: function () { return { customer: {} } }, created: function () { var id = this.$route.params.id; this.getCustomerById(id); }, watch: { '$route': function () { console.log(this.$route.params.id); } }, methods: { getCustomerById: function (id) { axios.get('/api/customer/'+id) .then(res => this.customer = res.data) .catch(err => console.log(err)); } } } var HomeComponent = { template: `<div> <h1>Home pages,portal leaf</h1> <h2> The following data is from the server side</h2> {{stat}} </div>`, data: function () { return { stat: ''// Representation of relevant statistical information, etc. } }, methods: { getStat: function () { return axios.get('/portal'); } }, created: function () { this.getStat().then(res => { this.stat = JSON.stringify(res.data); }).catch(err => { console.log(err); }) } } var router = new VueRouter({ //TODO: Various routing definitions; routes: [{ name: 'home', path: '/home', component: HomeComponent }, { name: 'customers', path: '/customers', component: CustomerListComponent, }, { name: 'detail', path: '/detail/:id', component: CustomerComponent, }, { name: 'login', path: '/login', component: LoginComponent } ] }); // Registering global event hooks //TODO: Will be analyzed in detail in the next post // router.beforeEach(function (to, from, next) { // if (to.matched.some(r => r.meta.auth)) { // if (!localStorage.getItem('token')) { // console.log(" Login required"); // next({ // path: '/login', // query: { to: to.fullPath } // }) // } else { // next(); // } // } else { // next() // } // }); var app = new Vue({ router: router, template: ` <div> <router-link :to="{name:'home'}" >Home</router-link> <router-link :to="{name:'customers'}" >Customers</router-link> <router-view></router-view> </div> `, el: '#app' });
router/customers.js
var router = require("express").Router(); var db = require('./fakeData'); router.get('/getCustomers', function (req, res) { var list = db.data; list = list.filter(v => v.name.indexOf(req.query.keyword) !== -1); res.json(list); }); router.get('/customer/:id',function(req,res){ var list=db.data; var obj=list.filter(v=>v.id==req.params.id)[0]; res.json(obj); }) module.exports = router;
middleware/authMiddleware.js
module.exports=function(req,res,next){ if(req.path="/login"){ res.json({ success:true }) } next(); }
app.js
var express = require("express"); var authMiddleware=require('./middleware/authMiddleware'); var customerRouter=require('./router/customers'); var app = express(); app.use(express.static('public')); app.get('/portal',function(req,res){ res.json({ data:[ { visits:12, clicks:100 }, { location:'BeiJing', total:17 } ] }) }) //TOOD: More on that in the next post., Ignore for now. // app.use(authMiddleware); app.use('/api',customerRouter); app.listen(8110,function(){ console.log("port 8110 is listenning!!!"); });