0
点赞
收藏
分享

微信扫一扫

#私藏项目实操分享#Nuxt

贵州谢高低 2022-02-17 阅读 127

nuxt

是基于 VUE 的 ssr 服务端渲染的框架

CSR(客服端选取)

当用户发送请求返回页面时,此时只是一个模板页面,浏览器解析代码通过 JS 根据接口去请求数据,得到数据后根据模板来进行渲染。

优点

减轻服务器端压力达到前后端分离开发

SSR(服务器端渲染)

SPA(单页应用)不利于搜索引擎的 SEO 操作,特别是百度根本没法抓取到 SPA 的内容页面
服务器端渲染有哪些好处:

  • 更好的 SEO,由于搜索引擎爬虫抓取工具可以直接查看完全渲染的页面
  • 对于缓慢的网络或运行缓慢的设备,可以提供网页速度,有良好的用户体验。
  • ssr 会减少对服务器的请求,普通的页面先获取文件,再读取内容。读取到 ajax 的 js 的时候,再向服务器发送请求,获取内容。这就是至少两次对服务器的请求了。 如果是 ssr,直接就是再服务器端渲染为完整的页面,发送到浏览器

优点:

  • 基于 Vue.js
  • 自动代码分成
  • 服务端渲染
  • 强大的路由功能,支持异步数据
  • 静态文件服务
  • 打包和压缩 JS 和 CSS
  • HTML 头部标签管理
  • 本地支持热加载
  • 集成 ESLint
  • 支持各种样式预处理器:SASS、LESS、Stylus 等等

基础

目录结构

名称

解释

assets

未编译的静态资源(LESS、SASS、JavaScript)

static

存放应用的静态文件,不会被webpack构建编译,服务器启动的时候,该目录下的文件会映射至应用的根路径 / 下

components

组织应用的 Vue.js 组件,但Nuxt不会拓展该目录下的组件

layouts

组织应用的布局组件

middleware

应用的中间件

pages

组织应用的路由及视图,根据该目录下的.vue文件自动生成对于的路由配置

plugins

组织需要在 根vue.js应用 实例化之前需要运行的 Javascript 插件。

store

组织应用的 Vuex 状态树 文件

nuxt.config.js

Nuxt.js 应用的个性化配置,以便覆盖默认配置。

配置

  1. 设置端口号和 ip

在 package.json 中添加:

"config":{
"nuxt":{
"host":"xxx",
"port":"xxx"
}
}

在 nuxt.config.js 中修改:

  1. 全局引入css

其中​​~​​ 匹配根目录

css:['~assets/css/normailze.css']
  1. 打包

在 build 中:

build:{
loaders:[{
test:/\.(png|jpe?g|gif|svg)$/,
loader:"url-loader",
query:{
limit:10000,
name:'img/[name].[hash].[ext]'
}
}]
}

流程图

服务器请求到渲染的过程:

#私藏项目实操分享#Nuxt_vue

  • nuxtServerInit:在这里可以做一些,如果后续还要请求会从中间件中继续开始
  • middleware:运行自定义的函数,可以运行在全局、某个布局或组件应用之前,可以在如图上的三种文件中配置,文件名的名称将成为中间件名称 (middleware/auth.js将成为 auth 中间件)
  • 中间件执行流程顺序:
  1. uxt.config.js
  1. 配布局
  2. 配页面
  • BOM对象和this 不能在服务器端的钩子函数中调用
  • 服务端通过 context 上下文信息去抓取内容,而不使用this,因为 this 指向的是 undefined
  • beforecreate 和 created 是运行在客户端和服务端的

路由

  • Nuxt.js 依据 pages 目录结构自动生成 vue-router 模块的路由配置。
  • 建议使用 ​​<nuxt-link>​​ 标签。
  • 定义带参数的​​动态​​路由,需要创建对应的以​​下划线​​作为前缀的 Vue 文件 或 目录。
  • 设置为​​必选​​的路由,需要在 ​​下划线​​作为前缀的目录内创建一个 index.vue 文件。
  • 可以在动态路由组件中定义​​参数校验​​方法。
  • ​嵌套​​路由(父组件[.vue]文件,子组件同名目录)在父组件内增加 ​​<nuxt-child/>​​ 用于显示子视图内容。
  • 展示区层级,当定义在pages下的路由都为一级路由,二级路由如果想要在一级显示,就将 pages 下的删掉,写入同名文件夹的 index 中

路由守卫

  1. 前置
  • 依赖中间件 middleware,插件
  • 全局守卫:nuxt.config 指向 middleware

layouts 定义中间件

  • 组件独享守卫:middleware
  • 插件全局前置守卫(router.beforeEach)
  1. 后置
  • 使用 vue 的 beforeRouteLeave 钩子
  • 插件全局后置守卫(router.afterEach)

过渡和动画

  • 使用​​<transition>​​组件来实现路由切换时的过渡动效
  • 默认使用的过渡效果名称为 page
/* 全局 */
.page-enter-active,
.page-leave-active {
transition: opacity 0.5s;
}
.page-enter,
.page-leave-active {
opacity: 0;
}
/* 页面 */
/* 将页面组件中的 transition 属性的值设置为 test
export default {
transition: 'test'
}
*/
.test-enter-active,
.test-leave-active {
transition: opacity 0.5s;
}
.test-enter,
.test-leave-active {
opacity: 0;
}

视图

默认模板和默认布局

  • 在根目录中创建的html页面默认会被认为是默认模板或者是在 src 文件夹下创建 app.html,在默认模板中可以使用​​{{大写}}​​来引入,需要重新启动服务器
  • 在 layouts/default 中 ,不需要重启服务器,记得在布局文件中添加 <nuxt/> 组件用于显示页面的主体内容。
  • 也可以在页面中使用 ​​layout​​属性来使用自定义布局

