解读:预渲染:
解决seo的问题:
- 前后端不分离;
- 压力在后端
- 好处:安全
- 前后端分离:
- spa单页面应用【vue-cli本身处理不了seo】
- 压力在客户端
- 预渲染
- 适合一个项目不是所有页面都做seo;
- 压力在客户端
- 问题:在html页面加载之前数据过来渲染后才有html的dom结构,这样也可能存在页面空白的情况;
- 服务端渲染
- 压力在服务器
- 启动了两个服务器,一个是nodejs服务;
- spa单页面应用【vue-cli本身处理不了seo】
一、遇到的问题
1、nuxt初始化失败问题解决方案
使用npm和pnpm初始化都失败
原因:主机连不上DNS服务器
解决方案
Step1:
打开文件夹
Windows:路径:C:\Windows\System32\drivers\etc
Mac: 路径:/etc/hosts
Step2:
使用记事本方式打开 hosts
文件,并在文件里面的最底部加上
185.199.108.133 raw.githubusercontent.com
185.199.108.133:443 raw.githubusercontent.com
如果发现此处保存不了,则可以鼠标右击hosts文件,选择属性,修改文件的权限即可。
Step3:
打开终端窗口,并ping 一下 raw.githubusercontent.com
这个地址
解决了
2、img加载图片出现403报错的解决方案
方法一:使用no-referrer
<meta name="referrer" content="no-referrer" />
方法二:使用images.weserv.nl
把图片路径直接传进去,把原来url
前面的http://
/https://
替换或者直接在图片url前加上https://images.weserv.nl/?url=
如:
https://images.weserv.nl/?url=http://xxx.jpg
3、vant list列表问题
主要需要注意以下几点
- 是否正确设置this.loading=false;。 (因为每次加载函数执行的时候,this.loading 会自动变为 true, 如果不设置为 false 则不会继续加载)。
- 需要给van-list增加 :immediate-check=“false” 属性,不要让他首次加载,然后在 created() {} 里面进行首次加载(这样可以防止首次加载出现多次加载的情况)
- 异步获取到数据后,需要给在元数据的基础上增加数据,可以参考后面的例子代码,注意,要使用 setTimeout(() => {} 并且一定要在 for 循环后立马使用 this.new_loading = false; (这样就不会出现多次加载的情况了)
- 同页面多个下拉加载的问题,可以针对 加载(loading),完成(finished),页数(page),数据(data_list),加载函数(onLoad) 这五个参数进行多重设置,也就是说,让每一个 vant-list 对应一组 加载(loading),完成(finished),页数(page),数据(data_list),加载函数(onLoad) 这五个参数,然后更新的时候分开更新就行。(我就不写这部分代码了)
- 数据加载完成后,要使用 this.finished = true; 。(这样可以防止没有数据了,还在继续做异步请求)
4、tailwind 布局
overflow相关
flex布局相关
- main-axis 主轴,横向
- cross-axis 交叉轴,纵向
用于设置flex items的排列方向
- .flex-row 水平排列
- .flex-col 竖直排列
- .flex-row-reverse 反向水平排列
- .flex-col-reverse 反向竖直排列
用于设置flex如何处理元素排列时超出宽度
- flex-no-wrap 不进行换行 会导致转入下一行
- flex-wrap 换行
- flex-wrap-reverse 反向换行
用于设置flex items沿着交叉轴对齐的方式
- .items-stretch 沿交叉轴展开填满
- .items-start / .items-center / .items-end 沿着交叉轴顶端/中间/低端展开
- .items-baseline 沿着交叉轴以基线展开
用于设置多行的flex容器中,线的位置
- .content-start 沿着交叉轴顶端排列线段
- .content-center 沿着交叉轴中间排列线段
- .content-end 沿着交叉轴底端排列线段
- .content-between 线段之间间距相等
- .content-around 线段两边间距相等
用于设置单个flex item在容器交叉轴上的位置
- .self-auto 继承flex容器align-items设置
- .self-start / .self-center / .self-end 沿着flex容器交叉轴自顶端/中间/底端排列
- .self-stretch 延展
用于设置flex items在主轴上的排列
- .justify-start / .justify-center / .justify-end 沿着主轴左边/中间/右边排列
- .justify-between 每个项目之间的空间相等
- .justify-around 每个项目周围的空间相等
用于设置flex items扩展和收缩
- flex-initial
- flex-1
- flex-auto
- flex-none
TailWindCSS学习总结-flex布局 - 知乎 (zhihu.com)
二、nuxt2文件夹路由
三、nuxt2 生命周期
服务端生命周期
1、nuxtServerInit
2、RouteMiddleware
全局守卫
局部守卫
注释掉nuxt.config.js里面的router配置
3、validate
可用来校验页面参数是否符合要求
4、asyncData
5、fetch
服务端和客户端共有的生命周期
beforeCreate
created
客户端有的生命周期
四、路由
<nuxt-link :to="{ path: '/list', query: { id: 1 }, params: { id: 2 } }">跳转到list页面-path</nuxt-link
注意:这种path写法 params里面的参数传递不到list页面,需要用下面这种name的方式
<nuxt-link :to="{ name: 'list', query: { id: 1 }, params: { id: 2 } }">跳转到list页面-name</nuxt-link>
自定义路由
安装包
npm i @nuxtjs/router
在根目录下新建router.js文件
// router.js
import Vue from 'vue';
import Router from 'vue-router';
import HomePage from './pages/home-page.vue'
import aboutPage from './pages/about-page.vue'
Vue.use(Router);
const routes = [
{ path: '/', component: HomePage },
{ path: '/about', component: aboutPage},
]
export function createRouter () {
return new Router({
mode: 'history',
routes,
})
};
修改nuxt.config.js配置
路由守卫
1、自定义路由 router.js
注意:全局守卫和路由守卫不能获取浏览器本地存储localStorage
全局守卫
路由守卫
页面的守卫
import Vue from 'vue';
import Router from 'vue-router';
import HomePage from './pages/home-page.vue'
import aboutPage from './pages/about-page.vue'
import newsPage from './pages/news-page.vue'
// import { createRouter, createWebHashHistory } from 'vue-router'
Vue.use(Router);
const routes = [
{ name:'home', path: '/', component: HomePage },
{ name:'home', path: '/home', component: HomePage },
{
name: 'news', path: '/news', component: newsPage,
beforeEnter (to, from, next) { // 路由守卫
console.log(localStorage) // 服务端渲染,找不到浏览器的本地存储
next()
}
},
{ name:'about', path: '/about', component: aboutPage}
]
const router = new Router({
mode: 'history',
routes,
});
// 全局路由守卫 前置守卫与后置守卫
// router.beforeEach((to, from, next) => {
// console.log(to, from, next);
// if (to.name == 'home') {
// next('/news')
// } else {
// next()
// }
// })
export function createRouter () {
return router
};
2、nuxt.js的文件夹路由
中间件:middleware
插件:plugins
1、配置文件中配置 plugins
2、新建plugins文件夹和router.js文件
服务端数据持久化处理
服务端不能使用localStorage和cookie的解决方案
安装
npm i --save cookie-universal-nuxt
引入:
使用
this.$cookies.set('token',token) // 服务端数据持久化存储
state.token = this.$cookies.get(token) // 服务端数据持久化存储
// store/index.js
export const state = {
token: 'adfasdfasdfasd'
};
export const mutations = {
setToken (state, token) {
state.token = token;
console.log('token', token)
this.$cookies.set('token',token) // 服务端数据持久化存储
},
getToken (state,token) {
state.token = this.$cookies.get(token) // 服务端数据持久化存储
}
};
export const actions = ()=>({
nuxtServerInit (store, context) {
// 参数一:vuex上下文
// context
store.commit('setToken','123333322')
console.log('nuxtServerInit')
// console.log('context:',context)
}
})
// playment.vue
<template>
<div>正在购买{
{ $store.state.token }}</div>
</template>
<script>
export default {
data() {
return {};
},
middleware({ store, route, redirect, params, query, req, res }) {
// console.log("token11", store.commit); // 服务端数据持久化存储)
// console.log("购买2", store);
store.commit("getToken", "token");
console.log("购买2", store.state.token);
if (!store.state.token) {
redirect("/login");
}
},
// middleware: "auth",
};
</script>
多级路由
五、tdk配置 head
全局
页面
六、全局样式与scss的使用
全局样式配置
sass配置
安装即可使用
七、nuxt3几种代理方式
Nuxt3 代理的最佳实践 - 知乎 (zhihu.com)
文章评论