主要看的课程1
初始化
1.创建项目
使用官方推荐的npx来安装:
(npm的5.2.x版本后默认安装了npx)
首先,确保您已经安装了 yarn、npx(默认包含在 npm v5.2+ 中)或 npm (v6.1+)。
使用 npx 进行搭建项目:
npm install -g npx
npx create-nuxt-app <项目名>
或者用yarn :
npm install -g yarn
yarn create nuxt-app <项目名>
2.配置端口和IP
在package.json
文件中和script同级写到
json
"config": {
"nuxt": {
"host": "127.0.0.1",
"port": "3001"
}
},
3.启动项目
cd 项目名
npm run dev
如果遇到Are you interested in participating? (Y/n)
收集信息,n
启动了如下:
可以看到真实数据存在
不像vue客户端来讲只有div而没有数据,是JS注入的,不利于爬虫
4.打包
可以使用npm run build
对当前项目打包,打包完成后.nuxt文件夹下会有dist文件
接着可以使用npm run start
来运行打包好的项目
nuxt生命周期
nuxt生命周期主要分成以下:vue的生命周期跑在客户端(浏览器端),而nuxt的生命周期可能跑在服务端也可能跑在客户端也可能两个都存在。
红色部分是nuxt的生命周期,跑在服务端,黄色部分是vue的生命周期(两个钩子,它既跑在了服务端又抛在了客户端),剩下的绿色也是vue剩余的生命周期(它跑在了客户端)。
"nuxtServerInit"钩子,对Store 的数据的一些初始化操作,进行服务器初始化,有且只会运行一次。
"middleware"钩子,允许定义一些自定义函数,他可以运行在全局同时也可以运行在某些布局页面之前或者某个组件组件渲染之前或者之后。配置方案有3种:配置文件nuxt.config.js中配置、或者页面组件中配置、或者在布局组件中配置。
"validate"给页面或组件的动态参数的有效性请求,当浏览器发出请求时,校验客户端发送的一些数据发到客户端之后是否正确,校验成功进入目标页面,校验失败可能返回404页面了。
"asyncData()" 和 "fetch()"这两个钩子几乎同时运行,进行异步数据的请求。asyncData适合在渲染组件前获取异步数据,他可以选择把数据返回,之后交由组件内部处理。fetch也类似在页面渲染前获取异步数据,可以用来填充vuex状态树。这两个钩子都会在每次页面调用之前被调用,也就是在服务端或者是在切换目标路由之前被调用,数据通过这两个钩子读取达到异载。由于是在组件初始化前被调用,如果通过this去访问两个方法的this,指向的是两个组件的实例对象
"render"就是要准备做服务端渲染了,所以在这之前都要把数据准备好,渲染好的页面通过render返回给浏览器。用户在页面操作请求新的页面时,此时注意,我们将再次跳转到中间件"middleware"钩子而不到达nuxtServerInit然后这样往下走进行render渲染。
不同页面间需要操作相同的数据请求时,只要数据发生了变化,asyncData和fetch重新拿到数据后,render在服务端会重新渲染。注意:render钩子只能定义渲染的一些配置,内部不要写一些逻辑,即使写了也不会执行。
!!!静态部署后,asyncData这个钩子就只会在打包的时候运行一次,后面就再也不会运行了
红色部分的钩子都在服务器端跑,但是输出可能在服务器也可能在浏览器 。并且服务器端的钩子不能访问到浏览器window对象(因为服务端还未渲染), 能拿到服务端对象context,this是undefined ,从绿色mounted客户端钩子开始可以拿到window对象
和this指向组件
。而黄色部分也使访问不到window的。
黄色部分,vue的两个钩子(beforeCreate,created图片有误),既会跑在服务端也会跑在客户端,可以通过this拿到服务端的上下文以及组件自身
绿色部分:剩下的一些vue钩子,例如组件创建前/后、组件更新前/后、组件销毁前/后,这些钩子一般都跑在客户端。需要注意的是,服务端渲染不存在kee-alive,也就是不存在组件缓存,那也就没有扩展的那些钩子,比如:激活activated、失活deactivated。
2.演示
"nuxtServerInit "钩子:在/store/index.js文件中写下面代码 然后 npm run dev
启动项目强制刷新页面、控制台会打印nuxtServerInit钩子的运行打印,store实例信息、context上下文信息、服务端的req res请求响应头等等
js
export const actions = {
nuxtServerInit(store, context) {
// 初始化数据到store当中
console.log('nuxtServerInit', store, context)
}
}
"middleware "钩子:
先在nuxt.config.js中配置路由前的中间件
接下来就是中间件的三种写法(其中第1是路由前置全局守卫,2是页面级别的前置全局守卫,3是路由前置组件独享守卫)
1.在所配置的middleware/auth.js
文件中
js
// 中间件函数可以得到上下文的信息context 或者 {store, route,redirect, params, query, req, res }
/**
* store: 状态管理树实例
* route: 单条路由的信息
* redirect: 后端的跳转
* params: 客户端携带来的一些参数
* query: 请求头
* req 和 res: 响应体
*/
export default (context) => {
// 全局守卫业务
console.log('middleware1 nuxt.config outside') // 第一种定义在服务器的方式,且是外部定义
}
2.在layouts/default.vue
布局页面文件中
js
<template>
</template>
<script>
export default {
// 第二种方法:页面层级中间件的定义
// middleware: 'auth', // 直接指向上面外面的auth
middleware() {
// 也可以定义在页面内部,这样写的auth运行在nuxt之后了
console.log('middleware2.2 layout inside')
}
}
</script>
3.在路由跳转页面pages/index.vue
中写
js
<template>
<Tutorial/>
</template>
<script>
export default {
name: 'IndexPage',
// 中间件第三种定义方式
// middleware: 'auth', // 就像2.1一样直接指向上面外部的auth
middleware() { // 或者也可以定义在页面内部的中间件,定义在页面内部,只有在这个页面被加载的时候会运行在这个页面实例化之前
console.log('middleware 3.2 page inside')
}
}
</script>
这样最终控制台在nuxtServerinit之后,依次执行执行出
middleware1 nuxt.config outside
middleware2.2 layout inside
middleware 3.2 page inside
"validate "钩子:在pages/index.vue
紧跟着写validate可以进行参数的校验,校验通过返回true会放行页面显示成功,否则失败或者404返回其他页面
asyncData()和fetch钩子:在pages/index.vue
页面中书写
黄色的两个钩子接着在pages/index.vue
中写,可以看出浏览器打印了且服务端的控制台也打印了
剩余绿色部分的客户端钩子:接着在pages/index.vue
中写到如下部分,可以看到执行顺序和vue中一样且只打印在哭护短浏览器,而服务端不会打印。
路由
约定式路由
js
<template>
<div class="goods">
<h3>商品</h3>
<!-- 1号页面,下划线文件名表示变量,它指向了动态路由的子名称,接着是传递的参数query -->
<nuxt-link to="/goods/1?a=1&b=2">商品01</nuxt-link>
<nuxt-link to="/goods/2?a=11&b=22">商品02</nuxt-link>
<!-- 路由的别名,路由的名字是目录的名字配上目录下面的文件名_id表示的动态路由 -->
<nuxt-link :to="{name:'goods-id', params:{id:3}, query:{a:111, b:222}}">商品03</nuxt-link>
<nuxt-link to="/goods/comment">评论</nuxt-link>
<!-- 子路由的展示区 -->
<nuxt/>
<!--
路由
约定式
展示区:</nuxt>
声明式跳转:<nuxt-link :to="{name:'product-id', params:{id:3}, query:{a:111, b:222}}">商品03</nuxt-link>
name: 路由名:目录名-其他目录-文件名
params:key 要对等文件名(例如id)
子路由:目录代表子路由,子路由由内部同级的文件,代表是同级一级路由
配置
-->
</div>
</template>
路由展示区
这个规律学过vue-router的应该已经知道了
扩展路由
扩展路由例如 默认首页是 /,但是也可以/index也是指向的首页同一个vue页面,在nuxt.config.js文件中的router配置
js
// middleware运行时配置一个中间件的函数运行他,中间件名叫auth
// 路由每次跳转都会找名叫auth的模块然后运行,看起来像个全局守卫
router: {
middleware: 'auth',
// 扩展路由
extendRoutes(routes, resolve) {
console.log(routes)
routes.push({
name: 'home', // 路由的别名
path: '/index', // 所以/index可以访问到这个路由页面
component: resolve(__dirname, 'pages/index.vue')
})
}
},
组件守卫
可以结合middleware中间件查看
然后就是插件都是全局的,即可以前置也可以后置,在nuxt.config.js中配置插件指向,并在plugins/router.js中写
js
// nuxt.config.js
// Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
plugins: [
'~plugins/router.js'
],
// plugins/router.js
// 插件里面也可以拿到context上下文
export default ({app, redirect, params, query, store}) => {
// app:从context中解析出 vue的app实例
// redirect:服务端跳转函数 √
console.log('插件')
app.router.beforeEach((to, from, next) => {
// 插件是路由前置全局的守卫
// next(true) / next(false) next('/login') ×
console.log('插件配置 全局前置', to)
if(to.name == 'login' || to.name == 'reg') {
next()
} else {
redirect({name: 'login'})
}
})
// 全局后置守卫
app.router.afterEach((to, from) => {
console.log('插件全局后置守卫')
})
}
然后就是页面、组件内部的前置后置守卫:beforeRouteEnter、beforeRouteLeave等
数据交互
安装 axios 或者 proxy
@nuxtjs/axios、@nuxt/proxy
安装命令
npm i @nuxtjs/axios @nuxt/proxy --save
注意,如果报错404之类的,重新配置镜像后分开下载:npm i @nuxtjs/axios --save
和npm i @nuxt/proxy --save
然后在nuxt.config.js中添加相应的模块,只需要添加axios
接着在static/data/list.json
{
"title": "nuxt数据"
}
然后在asyncData()钩子中完成数据点读取,由于上面我们已经添加了axios模块,所以我们可以在钩子函数中获取上下文context的同时获取nuxt本身携带的axios模块。
跨域配置
js
axios: {
proxy: true, // 开启axios跨域
prefix: '/api', // baseURL 地址前缀
},
// 需要跨域时代理转发的api名称以什么前缀开头,并且代理到哪一个服务器的地址
proxy: {
'/api/': {
target: 'http://localhost:3001', //代理转发的地址
changeOrigin: true,
pathRewrite: {
'^api': ''
}
}
},
读取数据
可以在pages/index.vue页面中通过asyncData和fetch钩子获取数据
js
// 由于上面我们已经添加了axios模块,所以我们可以在钩子函数中获取上下文context的同时获取nuxt本身携带的axios模块。
async asyncData({$axios}) {
// 同域资源,读取 static/data/list.json的数据
let res = await $axios({url: '/data/list.json'})
console.log('读取到的静态资源', res.data)
return {
title: res.data.title
}
// 跨域资源服务器资源读取
// 读取跨域数据会报跨域错,在nuxt.config.js中axios配置proxy
let res2 = await $axios({url: 'http://localhost:3001/api/home'})
console.log('res2跨域数据', res2)
},
// 同域资源,读取 static/data/list.json的数据
async fetch({$axios}) {
let res = await $axios({url: '/data/list.json'})
console.log('res', res.data.title)
}
拦截器
配置
在nuxt.config.js中配置拦截器的目录并开启服务端渲染
js
plugins: [
'~plugins/router.js',
{
src: '~/plugins/axios',
ssr: true // 开启服务端渲染
}
],
在 /plugins/axios.js文件中写拦截器
js
export default function({$axios, redirect, route, store}) {
// 基本配置
$axios.defaults.timeout = 10000;
// 请求拦截
$axios.onRequest(config => {
console.log('请求拦截')
// config.headers.token = '加token'
return config
})
// 响应拦截
$axios.onResponse(res => {
console.log('响应拦截')
// if(res.data.err === 2 && route.fullPath !== '/login') {
// redirect('/login?path' + route.fullPath) // 跳转到登录页并拼接当前所在的位置
// }
return res
})
// 错误处理
$axios.onError(error => {
return error
})
}
动画
loading加载动画
首先在nuxt.config.js中配置loading加载,
一是更改系统的loading样式
二是自定义组件
js
// 定义系统默认loading条效果更改,
// 或者自定义指定一loading组件
// loading: {
// color: '#399', height: '3px'
// },
loading: '~/components/Loading.vue',
自定义的样式组件,在/components/Loading.vue
中写,这样切换页面加载有样式
js
<template>
<div v-if="loading">
loding...
</div>
</template>
<script>
export default {
data: () => ({loading: false}),
methods: {
// 组件开始时
start(){
this.loading = true
},
finish(){
this.loading = false
}
},
}
</script>
<style scoped>
</style>
vuex
复习vuex,包括主模块index.js的四大,以及子模块,需要注意的是state写法是函数,另外三个是对象。
例如store/index.js
中写:
js
// 主模块
// state 返回的是一个函数,函数里面是对象,里面的每个角色都必须暴露
export const state = () => ({
bNav: false, // 主模块的值
bLoading: false
})
// mutations 返回的是一个对象
export const mutations = {
M_UPDATE_NAV(state, payload) {
state.bNav = payload
},
M_UPDATE_LOADING(state, payload) {
state.bLoading = payload
}
}
// actions 返回的是一个对象
export const actions = {
nuxtServerInit(store, context) {
// 初始化数据到store当中
console.log('nuxtServerInit', store, context)
}
}
// getters 返回的是一个对象
export const getters = {
getNav(state) {
return state.bNav ? '显示' : '隐藏'
},
}
在某个页面 pages/index.vue
中的请求数据写
js
<template>
<!-- <Tutorial/> -->
<div>
<h3>首页</h3>
<h4>同域资源</h4>
<div>{{title}}</div>
<!-- <h4>跨域资源</h4>
<div>{{data2}}</div> -->
<h4>vuex操作</h4>
<button @click="getStore">编程式操作</button>
<div>index getters:{{getNav}}</div>
<div>index state:{{bNav}}</div>
<div>user state:{{data}}</div>
<div>home state:{{home}}</div>
</div>
</template>
<script>
// 引入vuex的辅助函数
import {mapState, mapActions, mapGetters, mapMutations} from 'vuex'
export default {
name: 'IndexPage',
// 中间件第三种定义方式
// middleware: 'auth', // 就像2.1一样直接指向外部的auth
middleware() { // 或者也可以定义在页面内部的中间件,定义在页面内部,只有在这个页面被加载的时候会运行在这个页面实例化之前
console.log('middleware 3.2 page inside')
},
// 参数有效性的校验
validate(params, query) {
// 校验业务
console.log('validate')
return true // return false
},
// 由于上面我们已经添加了axios模块,所以我们可以在钩子函数中获取上下文context的同时获取nuxt本身携带的axios模块。
async asyncData({$axios}) {
// 同域资源,读取 static/data/list.json的数据
let res = await $axios({url: '/data/list.json'})
console.log('读取到的静态资源', res)
return {
title: res.data.title
}
// 跨域资源服务器资源读取
// 读取跨域数据会报跨域错,在nuxt.config.js中axios配置proxy
let res2 = await $axios({url: 'http://localhost:3001/api/home'})
console.log('res2跨域数据', res2)
return {
data2: res2.data.data2
}
},
// 同域资源,读取 static/data/list.json的数据
async fetch({$axios, store, error}) {
let res2 = await $axios({url: '/data/list.json'})
console.log('res2', res2.data.title)
res2.data && store.commit('home/M_UPDATE_HOME', {err:0, msg: '登陆成功', token:'假token', data:{title:"fetch 789"}})
},
// vuex
// **模块方式:** `store`目录下的每个`.js`文件会被转换成状态树[指定命名的子模块](http://vuex.vuejs.org/en/modules.html),当然(`index`是根模块)
// **Classic(不建议使用):**`store/index.js`返回创建Vuex.Store实例的方法
methods: {
getStore() {
// 编程式访问vuex
// 发出actions请求给user模块
// this.$store.dispatch('user/A_UPDATE_USER', {err:0, msg: '登陆成功', token:'假token', data:{title:"user 模块 actions所传递的新数据"}})
this.A_UPDATE_USER({err:0, msg: '登陆成功', token:'假token', data:{title:"123"}})
// 发出mutations请求给user模块
// this.$store.commit('user/M_UPDATE_USER', {err:0, msg: '登陆成功', token:'假token', data:{title:"组件commit传递过去的数据"}})
// this.M_UPDATE_USER({err:0, msg: '登陆成功', token:'假token', data:{title:"456"}})
},
...mapActions('user', ['A_UPDATE_USER']),
...mapMutations('user', ['M_UPDATE_USER'])
},
// mapGetter在计算属性中
computed: {
xx(){}, // 某些计算属性
// index主模块下的store才有getters
...mapGetters(['getNav']),
...mapState(['bNav']), // 或者直接获取state的bNav数据
...mapState('user', ['data']), // 获取user子模块的data数据
// ...mapState('home', ['data']) // 这样的data就和其余store里面的重了,所以可以写成以下对象的格式
...mapState({home: state => state.home.data})
}
}
</script>
状态持久化和token校验
安装一个包 npm i cookie-universal-nuxt --save
并在nuxt.config.js中配置模块
请求回来的cookie同步存储vuex中,强制刷新的时候重新获取cookie并缓存vuex,包括登录等等页面逻辑回跳,拦截器里面从state中获取携带token
模块
模块方式: store
目录下的每个.js
文件会被转换成状态树指定命名的子模块,当然(index
是根模块)
Classic(不建议使用): store/index.js
返回创建Vuex.Store实例的方法
sass样式
安装npm i node-sass sass-loader --save
如果安装node-sass出错
1.npm重新换个一下淘宝镜像
npm install -g mirror-config-china --registry=http://registry.npm.taobao.org
2.npm安装node-sass
npm install node-sass
3.之前安装的记得卸载掉,如果没有可忽略这一步
npm uninstall node-sass
在/assets/scss/global.scss
中添加全局变量
js
$theme-bg: #399
然后在nuxt.config.js
中添加
js
modules: [
'@nuxtjs-style-resources'
],
styleResources: {
scss: [
'./assets/scss/global.scss'
]
},
即可在其他页面使用全局变量$theme-bg
js
<template>
<div class="comment-detail">
<h3>评论详情普通当前页面sass变量</h3>
<div class="box">box</div>
<!-- 测试全局sass变量 -->
<div class="box2">box2</div>
</div>
</template>
<style lang="scss" scoped>
$bg: #399;
.box{
background: $bg;
}
.box2{
background: $theme-bg;
}
</style>
定义渲染 index.html页面
根目录下新建app.html作为启动页,可以 自定义注入的内容
html
<!DOCTYPE html>
<html lang="en" {{HTML_ATTRS}}>
<head {{HEAD_ATTRS}}>
<!-- <meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title> -->
{{HEAD}}
<!-- 加入个性化的内容 -->
</head>
<body {{BODY_ATTRS}}>
{{APP}}
</body>
</html>
内部资源指向问题
html
<h4>内部资源指向问题</h4>
<!-- 1.相对路径找到一些需要压缩的资源 assets -->
<img src="../assets/img/meal.png">
<!-- 项目根目录~ 别名相对路径-->
<img src="~assets/img/meal.png">
<!-- 2.绝对路径找到无需压缩的资源 static -->
<img src="/img/bg-login.png">
<div class="bgimg">css指向需要压缩的资源</div>
<style scoped>
/*3.css中的图片相对路径*/
.bgimg{
height: 50px;
/* background: url('../assets/img/banner2.png') no-repeat; */
background: url('~assets/img/banner2.png') no-repeat; /* 别名路径 */
}
</style>
外部资源引用
html
<h4>外部资源</h4>
<el-button onclick="alert($)">测试外部js脚本--jquery</el-button>
<!-- 1.可以通过nuxt.config.js中引入一些外部资源,例如添加脚本script,链接资源link -->
<!--
1.1 在nuxt.config.js的script中
script: [
{src: 'https://cdnjs.cloudflare.com/ajax/lib/jquery/3.1.1/jquery.min.js'}
],
1.2 在nuxt.config.js的link中
{rel: 'stylesheet', href: 'https://fonts.googleapis.com/css?family=Roboto'}
-->
<!-- 2.或者在app.html中以script引入<script scr="外部资源"></script> -->
<!-- 3.指定某一个组件的head(){}中,例如pages/user/index.vue中
-->
SEO优化
seo可以在nuxt.config.js中的head的meta中写,或者在页面的head()中书写meta,也可以全局混入。
- nuxt.config.js中写
js
head: {
// 去 package.json中取,没有就用后面的
title: process.env.npm_package_name || 'nuxt-ssr', // 网站的统一标题
htmlAttrs: {
lang: 'en'
},
// 整个页面的描述信息,也可以在某个页面中写!!例如在goods/index.vue中
meta: [
{ charset: 'utf-8' }, // 网站编码形式
// 移动端需要设置网页的视口viewport,移动设备的宽度width=device-width,初始缩放比initial-scale=1
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
// hid 为同一个标识,content是描述信息
{ hid: 'description', name: 'description', content: process.env.npm_package_description || '自定义的描述信息' },
{ name: 'format-detection', content: 'telephone=no' }
],
script: [
// {src: 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js'}
],
// 整个网站名称插入什么,这里是图标
link: [
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' },
{rel: 'stylesheet', href: 'https://fonts.googleapis.com/css?family=Roboto'} // 载入谷歌的字体
]
},
- 在某个页面pages/index.vue页面中写
js
// head选项,页面meta配置
head() {
return {
meta: [
{name: 'keywords', content: this.collectionName}
]
}
}
- 全局混入,定义seo变量使用
js
// 混入 mixins
Vue.mixin({
methods: {
$seo(title, content, payload = []) {
return {
title,
meta: [{
hid: 'description',
name: 'keywords',
content
}].concat(payload)
}
}
}
})
// 在_id.vue组件中使用
// 封装从mixin获取
head() {
return this.$seo(this.data.title, this.data.des, [{}])
}
nuxt-TS项目
使用命令新建nuxt-ts项目
创建命令:npx create-nuxt-app .
选择好之后,运行npm run dev如果报错在ts.config.json中添加"skipLibCheck": true
已有nuxt项目的typescript配置
已有nuxt项目的typescript配置:https://typescript.nuxtjs.org/guide/setup
1.安装yarn install --save @nuxt/typescript-build
在ts.config
2.配置buildModules: [ '@nuxt/typescript-build' // 配置TS ],
3.新建tsconfig.json
{
"compilerOptions": {
"target": "ES2018",
"module": "ESNext",
"moduleResolution": "Node",
"lib": [
"ESNext",
"ESNext.AsyncIterable",
"DOM"
],
"esModuleInterop": true,
"allowJs": true,
"sourceMap": true,
"strict": true,
"noEmit": true,
"baseUrl": ".",
"paths": {
"~/*": [
"./*"
],
"@/*": [
"./*"
]
},
"types": [
"@nuxt/types",
"@nuxt/typescript-build",
"@types/node"
]
},
"exclude": [
"node_modules"
]
}
4.新建vue-sheim.d.ts
ts
declare module "*.vue" {
import Vue from 'vue'
export default Vue
}
5.同新建nust-ts项目一样,需要在tsconfig.json
中添加
"skipLibCheck": true
6.安装和
包,以便以类的方式书写组件
pip install vue-class-component vue-property-decorator --save
7.改装代码,服务端的代码写在装饰器@Component({})中,包括validate、middleware中间件、asyncData()、head()、路由守卫beforeRouteLeave等,其余前端代码写进类中,例如函数、数据
状态管理概装饰器的用法
1.安装npm i vuex-class -S
2.引入
js
import {State, Getter, Action, Mutation} from 'vuex-class'
// 装饰器替换组
...mapState(['navB'])
@State bNav:boolean | undefined // 装饰一个实例属性bNav引用到state.bNav
...mapState({home: state => state.home.data})
@State(state => state.home.data) home ?: Object[]
...mapState('user', ['data'])
@State('user') data!:Object // 外部state.user 做组件内的data使用
...mapGetters(['getNav'])
@Getter getNav!:string // 抓取getters的key,作为组件实例属性使用
...mapActions('user', ['A_UPDATE_USER'])
@Action('user/A_UPDATE_USER') A_UPDATE_USER!:(payload:object) => void
...mapMutations('user', ['M_UPDATE_USER'])
@Action('user/M_UPDATE_USER') M_UPDATE_USER!:(payload:object) => void
// 计算属性定义
get xx():string{
return this.bNav ? '真' : '假'
}
transition全局动画
在进入/离开的过渡中,会有 6 个 class 切换。
v-enter:定义进入过渡的开始状态。在元素被插入之前生效,在元素被插入之后的下一帧移除。
v-enter-active:定义进入过渡生效时的状态。在整个进入过渡的阶段中应用,在元素被插入之前生效,在过渡/动画完成之后移除。这个类可以被用来定义进入过渡的过程时间,延迟和曲线函数。
v-enter-to:2.1.8 版及以上定义进入过渡的结束状态。在元素被插入之后下一帧生效 (与此同时 v-enter 被移除),在过渡/动画完成之后移除。
v-leave:定义离开过渡的开始状态。在离开过渡被触发时立刻生效,下一帧被移除。
v-leave-active:定义离开过渡生效时的状态。在整个离开过渡的阶段中应用,在离开过渡被触发时立刻生效,在过渡/动画完成之后移除。这个类可以被用来定义离开过渡的过程时间,延迟和曲线函数。
v-leave-to:2.1.8 版及以上定义离开过渡的结束状态。在离开过渡被触发之后下一帧生效 (与此同时 v-leave 被删除),在过渡/动画完成之后移除。
对于这些在过渡中切换的类名来说,如果你使用一个没有名字的 <transition>,则 v- 是这些类名的默认前缀。如果你使用了 <transition name="my-transition">,那么 v-enter 会替换为 my-transition-enter。
v-enter-active 和 v-leave-active 可以控制进入/离开过渡的不同的缓和曲线,在下面章节会有个示例说明。
npm安装包报错
解决办法:
js
1、执行:
下载nrm :npm install -g nrm
查看npm下载源:nrm ls
设置下载源:(最好使用npm源或者淘宝源)
例子:`npm config set registry http://registry.npmjs.org` 或者 nrm use npm
查看是否设置成功:npm config get registry
注:
-S 同 --save 表示生产环境
-D 则表示仅在开发环境生效
如果版本问题,建议使用yarn install
安装
npm换yarn
static 和 assets的区别
static是静态资源,不会被打包优化,无损,直接搬迁到打完包的环境下
assets文件夹下的文件则会被webpack优化,有些资源可能转化为base64
nuxtjs静态部署和asyncData(待补充)
在构建静态站点执行命令的时候 可以理解成把项目内所有路由(包括你配置在nuxt.config.js generate 属性内的) 以服务端渲染的方式请求一次并且保存页面.
而asyncData 的作用就是获取一些需要写进静态页结构的信息,或者首屏数据,比如seo信息.其他不需要写进静态页结构里面的都可以通过ajax获取