Open zhh10 opened 4 years ago
在根目录下新建一个文件
app.html
,就是nuxt的默认模版<!DOCTYPE html> <html lang="en"> <head> {{ HEAD }} // 这个head会在nuxt.config.js中定义了 </head> <body> <p>zhh10 github</p> {{ APP }} // 引入page文件夹下的文件 </body> </html>
修改默认模版后要重启一下服务器
在layouts/default.vue
中,默认布局无法设置head
<template>
<div>
<ul>
<li>首页</li>
<li>直播</li>
<li>点播</li>
</ul>
<Nuxt />
</div>
</template>
<style>
ul::after{
display:block;
content:'';
clear:both;
}
li{
list-style:none;
float:left;
margin:10px 10px;
}
</style>
推荐使用nuxt-link
<nuxt-link :to="{name:'index'}">home</nuxt-link>
<nuxt-link :to="{name:'about'}">about</nuxt-link>
<nuxt-link :to="{name:'news'}">news</nuxt-link>
嵌套路由
news文件夹下再建立一个newsItem文件
<nuxt-link :to="{name:news-newsItem}">newsItem</nuxt-link>
**动态嵌套路由**
- page
- news
- index
- newsItem (记得在父级使用`<nuxt-child></nuxt-child>`)
- newsItem/
- _id.vue
- index.vue(默认`nuxt-child`内容)
**参数传递**
全局配置
在assets/css里面配置(跳转得用
nuxt-link
).page-enter-active,.page-leave-active{ transition: opacity 2s; } .page-enter,.page-leave-to{ opacity:0; } .page-leave,.page-enter-to{ opacity:1; }
单独设置 在css文件中设置
.test-enter-active,.test-leave-active{ transition:all 2s; font-size:12px; } .test-enter,.test-leave-to{ opacity:0; font-size:40px; }
vue文件中设置
export default { transition:'test' }
error.vue
通过error.vue设置错误页面
<template> <div> <div v-if="error.statusCode===404"> 404页面,你需要的页面没有找到! </div> <div v-else> 500页面 </div> </div> </template> <script> export default{ props:['error'], } </script>
个性head
export default{
validate(params){
return /^\d+$/.test(params.id)
},
// 通过head方法,设置页面的独特head
head(){
return{
title:`直播间${this.$route.params.id}`,
meta:[
{hid:'description',name:'Live',content:'This is a LiveItem'},
]
}
}
}
nuxt.config.js
router:{
middleware:'auth',
}
middleware/auth.js
export default (context)=>{
// context 服务端上下文
// store route redirect params query req res
// 全局守卫业务
console.log('nuxt.config.js middleware')
}
layouts/default.vue
export default {
// middleware:'auth'
middleware(){
console.log('layout middleware')
}
//运行在nuxt.config.js之后
}
Live.vue
export default {
// middleware:'auth',
// 函数形式 只有加载这个页面时,才会运行这个中间件
// 运行在页面实例化之前
middleware(){
console.log('Live middleware')
}
}
上面操作打印顺序为:
middleware/auth.js
export default({store,route,redirect,params,query,req,res})=>{
// store vuex状态信息
// route 目标路由信息
// redirect 强制跳转
// params,query 校验参数合理性
redirect('/login')
}
middleware方法
plugins: 在运行Vue.js应用程序之前执行的JS插件
nuxt.config.js
plugins:['~/plugins/router']
plugins/router.js
export default ({app,redirect})=>{
// app == Vue实例
app.router.beforeEach((to,from)=>{
// 可以使用next('/login')
// 也可以使用redirect('/login')
if(to.name === 'login' || to.name === 'reg'){
next()
}else{
redirect({name:'login'})
}
})
}
reg.vue
这个时候可以访问windows对象了,因为浏览器已经把它渲染出来了
export default {
beforeRouteLeave(to,form,next){
let bl = window.confirm('是否要离开')
next(bl)
})
}
export default ({app,redirect} => {
app.router.afterEach((to,from)=>{
console.log(to.name,from.name)
})
})
<nuxt-link to="/" active-class="app_header--active">首页</nuxt-link>
<nuxt-link to="/goods" active-class="app_header--active">首页</nuxt-link>
.app_header--active{
background:#399;
color:#fff;
}
严格匹配
<nuxt-link exact-active-class="...." ></nuxt-link>
nuxt.config.js
router:{
middleware:'auth',
// 扩展路由
extendRoutes(routes,resolve){
routes.push({
name:'home',
path:'/index',
component:resolve(__dirname,'pages/index.vue')
})
}
}
layout/error.vue
<template>
<div>
<h1 v-if="error.statusCode">
{{error.message}}
</h1>
</div>
</template>
<script>
export default {
props:['error']
}
</script>
npm i @nuxtjs/axios @nuxtjs/proxy
modules:[
'@nuxtjs/axios',
'@nuxtjs/proxy'
]
添加进来的模块会以$开头
async asyncData({$axios}){
let res = await $axios.get(url:'...')
return {
title:res.data.title
}
},
async fetch({store,$axios}){
let res = await $axios.get(url:'...')
}
配置nuxt.config.js
modules:[
'@nuxtjs/axios',
'@nuxtjs/proxy'
],
axios:{
proxy:true,//开启axios跨域
prefix:'/api',//baseUrl
},
proxy:{
'/api':{
target:'http://localhost:3001',//代理转发地址
changeOrigin:true,
}
}
async asyncData({$axios}){
let res = await $axios.get({url:'/api/home'})
}
nuxt.config.js
plugins:[
{ src:'~plugins/axios',
ssr:true
}
]
plugins/axios
export default function({$axios,redirect,route,store}){
// 基本配置
$axios.default.timeout = 1000
// 请求拦截
$axios.onRequest(config => {
console.log('请求拦截')
config.headers.token = '...'
return config
})
// 响应拦截
$axios.onResponse(res => {
if(res.data.err === 2 && route.fullPath !== '/login'){
redirect('/login?path='+route.fullPath)
}
return res.data
})
// 错误处理
$axios.onError(error => {
return error
})
}
loading:{
color:'#399',
height:'3px',//滚动条高度
}
loading:'~/components/loading.vue'
components/loading.vue
<template>
<div v-if="loading">
...loading
</div>
</template>
<script>
export default {
data:()=>{
loading:false
},
methods:{
// 这两个方法名是nuxt约定好的,不能更改
start(){
this.loading = true
},
finish(){
this.loading = false
}
},
}
</script>
store/index.js
actions:{
nuxtServerInit({commit},{req}){
if(req.session.user){
commit('user',req.session.user)
}
}
}
nuxt.config.js
module.exports = {
router:{
middleware:'auth',
}
}
auth.js
export default (context)=>{
// context 服务端上下文
// store route redirect params query req res
// 全局守卫业务
}
export default {
// middleware:'auth'
middleware(){
console.log('middleware')
} //运行在nuxt.config.js之后
}
index.vue
export default {
// middleware:'auth',
// 函数形式 只有加载这个页面时,才会运行这个中间件
// 运行在页面实例化之前
middleware(){
}
}
定义在页面组件
validate({params,query}){
}
读数据,返回给组件
async(){
return {b:2}
}
读取服务断数据提交给vuex
fetch({store}){
}
服务端的钩子都可以拿到服务端的上下文context
在客户端可以访问window,和组件对象this
服务端的this是undefined
安装插件
npm i cookie-universal-nuxt --save
nuxt.config.js
modules:[
"@nuxtjs/axios",
"cookie-universal-nuxt"
]
上下文就多出了一个$cookie
思想:登录时,同步vuex && cookie,强制刷新后,nuxtServerInit钩子,取出cookies,同步vuex,axios拦截器读取vuex
login(){
this.$axios({
url:'/api/login',
method:'post',
data:{
username:'xxx',
password:123
}
}).then(res => {
this.$cookies.set('user',res.data)
this.$store.commit('user/User',res.data)
this.$router.push('/')
})
}
export const actions = {
nuxtServerInit({store,$cookies}){
let user = $cookies.get('user') ? $cookies.get('user') : {err:'未登录'}
store.commit('user/User',user)
}
}
/plugins/axios
export default function({$axios,redirect,route,store,$cookies}){
config.header.token = store.state.user.token
retunr config
}
nuxt.config.js
plugins:['~/plugins/mixins']
plugins/mixins
import Vue from "vue"
let show = ()=>{console.log(123)}
Vue.prototype.$show = show
// 服务端钩子内部不可使用,this不会执行vue实例
export function filter(n){
return n<10 ? '0' + n : ''+n
}
export const data = time => {
let d = new Date()
d.setTime(time)
let year = d.getFullYear()
let month = d.getMonth() + 1
let hour = d.getHours()
let min = d.getMinutes()
let sec = d.getSeconds()
return .....
}
Vue.filter
import * as filters from './assets/scripts/filter.js'
Object.keys(filters).forEach(key => {
Vue.filter(key,filters[key]
})
function direc1(el,binding,vnode){
console.log(123)
}
export default {
inserted(el,binding,vnode){
direc1(el,binding,vnode)
}
}
import direc1 from "./assets/scripts/direc1"
Vue.directive('direc1',direc1)
import UCButton from "../components/global/ucbutton.vue"
Vue.component('UCButton',UCButton)
nuxt.config.js
css:['assets/css/base.css']
Vue.mixin({
methods:{
$seo(title,content,payload = []){
return {
title,
meta:[{
hid:'description',
name:'keywords',
content
}].concat(payload)
}
}
}
})
head(){
this.$seo(......)
}
安装完就可以在vue中写scss了
npm i node-sass sass-loader
若想设置全局scss文件
npm i @nuxtjs/style-resources --save
指定全局scss文件
modules:['@nuxtjs/style-resource'],
styleResource:{
'scss':['./assets/scss/global.scss']
}
打包
nuxt generate
生成一个dist文件夹
npm install -g live-server
live-server
需要注意的是,在任何 Vue 组件的生命周期内, 只有 beforeCreate 和 created 这两个方法会在 客户端和服务端被调用。其他生命周期函数仅在客户端被调用。
store 目录下的每个 .js 文件会被转换成为状态树指定命名的子模块
使用状态树模块化的方式,store/index.js 不需要返回 Vuex.Store 实例,而应该直接将 state、mutations 和 actions 暴露出来:
export const state = ()=>({
count:0
})
export const mutations = {
add(state){
console.log(123)
state.count ++
}
}
<p>{{$store.state.dian.count}}</p>
import {mapMutations} from "vuex"
export default {
methods:{
...mapMutations({'add':'dian/add'}),
handleClick(){
console.log(this.$store.state)
this.add()
}
}
1. Nuxt安装及结构目录
Nuxt.js是一个基于Vue.JS的通用应用框架
安装vue-cli
初始化
启动
目录结构和配置文件
常用配置
~
是一个别名,~assets
意思是在根目录下找到assets文件夹