NUXT front-end server-side rendering technology framework

Server side rendering, also known as SSR (Server Side Render), completes the content of the page on the server side instead of obtaining data through AJAX on the client side.
Advantages: Better SEO, since search engine crawlers can view fully rendered pages directly

Nuxt.js is a lightweight application framework based on Vue.js. It can be used to create server-side rendering (SSR) applications, and can also act as a static site engine to generate static site applications.
https://zh.nuxtjs.org/

NUXT environment initialization

①. Download the compressed package
https://github.com/nuxt-community/starter-template/archive/master.zip

②、Decompression
Assign the content in the template to the module yygh-site

③. Modify package.json (dependency file) and nuxt.config.js

④. Open the yygh-site module terminal (right-click)

Command to download dependencies: npm install
Command to download element-ui: npm install element-ui

Create the myPlugin.js file in the plugins folder and introduce element-ui

Add plugins to nuxt.config.js

⑤. Test run

Command to run: npm run dev

Visit the project: http://localhost:3000

NUXT directory structure

①. Resource directory assets
Used to organize uncompiled static resources such as LESS/SASS or JavaScript

②. Component directory components
Vue.js components used to organize applications. Nuxt.js will not extend or enhance the Vue.js components in this directory, that is, these components will not have the asyncData method features like pages.

③. Layout directory layouts
Layout components used to organize applications, such as extracting the header and footer to form a layout page
Modify the default layout file default.vue and replace the content of the main content area with

<template>
<div class="app-container">
<div id="main">
<!--Public header-->
<myheader/>
\t\t\t
<div class="main-container">
<el-scrollbar class='page-component__scroll'>
<!--Content area-->
<nuxt/>
</el-scrollbar>
</div>
\t\t\t
<!--Public bottom-->
<myfooter/>
</div>
</div>
</template>
<script>
import '~/asserts/css/app.css'
import '~/asserts/css/chunk.css'
import '~/asserts/css/iconfont.css'
import '~/asserts/css/main.css'

//Introduce header files and tail files
import myheader from './myheader'
import myfooter from './myfooter'
export default{<!-- -->
components:{<!-- -->
myheader,myfooter //Use header files and tail files through tags
}
}
</script>

Create the header file layouts/myheader.vue

<template>
<div class="header-container">
<div class="wrapper">
<!--logo-->
<div class="left-wrapper v-link selected">
<img style="width:50px" width="50" height="50" src=""/>
<span class="text">Shangyitong Unified Appointment and Registration Platform</span>
</div>
<!--Search box-->
<div class="search-wrapper">
<div class="hospital-search animation-show">
<el-autocomplete class="search-inout small"
prefix-icon="el-icon-search"
v-model="state"
:fetch-suggestions="qerySearchAsync"
placeholder="Click to enter the hospital name"
@select="handleSelect">
<span slot="suffix" class="search-btn v-link high">
</el-autocomplete>
</div>
</div>
</div>
</div>
</template>
<script>
export default{<!-- -->
}
</script>

Create the tail file layouts/myfooter.vue

<template>
<div class="footer-container">
<div class="wrapper">
<div>
<span class="record">Beijing ICP No. 13018369</span>
<span class="phone">Telephone registration 010-56253825</span>
</div>
<div class=right>
<span class="v-link clickable">Contact us</span>
<span class="v-link clickable">Partners</span>
<span class="v-link clickable">User Agreement</span>
<span class="v-link clickable">Privacy Agreement</span>
</div>
</div>
</div>
</template>
<script>
export default{<!-- -->
}
</script>

④. Page directory pages
Routes and views used to organize applications.
The Nuxt.js framework reads all .vue files in this directory and automatically generates the corresponding routing configuration.

Introduce the homepage static page pages/index.vue

<template>
<div class="homepage-component">
<el-carousel indicator-position="outside">
<el-carousel-item v-for="item in 2" :key="item">
<img src="~asserts/images/web-banner.png" alt="">
</el-carousel-item>
</el-carousel>
</div>
</template>

⑤. Plug-in directory plugins
Used to organize Javascript plug-ins that need to be run before the root vue.js application is instantiated.

⑥. nuxt.config.js file
The nuxt.config.js file is used to organize the personalized configuration of the Nuxt.js application to override the default configuration.

Packaging axios

①.Install axios

Execute the installation command: npm install axios

②. Encapsulate axios for ajax requests

Create the utils folder under the module, and create request.js under the utils folder.

import axios from 'axios'
import {<!-- -->MessageBox,Message} from 'element-ui'

//Create axios instance
const service = axios.create({<!-- -->
baseURL:'http://localhost',
timeout:15000 //Request timeout
})
//http request interceptor
service.interceptors.request.use(
config => {<!-- -->
//The token will not be processed first and will be improved when used later.
return config
},
err => {<!-- -->
return Promise.reject(err)
}
)

