安装 npx create-nuxt-app 项目名
开发 npm run dev
打包 npm run build
npm run start
nuxt.config.js 文件修改过以后要重新启动项目。
生命周期:运行在服务端的钩子函数:
一、 nuxtServerInit(初始化东西到store中)
二、 middleware(中间件)
中间件:middleware目录下的auth.js中暴露出函数
export default ()=》{}
方式1:在全局配置nuxt.config.js文件中,配置
router:{middleware:‘auth’}
方式2:在布局层级layout运行middleware:'auth'
方式3:在页面层级pages运行 middleware(){console.log(‘middleware pages’); }
三、 validate(校验参数)
运行在pages层级,有return返回值
validate(参数){
console.log('validate pages');
return true;
}
返回true则正常,返回false报错。自动跳转错误页面
四、asyncData和fetch (pages层级)
运行在客户端的生命周期:vue的生命周期函数。 window来访问bom,this指向组件本身。
nuxt约定式路由:展示区:
不用有专门的router.js文件,直接写路由跳转就行。
1.
2.
-
动态路由跳转,在文件夹里面用 _id.vue 的方式来命名文件。
有两种方式来传递参数
① 商品02
②商品03
name是路由名,目录名-文件名
params 代表key,要对等文件名
query 为传递的参数
展示区的层级控制:
pages/一级展示/二级展示
/index.vue 表示会在一级展示区展示
/index.vue 为空文档的话表示会在二级展示区展示, 代表有默认页,不会寻 找其他页面。
扩展路由的配置:nuxt.config.js 中的router对象里,配置扩展路由
extendRoutes(routes,resolve){
routes.push({
name:‘home’,
path:’/index’,
component:resolve(__dirname,‘pages/index.vue’)
})
}
error页面的配置: 在layout层级中创建error.vue文件。
在文件中使用 props:[‘error’]来接收错误信息。
配置全局样式并引入 :在nuxt.config.js 中找到css对象,直接写入路径就可以
css: [ ‘assets/css/transition.css’ ]
设置路由切换动效: 在page页面里配置 transition:‘动画名 ’;
在css中配置 .动画名-enter-active,.动画名-leave-active{}
.动画名-enter,.动画名-leave-active{}
路由守卫:前置和后置
middleware({ store,route,query,params,redirect }){}
前置:
依赖中间件middleware,插件
全局守卫:1.nuxt.config 指向middleware
2. layouts 定义中间件
3.组件独享守卫(在page页面中):middleware
4.在plugins文件下创建router.js配置插件全局守卫:
后置:
1.在page页面使用vue的beforeRouteLeave钩子
2.在plugins文件下创建router.js配置插件全局后置守卫
plugins文件下配置router.js文件(要在nuxt.config.js中 plugin里引入):
export default({app,redirect,store,params.query})=>{
//app就是vue实例
app.router.beforeEach((to,from,next)=>{
// 全局前置守卫,插件
// next(true)/next(false)
// 不能next('/login')
// 路由强制跳转要使用redirect
// console.log('路由插件配置 全局前置守卫',to);
// if(to.path=='/login' || to.path=='/reg'){
// next()
// }else{
// redirect('/login')
// }
next()
})
//全局后置守卫
app.router.afterEach((to,from)=>{
console.log('路由插件全局后置守卫',to);
})
}
数据交互:
安装@nuxtjs/axios、@nuxtjs/proxy :
npm i @nuxtjs/axios @nuxtjs/proxy --save
在nuxt.config.js中的modules中配置 modules: [ ‘@nuxtjs/axios’]即可。
在modules中配置的模块,在引用时需要用$axios的方式。
async asyncData({$axios}){
let res = await $axios({url:'/data/list.json'})
console.log('读取到的同域静态资源',res.data);
return {
title:res.data.title
}
},
async fetch({$axios}){
let res = await $axios({url:'/data/list.json'})
console.log('fetch读取到的同域静态资源',res.data);
},
跨域行为的配置:在nuxt.config.js中:
axios:{
proxy:true ,//开启跨域行为
prefix:''//baseUrl
},
proxy:{
'/api/':{
target:'http://localhost:3001',//代理转发的地址
changeOrigin:true,
pathRewrite:{}
}
},
axios的配置:在plugins文件中创建axios.js文件。
nuxt.config.js中plugins中添加{
src:'~/plugins/axios',
ssr:true //服务端渲染
}
export default({$axios,route,store,redirect})=>{
// 基本配置
$axios.defaults.timeout=10000;
// 请求拦截
$axios.onRequest(config=>{
console.log('请求拦截');
config.headers.token='假token'
return config;
})
// 响应拦截
$axios.onResponse(res=>{
if(res.data.err===2 && route.fullPath !=='/login'){
redirect('/login?path='+route.fullPath)
}
return res
})
// 错误处理
$axios.onError(err=>{
return err
})
}
自定义loading页面:
一、在nuxt.config.js中设置
// loading:{
// color:"#399",
// height:'3px'
// },
二、引入
loading:'~/components/loading.vue',
<!-- -->
<template>
<div v-if="loading">
loading...
</div>
</template>
<script>
export default {
data () {
return {
loading:false
}
},
methods:{
//start 和 finish 方法为nuxt自带,不可改动
start(){
this.loading = true;
},
finish(){
this.loading = false;
}
}
}
</script>
vuex 状态管理(两种方式):
一、模块方式。 store目录下的每个.js文件会被转换为状态树【指定命名的子模块】index是根模块
二、classic 方式(不建议使用): store/index.js 返回创建vuex.store 实例的方法
模块化:home.js
export const state=()=>({
err:1,
data:{}
})
export const mutations ={
M_updata_home(state,payload){
state.err = payload.err;
state.data = payload.data;
}
}
export const actions ={
A_updata_home({commit,state},payload){
commit('M_updata_home',payload)
}
}
import {mapActions,mapGetters,mapState,mapMutations} from 'vuex'
...mapActions('user',['a_update_user']),
...mapMutations('user',['m_update_user']),
...mapMutations(['M_UPDATE_NAV'])
状态持久化 &&token校验
cookie:
npm i cookie-universal-nuxt --save
modules: [
'cookie-universal-nuxt' //引入模块
],
思想:在登录时同步vuex和cookie,强制刷新后, nuxtServerInit 钩子来取出cookies,同步vuex
axios拦截器读取vuex
在登录时同步vuex和cookie:
login(){
this.$axios({
url:''
}).then(res=>{
this.$cookies.set('user',res.data);
this.$store.commit('user/m_update_user',res.data)
})
}
强制刷新后, nuxtServerInit 钩子来取出cookies,同步vuex
export const actions={
nuxtServerInit(store,{app:{$cookies}}){
// console.log(store,context);
let user = $cookies.get('user') ? $cookies.get('user'):{err:2,msg:'未登录'}
store.commit('user/m_update_user',user)
}
}
同步vuex axios拦截器读取vuex
$axios.onRequest(config=>{
console.log('请求拦截');
config.headers.token=store.state.user.token
return config;
})
引入element-ui
创建element-ui.js文件
npm i element-ui -S
// 整体引入
import ElementUI from 'element-ui'
Vue.use(ElementUI);
// 按需引入
// import {button} from 'element-ui'
// Vue.use(button)
nuxt.config.js中配置:
css: [
'element-ui/lib/theme-chalk/index.css'
],
plugins: [
{
src:'~/plugins/element-ui',
ssr:true
}
],
build: {
transpile:[/^element-ui/],
}
nuxt 定义全局方法:(插件形式)
plugins: [
'引入js文件'
],
// 定义全局方法
import Vue from 'vue'
let show =()=> console.log('全局方法show');
Vue.prototype.$show=show;
过滤器的引入:直接在上面的全局方法文件中引入
全局方法.js中引入:
import * as _filters from '../assets/script/filter'
Objext.keys(_filters).forEach(key=>Vue.filter(key,_filters[key]));
全局指令
// 全局指令
import direc1 from '../assets/script/directives/direct1'
import direc2 from '../assets/script/directives/direct2'
Vue.directive('direc1',direc1);
Vue.directive('direc2',direc2);
全局组件
// 全局组件
import UcButton from '../components/global/uc-button.vue'
Vue.component('uc-button',UcButton)
全局头部meta信息的自定义:
head: {
title: process.env.npm_package_name || '统一标题',
htmlAttrs: {
lang: 'en'
},
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: process.env.npm_package_name_description || '自定义的描述信息' }
],
link: [
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
]
},
单个页面设置头部meta:
钩子函数:
head(){
return this.$seo('标题','内容',[{}])
},
// 混入methods,使所有的组件中的methods中都有seo方法
Vue.mixin({
methods:{
$seo(title,content,payload=[]){
return{
title,
meta:[{
hid:'description',
name:'keywords',
content
}].concat(payload)
}
}
}
})
sass的使用
npm i node-sass sass-loader --save
npm install sass-loader@7.3.1 node-sass@4.14.1 --save-dev //安装对应的版本
设置公共scss文件
npm install @nuxtjs/style-resources --save
modules: [
'@nuxtjs/style-resources'
],
styleResources:{
scss:['./assets/scss/global.scss']
}
入口模板app.html
<!DOCTYPE html>
<html {{HTML_ATTRS}}>
<head {{HEAD_ATTRS}}>
{{HEAD}}
</head>
<body {{BODY_ATTRS}}>
{{APP}}
</body>
</html>
引入外部资源:
nuxt.config.js:
script:[
{src:'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js'}
],
link: [
{rel:'stylesheet',href:'https://fonts.googleapis.com/css?family=Roboto'}
]
页面中:
head:{
script:[
{src:'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js'}
],
link: [
{rel:'stylesheet',href:'https://fonts.googleapis.com/css?family=Roboto'}
]
}
部署
nuxt
npm run build 打包
需要复制到服务器的文件
.nuxt
package-lock.json
package.json
nuxt.config.json
static
开发端口的配置:
在package.json中配置
”config“:{
"nuxt":{
"host":"127.0.0.1",
"port":"1818"
}
},