官网:
https://www.nuxtjs.cn/
服务器端渲染:
这是 Nuxt 最受欢迎的模式。利用 SSR(也叫做 “universal” or “isomorphic” 模式),Node.js 服务器将基于 Vue 的组件渲染成 HTML 并传输到客户端,而不是纯 javascript。与传统的 Vue SPA 相比,使用 SSR 将带来巨大的 SEO 提升、更好的用户体验和更多的机会。
因为由开发者独立实现 SSR 将会非常繁琐,Nuxt.js 对此提供了开箱即用的全面支持,并帮你规避常见的陷阱。
生成静态站点:
生成静态站点是现在的一个热门话题(也叫做 JAMStack)。与其换一个框架并花时间去适应它,为什么不一石二鸟呢? (only proverbial )
Nuxt.js 支持基于 Vue 应用程序生成静态站点。这是“两全其美”的,因为你不要服务器,但是仍能获得 SEO 的好处,这是因为 Nuxt 将预先渲染所有页面,并且包括必要的 HTML。此外,你可以轻松地将生成的页面部署到 Netlify 或 GitHub pages 上。
Nuxt.js 是什么?
Nuxt.js 是一个基于 Vue.js 的通用应用框架。
通过对客户端/服务端基础架构的抽象组织,Nuxt.js 主要关注的是应用的 UI 渲染。
我们的目标是创建一个灵活的应用框架,你可以基于它初始化新项目的基础结构代码,或者在已有 Node.js 项目中使用 Nuxt.js。
Nuxt.js 预设了利用 Vue.js 开发服务端渲染的应用所需要的各种配置。
除此之外,我们还提供了一种命令叫:nuxt generate ,为基于 Vue.js 的应用提供生成对应的静态站点的功能。
我们相信这个命令所提供的功能,是向开发集成各种微服务(Microservices)的 Web 应用迈开的新一步。
作为框架,Nuxt.js 为 客户端/服务端 这种典型的应用架构模式提供了许多有用的特性,例如异步数据加载、中间件支持、布局支持等。
Nuxt.js 框架是如何运作的?
Nuxt.js 集成了以下组件/框架,用于开发完整而强大的 Web 应用:
Vue 2
Vue-Router
Vuex (当配置了 Vuex 状态树配置项 时才会引入)
Vue 服务器端渲染 (排除使用 mode: ‘spa’)
Vue-Meta
压缩并 gzip 后,总代码大小为:57kb (如果使用了 Vuex 特性的话为 60kb)。
另外,Nuxt.js 使用 Webpack 和 vue-loader 、 babel-loader 来处理代码的自动化构建工作(如打包、代码分层、压缩等等)。
1.1 什么是服务端渲染
服务端渲染又称SSR (Server Side Render)是在服务端完成页面的内容,而不是在客户端通过AJAX获取数据。
服务器端渲染(SSR)的优势主要在于:更好的 SEO,由于搜索引擎爬虫抓取工具可以直接查看完全渲染的页面。
如果你的应用程序初始展示 loading 菊花图,然后通过 Ajax 获取内容,抓取工具并不会等待异步完成后再进行页面内容的抓取。也就是说,如果 SEO 对你的站点至关重要,而你的页面又是异步获取内容,则你可能需要服务器端渲染(SSR)解决此问题。
另外,使用服务器端渲染,我们可以获得更快的内容到达时间(time-to-content),无需等待所有的 JavaScript 都完成下载并执行,产生更好的用户体验,对于那些内容到达时间(time-to-content)与转化率直接相关的应用程序而言,服务器端渲染(SSR)至关重要。
1.2 什么是NUXT:
Nuxt.js 是一个基于 Vue.js 的轻量级应用框架,可用来创建服务端渲染 (SSR) 应用,也可充当静态站点引擎生成静态站点应用,具有优雅的代码结构分层和热加载等特性。
官网网站:
https://zh.nuxtjs.org/
2.1 下载压缩包
https://github.com/nuxt-community/starter-template/archive/master.zip
资料位置:
2.2解压
将template中的内容复制到 yygh-site
2.3修改package.json
name、description、author(必须修改这里,否则项目无法安装):
{
"name": "yygh-site",
"version": "1.0.0",
"description": "尚医通",
"author": "atguigu",
"private": true,
"scripts": {
"dev": "nuxt",
"build": "nuxt build",
"start": "nuxt start",
"generate": "nuxt generate",
"lint": "eslint --ext .js,.vue --ignore-path .gitignore .",
"precommit": "npm run lint"
},
...
}
2.4修改nuxt.config.js
修改title: ‘{{ name }}’、content: ‘{{escape description }}’
这里的设置最后会显示在页面标题栏和meta数据中:
module.exports = {
/*
** Headers of the page
*/
head: {
title: 'yygh-site',
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: '尚医通' }
],
2.5终端中进入项目目录安装依赖
npm install
2.6 引入element-ui
1、下载element-ui
npm install element-ui
2、在plugins文件夹下创建myPlugin.js文件
3、在myPlugin.js文件引入element-ui:
import Vue from 'vue'
import ElementUI from 'element-ui' //element-ui的全部组件
import 'element-ui/lib/theme-chalk/index.css'//element-ui的css
Vue.use(ElementUI) //使用elementUI
4、在nuxt.config.js文件中使用myPlugin.js
在build下面添加内容:
plugins: [
{ src: '~/plugins/myPlugin.js', ssr: false }
]
添加位置:
2.7 测试运行
npm run dev
访问项目:http://localhost:3000/
3.1 安装axios
执行安装命令
npm install axios
3.2 封装axios
创建utils文件夹,utils下创建request.js
import axios from 'axios'
import { MessageBox, Message } from 'element-ui'
// 创建axios实例
const service = axios.create({
baseURL: 'http://localhost',
timeout: 15000 // 请求超时时间
})
// http request 拦截器
service.interceptors.request.use(
config => {
// token 先不处理,后续使用时在完善
return config
},
err => {
return Promise.reject(err)
})
// http response 拦截器
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
}
},
error => {
return Promise.reject(error.response)
})
export default service
1.1添加静态资源
将静态资源下面的css、images文件夹添加到assets目录,如图:
1.2 定义布局
1.2 .1 修改默认布局
参考静态资源文件首页,我们可以把页头和页尾提取出来,形成布局页。
在layouts目录下修改默认布局文件default.vue,将主内容区域的内容替换成
修改layouts/default.vue文件,全部替换:
1.2 .2 提取头文件
创建layouts/myheader.vue文件:
尚医通 预约挂号统一平台
搜索
帮助中心
登录/注册
1.2 .3 提取尾文件
创建layouts/myfooter.vue文件
1.2 .4 默认布局引入头尾文件
修改layouts/default.vue文件
启动项目:npm run dev
访问项目:http://localhost:3000/
2.1 引入首页静态页面
修改pages/inde.vue文件:全部复制
----
2.2 首页数据分析
1,获取医院等级(根据数据字典编码获取)
2,获取地区(根据数据字典编码获取)
3,医院分页列表
4,根据医院名称关键字搜索医院列表
3.1 医院分页列表
条件带分页的查询并封装医院等级等:
//条件分页查询------前端管理页面的
@Override
public Page findHospList(
Integer page, Integer limit, HospitalQueryVo hospitalQueryVo) {
//分页条件
Pageable pageable = PageRequest.of(page-1,limit);
//模糊查询的条件匹配器
ExampleMatcher exampleMatcher = ExampleMatcher.matching()
.withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING)
.withIgnoreCase(true);
Hospital hospital = new Hospital();
BeanUtils.copyProperties(hospitalQueryVo,hospital);
//Example的泛型和分页的泛型要保持一样
Example example = Example.of(hospital, exampleMatcher);
Page all = hospitalRepository.findAll(example, pageable);
//修改这里,进行远程调用
all.getContent().stream().forEach(item -> {
//获取查询list集合,遍历进行医院等级和省市级的封装
this.setHospitalHosType(item);//远程调用
});
return all;
}
添加controller接口
在.HospitalApiController 类添加方法
@ApiOperation("根据医院名称查询--前端用户页面")
@GetMapping("findByHosName/{hosname}")
public Result findByHosName(@PathVariable String hosname){
List hospitalList = hospitalService.findByHosName(hosname);
return Result.ok(hospitalList);
}
repository添加接口
在HospitalRepository类添加接口:
@Repository
public interface HospitalRepository
extends MongoRepository { //这里为何是String
//判断是否存在数据
Hospital getHospitalByHoscode(String hoscode);
//springdata的规则查询,根据医院名称查询
List findHospitalByHosnameLike(String hosname);
}
在HospitalService类添加接口实现:
//根据医院名称查询--前端用户页面
@Override
public List findByHosName(String hosname) {//根据医院名称模糊查询
//直接是根据一个条件的查询,我们就直接使用springdata的方式实现
List all = hospitalRepository.findHospitalByHosnameLike(hosname);
return all;
}
4.1 封装api请求
创建api文件夹,创建/api/hosp.js
import request from '@/utils/request'
const api_name = `/api/hosp/hospital`
export default {
getPageList(page, limit, searchObj) {
return request({
url: `${api_name}/findHospList/${page}/${limit}`,
method: 'get',
params: searchObj
})
},
getByHosname(hosname) {
return request({
url: `${api_name}/findByHosName/${hosname}`,
method: 'get'
})
}
}
创建/api/dict.js
import request from '@/utils/request'
const api_name = '/admin/cmn/dict'
export default {
findByDictCode(dictCode) {
return request({
url: `${api_name}/findByDictCode/${dictCode}`,
method: 'get'
})
},
findByParentId(parentId) {
return request({
url: `${api_name}/findChildData/${parentId}`,
method: 'get'
})
}
}
4.2 添加组件
修改pages/index.vue组件
测试:
点击三级甲等图标进行查询:
地区查询图标按钮:
报跨越的,前端请求和路径和后端请求路径不一致,检查一下
说明:需要获取医院信息(医院基本信息、预约信息)和科室信息
1.1 后端api接口:
添加controller接口
在HospitalApiController类添加方法
在HospitalServiceImpl类实现接口:
@Autowired
private DepartmentService departmentService;
@Override
public Map item(String hoscode) {
Map result = new HashMap<>();
//医院详情
Hospital hospital = this.setHospitalHosType(this.getByHoscode(hoscode));
result.put("hospital", hospital);
//预约规则
result.put("bookingRule", hospital.getBookingRule());
//不需要重复返回
hospital.setBookingRule(null);
return result;
}
1.2 预约挂号前端
1.2.1封装api请求
在/api/hosp.js文件添加方法,修改成和自己后端接口一样
//根据医院编号查询医院详情
show(hoscode) {
return request({
url: `${api_name}/findHospDetail/${hoscode}`,
method: 'get'
})
},
//查询医院科室列表
findDepartment(hoscode) {
return request({
url: `${api_name}/department/${hoscode}`,
method: 'get'
})
}
创建/pages/hosp/_hoscode.vue组件:复制文档
修改路径hosp:
修改最外层的_hoscode.vue:
创建两个空文件夹detail/notice文件:下面创建文件都叫_hoscode.vue
复制页面组件:
测试: