Shang Yi Tong - Front End Build - Transform Template 02

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

Tags: Javascript Vue.js Front-end Ajax

Posted by shibbi3 on Mon, 27 Sep 2021 22:07:30 +0530