NUXT.js

Nuxt.js 是一个基于 Vue.js 的通用应用框架。 通过对客户端/服务端基础架构的抽象组织,##Nuxt.js 主要关注的是应用的 UI渲染。

  1. nuxt不仅仅用于服务端渲染也可用于spa应用开发;
  2. 利用nuxt提供的基础项目结构、路由生成、中间件、插件等特性可大幅提高开发效率
  3. nuxt可用于网站静态化
    Nuxt.js官方文档
    https://zh.nuxtjs.org/guide
    nuxt安装
    运行 create-nuxt-app
npx create-nuxt-app <项目名>

选项

image.png

运行项目: npm run dev

目录结构

assets:资源目录 assets 用于组织未编译的静态资源如 LESS 、 SASS 或 JavaScript 。

components:组件目录 components 用于组织应用的 Vue.js 组件。Nuxt.js 不会扩展增强该目 录下 Vue.js 组件,即这些组件不会像⻚面组件那样有 asyncData 方法的特性。

layouts:布局目录 layouts 用于组织应用的布局组件。 middleware:中间件目录用于存放应用的中间件。

pages:⻚面目录 pages 用于组织应用的路由及视图。Nuxt.js 框架读取该目录下所有的 .vue 文件并自动生成对应的路由配置。

plugins:插件目录 plugins 用于组织那些需要在 根vue.js应用 实例化之前需要运行的 Javascript 插件。

static:静态文件目录 static 用于存放应用的静态文件,此类文件不会被 Nuxt.js 调用 Webpack 进行构建编译处理。 服务器启动的时候,该目录下的文件会映射至应用的根路径 / 下。

store:用于组织应用的 Vuex 状态树文件。 Nuxt.js 框架集成了 Vuex 状态树 的相关功能配置, 在 store 目录下创建一个 index.js 文件可激活这些配置。 nuxt.config.js:该文件用于个性化配置Nuxt应用。

路由

路由生成
pages目录中所有 *.vue 文件自动生成应用的路由配置,新建:
pages/admin.vue 商品管理⻚ pages/login.vue 登录⻚
导航
添加路由导航,layouts/default.vue

<nav>
<nuxt-link to="/">首⻚</nuxt-link> <!--别名:n-link,NLink,NuxtLink--> <NLink to="/admin">管理</NLink> <n-link to="/cart">购物⻋</n-link>
</nav>

商品列表,index.vue

  <template>
  <div>
<h2>商品列表</h2> <ul>
      <li v-for="good in goods" :key="good.id" >
        <nuxt-link :to="`/detail/${good.id}`">
          <span>{{good.text}}</span>
<span>¥{{good.price}}</span> </nuxt-link>
</li> </ul>
  </div>
</template>
<script>
export default {
  data() {
return { goods: [
{id:1, text:'Web',price:8999}, {id:2, text:'Python',price:8999},
]} }
};
</script>

动态路由

以下划线作为前缀的 .vue文件 或 目录会被定义为动态路由,如下面文件结构

pages/
--| detail/
----| _id.vue

会生成如下路由配置:

pages/
--| detail/
----| _id.vue
{
    path: "/detail/:id?",
    component: _9c9d895e,
    name: "detail-id"
}

如果detail/里面不存在index.vue,:id将被作为可选参数

嵌套路由

创建内嵌子路由,你需要添加一个 .vue 文件,同时添加一个与该文件同名的目录用来存放子视图组 件。
构造文件结构如下:

pages/
--| detail/
----| _id.vue
--| detail.vue

生成的路由配置如下:

{
  path: '/detail',
  component: 'pages/detail.vue',
  children: [
    {path: ':id?', name: "detail-id"}
  ]
}

测试代码,detail.vue

 
<template>
    <div>
        <h2>detail</h2>
        <nuxt-child></nuxt-child>
    </div>
</template>

配置路由

要扩展 Nuxt.js 创建的路由,可以通过 router.extendRoutes 选项配置。例如添加自定义路由:

 
// nuxt.config.js
export default {
  router: {
    extendRoutes (routes, resolve) {
      routes.push({
        name: "foo",
        path: "/foo",
        component: resolve(__dirname, "pages/custom.vue")
}); }
} }

视图

下图展示了Nuxt.js 如何为指定的路由配置数据和视图


image.png

默认布局
查看 layouts/default.vue

<template>
<nuxt/>
</template>

自定义布局
创建空白布局⻚面 layouts/blank.vue ,用于login.vue

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

⻚面 pages/login.vue 使用自定义布局:

export default {
 layout: 'blank'
}

自定义错误⻚面

创建layouts/error.vue

<template>
  <div class="container">
<h1 v-if="error.statusCode === 404">⻚面不存在</h1> <h1 v-else>应用发生错误异常</h1>
<p>{{error}}</p>
<nuxt-link to="/">首 ⻚</nuxt-link>
  </div>