//http response interceptor
service.interceptors.response.use(
response => {<!-- -->
if(response.data.code != 200){<!-- -->
Message({<!-- -->
message:response.data.message,
type:'error',
duration:5*1000
})
return Promise.reject(response.data)
}else{<!-- -->
return response.data
}
\t\t
}
)

NUXT route jump

1. Fixed routing

<!--Bind an event in the display page-->
<div @click="show(item.hoscode)">

<script>
methods:{<!-- -->
show(hoscode){<!-- -->
window.location.href = '/hosp' //By default, jump to index.vue under hosp in the pages directory
}
}
</script>

2. Dynamic routing (the path of each jump is different)

Dynamic route creation page rules: Create a vue file from under the folder, vue file naming convention: _parameter name.vue

<!--Bind an event in the display page-->
<div @click="show(item.hoscode)">

<script>
methods:{<!-- -->
show(hoscode){<!-- -->
window.location.href = '/hosp' + hoscode //The number is different each time
}
}
</script>

=============================================

The front-end page calls the back-end interface

1. Create an api/hosp.js and dict.js

hosp.js

import request from '@/utils/request'

const api_name='/api/hosp/hospital' //corresponds to the path on the backend Controller class

export default{<!-- -->
//Query hospital list
getPageList(page,limit,searchObj){<!-- -->
return request({<!-- -->
url:'${api_name}/findHospList/${page}/${limit}' ,//Corresponding Controller internal method path
method:get,
params:searchObj
})
},

//Fuzzy query based on hospital name
getByHosname(hosname){<!-- -->
return request({<!-- -->
url:'${api_name}/findByHosName/${hosname}' ,//Corresponding Controller internal method path
method:'get'
})
}
}

dict.js

import request from '@/utils/request'

const api_name='/admin/cmn/dict' //corresponds to the path on the backend Controller class

export default{<!-- -->
//Get lower-level nodes based on dictCode
findByDictCode(dictCode){<!-- -->
return request({<!-- -->
url:'${api_name}/findByDictCode/${dictCode}' ,//Corresponding Controller internal method path
method:'get'
})
},

//Get the district and county based on id
findByParentId(parentId){<!-- -->
return request({<!-- -->
url:'${api_name}/findChildData/${parentId}' ,//Corresponding Controller internal method path
method:'get'
})
}
}

2. pages/index.vue calls the api and displays

<script>
import hospApi from '@/api/hosp'
import dictApi from '@/api/dict'
\t
export default{<!-- -->
//Server-side rendering is asynchronous and displays the hospital list
asyncData({<!-- -->params,error}){<!-- -->
return hospApi.getPageList(1,10,null)
.then(response => {<!-- -->
return {<!-- -->
list:response.data.content,
pages:response.data.totalPages
}
})
},

data(){<!-- -->
return {<!-- -->
searchObj:{<!-- -->},
page:1,
limit:10,
\t\t\t\t
hostname:'',//Hospital name
hostypeList:[],//Hospital level collection
districtList:[],//District collection

hostypeActiveIndex:0,
provinceActiveIndex:0
}
},

created(){<!-- -->
this.init()
},

methods:{<!-- -->
//Query the hospital level list and all region lists
init(){<!-- -->
dictApi.findByDictCode('Hostype')
.then(response => {<!-- -->
//Clear hostypeList
this.hostypeList = []
this.hostypeList.push({<!-- -->"name":"All","value":""})

//Add the data returned by the interface to hostypeList
for(var i = 0;i < response.data.length;i + + ){<!-- -->
this.hostypeList.push(response.data[i])
}
})
dictApi.findByDictCode('BeiJing')
.then(response => {<!-- -->
this.districtList = []
this.districtList.push({<!-- -->"name":"All","value":""})
for(let i in response.data){<!-- -->
this.districtList.push(response.data[i])
}
})
},

//Query hospital list
getList(){<!-- -->
hospApi.getPageList(this.page,this.limit,this.searchObj)
.then(response => {<!-- -->
for(lei i in response.data.coutent){<!-- -->
this.list.push(response.data.content[i])
}
this.page = response.data.totalPages
})
}

//Click method in page display
//Query based on hospital level
hostypeSelect(hostype,index){<!-- -->
//Prepare data
this.list = []
this.page = 1
this.hostypeActiveIndex = index
this.searchObj.hostype = hostype
//Call the above method to query the hospital list
this.getList()
}
}
}
</script>

3. Index.vue displays data

<!--Traverse and display hospital level names-->
<span v-for="(item,index) in hostypeList" :key="index" class="item v-link clickable"
@click="hostypeSelect(item.value,index)">
{<!-- -->{item.name}}
</span>

<!--Traverse the display area-->
<span v-for="(item,index) in districtList" :key="index" class="item v-link clickable">
{<!-- -->{item.name}}
</span>


<!--Since the image is stored in data through base64, it needs to be processed when displayed-->
<image :src="'data:image/jpeg;base64,' + item.logoData" :alt="item.hosname" class="hospital-img">