学习Nuxt.js

NuxtJS 让你构建你的下一个 Vue.js 应用程序变得更有信心。这是一个 开源 的框架,让 web 开发变得简单而强大。

在这里插入图片描述
在这里插入图片描述

理解SSR

传统服务端渲染CSR
单页面应用SPA 首屏性能不好 seo不好
服务端渲染SSR(server side render)

npm install  vue-server-renderer@2.6.11 express

在vue的脚手架项目中的vue-template-compiler 也是@2.6.11,上面的安装的版本号要和这里相同

已经存在spa
需要seo页面是否只是少数几个营销页面预渲染是否可以考虑
确实需要做ssr改造,利用服务器端爬虫技术puppeteer
最后选择重构 全新项目建议nuxt.js

npx create-nuxt-app <项目名>

运行项目: npm run dev

layouts/default.vue

nuxt-link像router-link
nuxt 像router-view

<template>
  <div>
    <nuxt-link no-prefetch to="/detail/123">详情</nuxt-link>
    //no-prefetch禁用预加载行为
    <nuxt-link to="/cat">购物猫</nuxt-link>
    <nuxt-link to="/">首页</nuxt-link>
    
    <nuxt />
  </div>
</template>

pages页面下自定义 选用哪个layouts

export default {
  layout:'blank'
}

layouts/blank.vue

<template>
  <nuxt></nuxt>
</template>

pages文件夹下新建.vue文件,自动创建路由,

nuxt的主页,也就是路由的路径为 / 的 就是pages/index.vue

<template>
  <Tutorial/>     //Tutorial组件 在components文件夹下的Tutorial.vue文件  无需导入直接使用Tutorial
</template>

middleware的使用

pages下某个文件使用 就是局部使用

  export default {
        middleware: ['auth']
    }

nuxt.config.js中使用就是 全局配置 对每个

export default {
	router: {
		middleware: ['auth']
	}
}

动态路由

访问localhost:3000/detail/123
pages/detail/_id.vue

<template>
  <div>
      {{$route.params.id}}//这里渲染123
  </div>
</template>
async asyncData({ $axios, params, error }) {// params就是上面的params  
// asyncData出现的比较早 所以 不能访问this
     if (params.id) {
         // asyncData中不能使用this获取组件实例
         // 但是可以通过上下文获取相关数据
         const { data: goodInfo } = await $axios.$get("/api/detail", { params });
         if (goodInfo) {
             return { goodInfo };
         }
         error({ statusCode: 400, message: "商品详情查询失败" });
     } else {
         return { goodInfo: null };
     }
 }

asyncData

asyncData方法会在组件(限于页面组件)每次加载之前被调用。它可以在服务端或路由更新之前被调用。在这个方法被调用的时候,第一个参数被设定为当前页面的上下文对象,你可以利用 asyncData方法来获取数据,Nuxt.js 会将 asyncData 返回的数据融合组件 data 方法返回的数据一并返回给当前组件。

注意:由于asyncData方法是在组件 初始化 前被调用的,所以在方法内是没有办法通过 this 来引用组件的实例对象。

Nuxt.js 提供了几种不同的方法来使用 asyncData 方法,你可以选择自己熟悉的一种来用:

这里我只展示了一种,其他的情况看官网

export default {
  async asyncData({ params }) {
    const { data } = await axios.get(`https://my-api/posts/${params.id}`)
    return { title: data.title }
  }
}

asyncData 方法返回的数据在融合 data 方法返回的数据后,一并返回给模板进行展示,如:

<template>
  <h1>{{ title }}</h1>
</template>

nuxt命令

在这里插入图片描述

路由拦截 路由扩展

  extendRoutes(routes, resolve) {
    routes.push({
      name: 'custom',
      path: '*',
      component: resolve(__dirname, 'pages/404.vue')
    })
  },

插件

plugins/api-inject.js

export default ({ $axios }, inject) => {
    inject('login', user => {
        return $axios.$post('/api/login', user)
    })    
}

nuxt-config.js

 plugins: [
    '@/plugins/element-ui',
    '@/plugins/api-inject',//注册下
 ]

this.$login(u) 就可以访问到api/login接口了

拦截器

plugins/interceptor.js

export default function ({ $axios, store }) {
    $axios.onRequest(config => {
        // 每次请求都会修改令牌的操作
        if (store.state.user.token) {
            config.headers.Authorization = "Bearer " + store.state.user.token;
        }
        return config;
    });
}

nuxt.config.js

 plugins: [   
    "@/plugins/interceptor"
  ],

跨域

nuxt.config.js

  axios: {
    proxy: true
  },
  proxy: {
    "/api": "http://localhost:8080"
  },

store

store/user.js

export const state = () => ({
    token: ''
});
export const mutations = {
    init(state, token) {
        state.token = token;
    }
};
export const getters = {
    isLogin(state) {
        return !!state.token;
    }
};
export const actions = {
    login({ commit, getters }, u) {
        return this.$axios.$post("/api/login", u).then(({ token }) => {
            if (token) {
                commit("init", token)
            }
            return getters.isLogin;
        });
    }
};

在middleware和plugins下的js文件可以访问到user

export default function ({ store }) {
   
   store.state.user.token
    
}

koa一半使用

var Koa = require('koa');
var app = new Koa();
const bodyparser = require('koa-bodyparser')
const router = require('koa-router')({prefix:'/api'})  //通过/api/goods访问接口  

app.keys = ["some secret", "another secret"]

const goods =[
    {id:1,text:'web全栈架构师',price:1000},
    {id:2,text:'java全栈架构师',price:1000},
]

router.get('/goods', ctx => {
    ctx.body = {
        ok: 1,
        goods
    }
})

router.get('/detail',ctx =>{
    ctx.body = {
        ok:1,
        data:goods.find(good => good.id == ctx.query.id)
    }
})

router.post('/login',ctx=>{
    const user = ctx.request.body
    if(user.username === 'jerry' && user.password == '123'){
        const token = 'a mock token'
        ctx.cookies.set('token',token)
        ctx.body = {ok:1,token}
    }else{
        ctx.body = {ok:0}
    }
})


app.use(bodyparser())

app.use(router.routes())

//使用路由中间件
// app.use(router.routes()).use(router.allowedMethods());

app.listen(8080)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值