</template>
<script>
export default {
  props: ['error'],
  layout:'blank'
}
</script>

⻚面

⻚面组件就是 Vue 组件,只不过 Nuxt.js 为这些组件添加了一些特殊的配置项 给首⻚添加标题和meta等,index.vue

export default {
 head() {
return {
title: "课程列表",
// vue-meta利用hid确定要更新meta
meta: [{ name: "description", hid: "description", content: "set page
meta" }],
     link: [{ rel: "favicon", href: "favicon.ico" }],
}; },
};
image.png

异步数据获取

asyncData 方法使得我们可以在设置组件数据之前异步获取或处理数据。
范例:获取商品数据

接口准备

安装依赖: npm i koa-router koa-bodyparser -S
接口文件,server/api.js

整合axios

安装@nuxt/axios模块: npm install @nuxtjs/axios -S

配置:nuxt.config.js

modules: [
   '@nuxtjs/axios',
], axios: {
   proxy: true
},
proxy: {
   "/api": "http://localhost:8080"
},

注意配置重启生效
测试代码:获取商品列表,index.vue

<script>
export default {
  async asyncData({ $axios, error }) {
      const {ok, goods} = await $axios.$get("/api/goods");
      if (ok) {
          return { goods };
      }
// 错误处理
error({ statusCode: 400, message: "数据查询失败" }); },
}
</script>

测试代码:获取商品详情,/index/_id.vue

<template>
 <div>
   <pre v-if="goodInfo">{{goodInfo}}</pre>
 </div>
</template>
<script>
export default {
 async asyncData({ $axios, params, error }) {
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 };
   }
} };
</script>

中间件
中间件会在一个⻚面或一组⻚面渲染之前运行我们定义的函数,常用于权限控制、校验等任务。 范例代码:管理员⻚面保护,创建middleware/auth.js

 
export default function({ route, redirect, store }) { // 上下文中通过store访问vuex中的全局状态
// 通过vuex中令牌存在与否判断是否登录
if (!store.state.user.token) {
    redirect("/login?redirect="+route.path);
  }
}

注册中间件,admin.vue

<script>
   export default {
       middleware: ['auth']
}
//全局注册
</script>
  router: {
 middleware: ['auth']
}

状态管理 vuex

应用根目录下如果存在 store 目录,Nuxt.js将启用vuex状态树。定义各状态树时具名导出state, mutations, getters, actions即可。
范例:用户登录及登录状态保存,创建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;
    });
} };

登录⻚面逻辑,login.vue

 
<template>
  <div>
<h2>用户登录</h2>
<el-input v-model="user.username"></el-input>
<el-input type="password" v-model="user.password"></el-input> <el-button @click="onLogin">登录</el-button>
  </div>
</template>
<script>
export default {
  data() {
    return {
      user: {
        username: "",
        password: ""
 
} };
}, methods: {
    onLogin() {
      this.$store.dispatch("user/login", this.user).then(ok=>{
          if (ok) {
            const redirect = this.$route.query.redirect || '/'
            this.$router.push(redirect);
} });
} }
};
</script>

插件

Nuxt.js会在运行应用之前执行插件函数,需要引入或设置Vue插件、自定义模块和第三方模块时特别有 用。
范例代码:接口注入,利用插件机制将服务接口注入组件实例、store实例中,创建plugins/api-inject.js

范例:添加请求拦截器附加token,创建plugins/interceptor.js

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

注册插件,nuxt.config.js

plugins: [
 "@/plugins/api-inject"
],

范例:添加请求拦截器附加token,创建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"]

nuxtServerInit

通过在store的根模块中定义 nuxtServerInit 方法,Nuxt.js 调用它的时候会将⻚面的上下文对象作 为第2个参数传给它。当我们想将服务端的一些数据传到客户端时,这个方法非常好用。
范例:登录状态初始化,store/index.js

 
export const actions = {
  nuxtServerInit({ commit }, { app }) {
    const token = app.$cookies.get("token");
    if (token) {
      console.log("nuxtServerInit: token:"+token);
      commit("user/init", token);
    }
} };

安装依赖模块:cookie-universal-nuxt npm i -S cookie-universal-nuxt
注册, nuxt.config.js

modules: ["cookie-universal-nuxt"],

nuxtServerInit只能写在store/index.js nuxtServerInit仅在服务端执行

发布部署

服务端渲染应用部署

先进行编译构建,然后再启动 Nuxt 服务

 npm run build
npm start

生成内容在.nuxt/dist中

静态应用部署

Nuxt.js 可依据路由配置将应用静态化,使得我们可以将应用部署至任何一个静态站点主机服务商。

 npm run generate

注意渲染和接口服务器都需要处于启动状态 生成内容再dist中

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,271评论 5 466
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,725评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,252评论 0 328
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,634评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,549评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,985评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,471评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,128评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,257评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,233评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,235评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,940评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,528评论 3 302
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,623评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,858评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,245评论 2 344
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,790评论 2 339