1. Basic transformation process
1.1 Define Routing Module
src/router/index.js
Configure hospital setup management related routes
{ path: '/hosp', component: Layout, redirect: '/hosp/hospital/list', name: 'hospital', meta: { title: 'hospital management', icon: 'table' }, children: [ { path: 'hospitalSet/list', name: 'Hospital Settings', component: () =>import('@/views/hosp/hospitalSet/list'), meta: { title: 'Hospital Settings' } }, { path: 'hospitalSet/add', name: 'EduTeacherCreate', component: () =>import('@/views/hosp/hospitalSet/form'), meta: { title: 'Add to' }, hidden: true }, { path: 'hospitalSet/edit/:id', name: 'EduTeacherEdit', component: () =>import('@/views/hosp/hospitalSet/form'), meta: { title: 'edit', noCache: true }, hidden: true } ] }
1.2 Define the api module
Create file src/api/hosp/hospitalSet.js
import request from '@/utils/request' const api_name = '/admin/hosp/hospitalSet' export default { getPageList(page, limit, searchObj) { return request({ url: `${api_name}/${page}/${limit}`, method: 'get', params: searchObj }) }
}
1.3 Define page component script
src/views/hosp/hospitalSet/list.vue
<script> import hospitalSetApi from '@/api/hosp/hospitalSet' export default { // Define a data model data() { return { list: null // list } }, // Getting data after successful page rendering created() { this.fetchData() }, methods: { // Load List Data fetchData(page = 1) { console.log('Turn over the page.' + page) // Acquire remote data asynchronously (ajax) this.page = page hospitalSetApi.getPageList(1, 10, null).then( response => { this.list = response.data.records } ) } } } </script>
1.4 Define Page Component Template
<template> <div class="app-container"> <!-- banner list --> <el-table :data="list" stripe style="width: 100%"> <el-table-column type="index" width="50"/> <el-table-column prop="hosname" label="Hospital Name"/> <el-table-column prop="hoscode" label="Hospital Number"/> <el-table-column prop="apiUrl" label="api Base Path"width="200"/> <el-table-column prop="contactsName" label="Contact Name"/> <el-table-column prop="contactsPhone" label="Cell Phone"/> <el-table-column label="state" width="80"> <template slot-scope="scope"> {{ scope.row.status === 1 ? 'available' : 'Not available' }} </template> </el-table-column> </el-table> </div> </template>
1.5 Test Data Communication
Start Project
Command line execution: npm run dev
Open Browser Debugging Status
The test failed, the interface requested, but did not return the result. Why? This is a cross-domain problem.
1.6 Cross-domain Processing
Cross-domain: Browser restrictions on javascript's homology policy.
The following scenarios are cross-domain:
Cross-domain Reason Explanation
Example
Domain name is different www.jd.com and www.taobao.com Same domain name, different ports www.jd.com:8080 and www.jd.com:8081 Second level domain name is different item.jd.com and miaosha.jd.com
If the domain name and port are the same, but the request path are different, they are not cross-domain, for example:
www.jd.com/item
www.jd.com/goods
http and https are also cross-domain
And we just visited localhost:8201 from localhost:3000, which is a different port, cross-domain.
How to solve it?
Spring has already provided us with a solution, and we just need to add a tag to the corresponding controller (@CrossOrigin //Cross Domain).
If we add the cross-domain tag @CrossOrigin to the HospitalSetController class and test again, the test will be successful!
2. Paging Query
2.1 Define page component script
src/views/hosp/hospitalSet/list.vue
<script> //Introducing js files for interface definitions import hospset from '@/api/hospset' export default { //Define variables and initial values data() { return { current:1, //Current Page limit:3, //Number of records per page searchObj:{}, //Conditional Encapsulation Object list:[], //Data collection per page total:0 //Total Records } }, created() { //Execute before page rendering //Call the method defined by methods to get the data this.getList() }, methods: {//Define methods to make requests for interface calls //List of hospital settings getList(page=1) { //Add current page parameters this.current = page hospset.getHospSetList(this.current,this.limit,this.searchObj) .then(response => { //Request success response is interface return data //Return set assignment list this.list = response.data.records //Total Records this.total = response.data.total }) .catch(error => {//request was aborted console.log(error) }) } } } </script>
2.2 Define Page Component Template
Add paging component under table component
<!-- paging --> <el-pagination :current-page="page" :page-size="limit" :total="total" style="padding: 30px 0; text-align: center;" layout="total, prev, pager, next, jumper" @current-change="fetchData" /> 2.3 enquiry form <el-form :inline="true" class="demo-form-inline"> <el-form-item> <el-input v-model="searchObj.hosname" placeholder="Hospital Name"/> </el-form-item> <el-form-item> <el-input v-model="searchObj.hoscode" placeholder="Hospital Number"/> </el-form-item> <el-button type="primary" icon="el-icon-search" @click="getList()">query</el-button> </el-form>
3. Delete
3.1 Define the api module
Add method in src/api/hosp/hospitalSet.js
//Delete hospital settings deleteHospSet(id) { return request ({ url: `/admin/hosp/hospitalSet/${id}`, method: 'delete' }) }
3.2 Define Page Component Template
Add delete columns to the table component
<el-table-column label="operation" width="280" align="center"> <template slot-scope="scope"> <el-button type="danger" size="mini" icon="el-icon-delete" @click="removeDataById(scope.row.id)"> </el-button> </template> </el-table-column>
3.3 Define page component script
//Method of Deleting Hospital Settings removeDataById(id) { this.$confirm('This action will permanently delete the hospital is the setup information, Continue or not?', 'Tips', { confirmButtonText: 'Determine', cancelButtonText: 'cancel', type: 'warning' }).then(() => { //Determine the execution of the then method //Call Interface hospset.deleteHospSet(id) .then(response => { //Tips this.$message({ type: 'success', message: 'Delete succeeded!' }) //Refresh this.getList(1) }) }) }
4. axios response interceptor
4.1 About code===200
if (res.code !== 200) { return Promise.reject('error') }
4.2 About response
code===200 When released, front page receives response.data Instead of response if (res.code !== 200) { return Promise.reject('error') }
4.3 About error
Unify error results and display error messages
5. Bulk Delete
5.1 Define an api module
Add method in src/api/hosp/hospitalSet.js
removeRows(idList) { return request({ url: `${api_name}/batchRemove`, method: 'delete', data: idList }) }
5.2 Define Page Component Template
Add Bulk Delete on table Component
<!-- Toolbar --> <div> <el-button type="danger" size="mini" @click="removeRows()">Bulk Delete</el-button> </div> stay table Add Checkbox on Component <el-table :data="list" stripe style="width: 100%" @selection-change="handleSelectionChange"> <el-table-column type="selection" width="55"/>
5.3 Define page component script
1, Data defines data
multipleSelection: [] // List of records selected in batch selection
2, Define Method
// Triggered when table check box options change handleSelectionChange(selection) { this.multipleSelection = selection },
3, Define the deletion method
//Bulk Delete removeRows() { this.$confirm('This action will permanently delete the hospital is the setup information, Continue or not?', 'Tips', { confirmButtonText: 'Determine', cancelButtonText: 'cancel', type: 'warning' }).then(() => { //Determine the execution of the then method var idList = [] //Traverse the array to get each id value and set it into the idList for(var i=0;i<this.multipleSelection.length;i++) { var obj = this.multipleSelection[i] var id = obj.id idList.push(id) } //Call Interface hospset.batchRemoveHospSet(idList) .then(response => { //Tips this.$message({ type: 'success', message: 'Delete succeeded!' }) //Refresh this.getList(1) }) }) }
6. Locking and Unlocking
6.1 Define an api module
Add method in src/api/hosp/hospitalSet.js
//Lock and unlock lockHospSet(id,status) { return request ({ url: `/admin/hosp/hospitalSet/lockHospitalSet/${id}/${status}`, method: 'put' }) }
6.2 Define Page Component Template
Add a button to the table component
<el-table-column label="operation" width="280" align="center"> <template slot-scope="scope"> <el-button type="danger" size="mini" icon="el-icon-delete" @click="removeDataById(scope.row.id)">delete</el-button> <el-button v-if="scope.row.status==1" type="primary" size="mini" icon="el-icon-delete" @click="lockHostSet(scope.row.id,0)">locking</el-button> <el-button v-if="scope.row.status==0" type="danger" size="mini" icon="el-icon-delete" @click="lockHostSet(scope.row.id,1)">Unlock</el-button> </template> </el-table-column>
6.3 Define page component script
//Lock and unlock lockHostSet(id,status) { hospset.lockHospSet(id,status) .then(response => { //Refresh this.getList() }) },
7. Add Hospital Settings
7.1 Define an api module
Add method in src/api/hosp/hospitalSet.js
//Add hospital settings saveHospSet(hospitalSet) { return request ({ url: `/admin/hosp/hospitalSet/saveHospitalSet`, method: 'post', data: hospitalSet }) }
7.2 Define page component scripts
src/views/hosp/hospitalSet/form.vue, improve data definition
export default { data() { return { hospitalSet:{} } }
7.3 Define Page Component Template
src/views/hosp/hospitalSet/form.vue
<template> <div class="app-container"> Addition of Hospital Settings <el-form label-width="120px"> <el-form-item label="Hospital Name"> <el-input v-model="hospitalSet.hosname"/> </el-form-item> <el-form-item label="Hospital Number"> <el-input v-model="hospitalSet.hoscode"/> </el-form-item> <el-form-item label="api Base Path"> <el-input v-model="hospitalSet.apiUrl"/> </el-form-item> <el-form-item label="Contact Name"> <el-input v-model="hospitalSet.contactsName"/> </el-form-item> <el-form-item label="Cell Phone"> <el-input v-model="hospitalSet.contactsPhone"/> </el-form-item> <el-form-item> <el-button type="primary" @click="saveOrUpdate">Preservation</el-button> </el-form-item> </el-form> </div> </template>
7.4 Implement new functionality
<script> import hospset from '@/api/hospset' export default { data() { return { hospitalSet:{} } }, created() { }, methods: { //Add to saveOrUpdate() { hospset.saveHospSet(this.hospitalSet) .then(response => { //Tips this.$message({ type: 'success', message: 'Added Successfully!' }) //Jump List Page using Routing Jump this.$router.push({path:'/hospSet/list'}) }) } } } </script>
8. Display hospital settings
8.1 Define an api module
Add method in src/api/hosp/hospitalSet.js
//Hospital setup id query getHospSet(id) { return request ({ url: `/admin/hosp/hospitalSet/getHospSet/${id}`, method: 'get' }) },
8.2 Define page component script
Define echo methods in src/views/hosp/hospitalSet/form.vue, methods
//Query by id getHostSet(id) { hospset.getHospSet(id) .then(response => { this.hospitalSet = response.data }) },
Getting data after successful page rendering
Because the following are defined in the route: path:'edit/:id', you can use
this.$route.params.id Get in route id created() {//Execute before page rendering //Get Routing id Value Call Interface Get Hospital Settings Information if(this.$route.params && this.$route.params.id) { const id = this.$route.params.id this.getHostSet(id) } },
8.3 Define Page Component Template
src/views/hosp/hospitalSet/list.vue
<router-link :to="'/hospSet/edit/'+scope.row.id"> <el-button type="primary" size="mini" icon="el-icon-edit"></el-button> </router-link>
9. Update hospital settings
9.1 Define an api module
Add method in src/api/hosp/hospitalSet.js
//Modify hospital settings updateHospSet(hospitalSet) { return request ({ url: `/admin/hosp/hospitalSet/updateHospitalSet`, method: 'post', data: hospitalSet }) }
9.2 Define page component script
src/views/hosp/hospitalSet/form.vue, method defines updateData
//modify update() { hospset.updateHospSet(this.hospitalSet) .then(response => { //Tips this.$message({ type: 'success', message: 'Successful modification!' }) //Jump List Page using Routing Jump this.$router.push({path:'/hospSet/list'}) }) },
Perfect saveOrUpdate method
saveOrUpdate() { //Determine whether to add or modify if(!this.hospitalSet.id) { //No id, add this.save(); } else {//modify this.update() } }
10. Component reuse issues
Problem: When vue-router navigation switches, if both routes render the same component,
The component's life cycle method (created or mounted) is no longer invoked, and the component is reused, showing the build rendered by the previous route
Solution: You can simply add a unique key to the router-view to ensure that the lifecycle method is triggered again when routing switches and that components are reinitialized.
Modify the src/views/layout/components/AppMain.vue file as follows:
<router-view:key="key"></router-view> computed: { key() { returnthis.$route.name !== undefined? this.$route.name + +newDate(): this.$route + +newDate() } }
11. Configure nginx
Since there are many service modules in our backend, each module has its own access path and port, in order to provide a uniform api interface, nginx is used as the reverse proxy server.
Reverse proxy, in fact, the client is not aware of the proxy, because the client does not need any configuration to access, we only need to send the request to the reverse proxy server, the reverse proxy server to select the target server to obtain data, then return to the client, the reverse proxy server and the target server are a server, exposing the generationHandler address, hiding real server IP address
1, download and install nginx (window version)
2, Configure nginx
server { listen 80; server_name localhost; location /api/hosp/ { proxy_pass http://localhost:8201; } location /api/cmn/ { proxy_pass http://localhost:8205; } ... }
3, Adjust BASE_API in/config/dev.env.js
BASE_API: 'http://localhost'
Explain:
1. Follow-up add service module to add nginx configuration without explanation
2. We will follow up with the Spring Cloud Gateway gateway, which will replace the nginx gateway