页面

页面组件实际上是 Vue 组件,只不过 Nuxt.js 为这些组件添加了一些特殊的配置项(对应 Nuxt.js 提供的功能特性)以便你能快速开发通用应用。

  • 自定义错误页面:layouts/error.vue 文件来定制化错误页面,不需要包含 <nuxt/> 标签
export default {
// 运行在页面层级 可以指向外部auth 也可以自己定义
// middleware:'auth',
middleware(){
console.log('页面层级middleware');
},
// 参数的有效性
validate({req,res}){
// 检验业务
console.log('校验参数');
return true;
// 返回失败会去error页面
},
// 读取数据返回给组件
asyncData() {
console.log('asyncData执行啦');
// 异步业务逻辑,读取服务器端的数据
return {
msg:'word'
}
},
// 读取数据返回给 vuex
fetch({store}) {
console.log('fetch执行啦');
// 异步业务逻辑,读取服务器端的数据提交给vuex
store.commit('setMsg', 'word');
}
// 设置头部信息
head () {},
}

属性名

描述

asyncData

最重要的一个键, 支持 异步数据处理,另外该方法的第一个参数为当前页面组件的 上下文对象。

fetch

与 asyncData 方法类似,用于在渲染页面之前获取数据填充应用的状态树(store)。不同的是 fetch 方法不会设置组件的数据。详情请参考 关于 fetch 方法的文档。

head

配置当前页面的 Meta 标签, 详情参考 页面头部配置 API。

layout

指定当前页面使用的布局(layouts 根目录下的布局文件)。详情请参考 关于 布局 的文档。

loading

如果设置为false,则阻止页面自动调用this.$nuxt.$loading.finish()和this.$nuxt.$loading.start(),您可以手动控制它,请看例子,仅适用于在 nuxt.config.js 中设置loading的情况下。请参考API 配置 loading 文档。

transition

指定页面切换的过渡动效, 详情请参考 页面过渡动效。

scrollToTop

布尔值,默认: false。 用于判定渲染页面前是否需要将当前页面滚动至顶部。这个配置用于 嵌套路由的应用场景。

validate

校验方法用于校验 动态路由的参数。

middleware

指定页面的中间件,中间件会在页面渲染之前被调用, 请参考 路由中间件。

数据交互与跨域

数据交互

  • npm 安装这两个依赖:@nuxtjs/axios、@nuxtjs/proxy
  • 添加到项目的 nuxt.config 的 modules 中
  • 添加完成后服务的获取的上下文中就会多出一个 ​​$axios​​,通过 $axios 就可以进行数据的交互

跨域

  • 在 nuxt.config 中配置 axios 和 proxy
axios: {
// 开启跨域
proxy: true,
// 添加需要跨域的 baseUrl
prefix: '/api'
},
proxy: {
'/api':{
// 代理转发的地址
target:'http://10.10.35.19:3000',
changeOrigin:true,
pathRewirte:{
// '^api':''
}
}
},

使用vuex

  1. 模块方式

​store​​ 目录下的每个 ​​.js​​ 文件会被转换成状态树,index 是根模块

  1. classic 方式 (不推荐)

​store/index.js​​ 返回创建 Vuex.Store 实例的方法

  1. state 必须是函数,mutation、 actions 可以是对象

装饰器

  1. 安装依赖:vuex-class
  1. 可以从其中拿到 state、getter、action、mutation等
// 装饰一个实例属性 msg 引用到 state.msg
// 类似于 在计算属性中:...mapState(['msg'])
@State msg:boolean | undefined;
// 抓取 state 里面的数据
// ...mapState({home:state=>state.home.data})
@State(state=>state.home.data) home?:object[];
// 外部 state.user 做组件内部的 data 使用
// ...mapState('user',['data'])
@State('user') data!:object;
// 抓取 getters 的 key,作为组件实例属性使用
// ...mapGetter(['getNav'])
// 属性一致可以省略 没有参数可以省略括号
@Getter getNav!:string
// ...mapActions('user',['A_UPDATE_USER'])
@Action('user/A_UPDATE_USER') A_UPDATE_USER!:(payload:object)=>void
// ...mapMutations('user',['M_UPDATE_USER'])
@Mutation('user/A_UPDATE_USER') M_UPDATE_USER!:(payload:object)=>void

全局拦截器、token 携带

  • 可以通过编写插件的形式进行全局拦截器的编写
  • 可以进行请求拦截、响应拦截、错误拦截、对axios进行基本配置等
  • token携带:在拦截的时候对请求进行拦截并在头部添加
export default ({ $axios, store, redirect, route }) => {
// 基本配置
$axios.defaults.timeout = 10000;
// 请求拦截
$axios.onRequest(config=>{
console.log('请求拦截处理');
config.headers.token = '添加token'
return config
})
// 响应拦截
$axios.onResponse(res=>{
// 像 token 过期等 根据服务器端返回的错误码进行处理
if(res.data.error === 2 && route.pullPath !== '/') {
redirect('/?path =' + route.fullPath)
}
return res
})
// 错误处理
$axios.onError(error=>{
// 处理
// ...
// 返回
return error
})
};

状态持久化和 token 校验

  • 安装模块: cookie-universal-nuxt --save
  • 持久化:在登陆时,同步 vuex 和 cookie,用户在强制刷新后,请求发送到服务端 触发 nuxtServerInit 钩子,在里面取出 cookies,然后去同步 vuex,在 axios 拦截器中读取 vuex
// 登陆后 服务端返回
this.$axios({}).then(res=>{
// 同步 vuex 和 cookie
this.$cookies.set(‘user’,res.data)
this.$store.commit('user/M_UPDATE_USER',res.data)
})


举报

相关推荐

0 条评论