简介
1、服务渲染
服务端渲染技术NUXT,即数据的操作过程在服务端实现,客户端只负责做显示,利于 SEO
服务端渲染又称 SSR (Server Side Render)是在服务端完成页面的内容,而不是在客户端通过AJAX获取数据。即原来是客户端发送 ajax请求,然后服务端得到数据,返回并做渲染,即异步,但异步不利于做 SEO,当爬虫抓取的时候,抓取工具并不会等待异步完成后再进行页面内容的抓取,又因为是异步,所以内容可能还没有渲染成功,会造成网站排名靠后。
服务器端渲染(SSR)的优势主要在于:更好的 SEO,由于搜索引擎爬虫抓取工具可以直接查看完全渲染的页面。
2、nuxt
Nuxt.js 是一个基于 Vue.js的轻量级应用框架,可用来创建服务端渲染 (SSR) 应用,也可充当静态站点引擎生成静态站点应用,具有优雅的代码结构分层和热加载等特性
3、下载使用
3.1、下载
https://github.com/nuxt-community/starter-template/archive/master.zip
3.2、使用
- 解压出来,然后在前端项目文件夹下面新建文件夹,然后将压缩后的 template文件夹下的所有内容放进新建的文件夹
- 打开项目,找到这个文件夹下的 package.json文件,修改 name、description、author
- 找到 nuxt.config.js,修改 title、meta->content
- 右键该 nuxt项目->在集成终端中打开,输入 npm install
- 再下载一个 element-ui, npm install element-ui
- 在 plugins文件夹下创建 myPlugin.js文件,并加入内容,用于引用 element-ui
import Vue from 'vue'
//element-ui的全部组件
import ElementUI from 'element-ui'
//element-ui的css
import 'element-ui/lib/theme-chalk/index.css'
//使用elementUI
Vue.use(ElementUI)
- 在 nuxt.config.js的 build{}的下面加入内容
plugins: [
{ src: '~/plugins/myPlugin.js', ssr: false }
]
- 测试运行,npm run dev,访问项目:http://localhost:3000/
4、nuxt的目录结构
- .nuxt:相关的编译后文件
- assets:放一些静态资源,比如:css、js、图片
- components:vue支持的相关组件
- middleware、static、store:放相关的静态资源
- plugins:放依赖的插件
4.1、layouts
页面布局,比如上部固定样式,下部固定样式等,中间的内容引用 pages的页面
4.2、pages
页面内容
5、封装 axios
- 下载 axios,npm install axios
- 在 nuxt项目下新建文件夹 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
nuxt技术点
1、nuxt的路由跳转
nuxt有两种路由跳转方式:固定路由、动态路由
1.1、固定路由
是什么路径,就跳转到什么页面,即路径对应固定的页面,
会默认寻找 pages文件夹下的对应文件夹的默认文件(index.vue)
//找到 pages/hospital/index.vue页面
window.location.href = '/hospital'
1.2、动态路由
在路径中添加参数,不同的参数会显示不同的内容
会寻找 pages文件夹下对应文件夹的 参数名称.vue,即有一个命名规范:参数名称.vue
动态路由相当于 vue那样的 router/index.js的情况,但 nuxt中没有 router/index.js,所以可用动态路由来路径传参
//找到 pages/hospital/_hoscode.vue页面
window.location.href = '/hospital/' + hoscode
2、监听全局事件
页面 B想调用页面 A的方法
2.1、A引入 Vue
import Vue from 'vue'
2.2、A添加 mounted方法
即页面渲染之后执行的方法
mounted() {
// 注册全局登录事件对象
window.loginEvent = new Vue();
// 监听登录事件
loginEvent.$on('loginDialogEvent', function () {
document.getElementById("loginDialog").click();
})
}
2.3、B添加 js-cookie
import cookie from 'js-cookie'
2.4、B调用方法
schedule(depcode) {
// 登录判断
let token = cookie.get('token')
if (!token) {
loginEvent.$emit('loginDialogEvent')
return
}
window.location.href = '/hospital/schedule?hoscode=' + this.hospital.hoscode + "&depcode="+ depcode
},
简单使用
1、实例1
1.1、实现首页
1.1.1、添加静态资源
将 css、images放入 assets文件夹下
1.1.2、修改 layouts/default.vue
<template>
<div class="app-container">
<div id="main">
<!-- 公共头 -->
<myheader />
<div class="main-container">
<el-scrollbar class="page-component__scroll">
<!-- 内容区域 -->
<nuxt />
</el-scrollbar>
</div>
<!-- 公共底 -->
<myfooter />
</div>
</div>
</template>
<script>
import "~/assets/css/app.css"
import "~/assets/css/chunk.css"
import "~/assets/css/iconfont.css"
import "~/assets/css/main.css"
export default {}
</script>
1.1.3、提取头文件
创建 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="~assets/images/logo.png">
<span class="text">互联网医院平台</span>
</div>
<!-- 搜索框 -->
<div class="search-wrapper">
<div class="hospital-search animation-show">
<el-autocomplete class="search-input small" prefix-icon="el-icon-search"
v-model="state" :fetch-suggestions="querySearchAsync"
placeholder="点击输入医院名称" @select="handleSelect">
<span slot="suffix" class="search-btn v-link highlight clickable selected">搜索 </span>
</el-autocomplete>
</div>
</div>
<!-- 右侧 -->
<div class="right-wrapper">
<span class="v-link clickable">帮助中心</span>
<!-- <el-dropdown >-->
<!-- <span class="el-dropdown-link">-->
<!-- 晴天<i class="el-icon-arrow-down el-icon--right"></i>-->
<!-- </span>-->
<!-- <el-dropdown-menu class="user-name-wrapper" slot="dropdown">-->
<!-- <el-dropdown-item>挂号订单</el-dropdown-item>-->
<!-- <el-dropdown-item>就诊人管理</el-dropdown-item>-->
<!-- <el-dropdown-item divided>退出登录</el-dropdown-item>-->
<!-- </el-dropdown-menu>-->
<!-- </el-dropdown>-->
<span class="v-link clickable" @click="dialogUserFormVisible = true">登录/注册</span>
</div>
</div>
</div>
</template>
<script>
export default {}
</script>
1.1.4、提取尾文件
创建 layouts/myfooter.vue文件
<template>
<div class="footer-container">
<div class="wrapper">
<div>
<span class="record">京ICP备13018369号</span>
<span class="phone">电话挂号010-56253825</span>
</div>
<div class="right">
<span class="v-link clickable"> 联系我们 </span>
<span class="v-link clickable"> 合作伙伴 </span>
<span class="v-link clickable"> 用户协议 </span>
<span class="v-link clickable"> 隐私协议 </span>
</div>
</div>
</div>
</template>
<script>
export default {}
</script>
1.1.5、默认布局引入头尾文件
修改 layouts/default.vue文件,将两个页面作为组件引入进去,使得页面中可用标签进行使用
<script>
import "~/assets/css/app.css"
import "~/assets/css/chunk.css"
import "~/assets/css/iconfont.css"
import "~/assets/css/main.css"
import myheader from './myheader'
import myfooter from './myfooter'
export default {
components: {
myheader,myfooter
}
}
</script>
1.1.6、修改首页
修改 pages/inde.vue文件,然后重启即可
1.2、开发过程
1.2.1、创建 api文件
创建 js文件,用于引用对应 controller的接口方法
import request from '@/utils/request'
const api_name = `/admin/cmn/dict`
export default {
//根据 dictCode获取子节点
findByDictCode(dictCode){
return request({
url: `${api_name}/findByDictCode/${dictCode}`,
method: 'get'
})
},
}
1.2.2、修改 index.vue
在里面定义方法和组件,最后进行首页展示,主要是服务端的异步渲染
export default {
//服务端渲染异步,显示医院列表
//很多代码做了封装,不需要去 data中定义数据,可直接在 return 中定义
//params用于得到路径中的数据,error用于得到异常信息
asyncData({ params, error }) {
//调用
return hospital.findByConditionWithPage(1,10,null)
.then(response => {
return {
hospitalList: response.data.content,
totalPages: response.data.totalPages
}
})
},
}
版权归原作者 nwonknU_ 所有, 如有侵权,请联系我们删除。