Nuxt.js的那些事儿(一)

在这段时间中了解到VueSSR框架( Nuxt.js ),自己体验了一下,还挺不错的,自己找了一个(知乎招聘)官网模仿了一下,在下面的内容,我将记录自己基于express+nuxt.js+less+axios怎么去开发,因为是自己的练手项目,不足的地方还是很多,希望大家多多包涵,多多提建议改进,我已经将项目源码放置在 github☞

开始

搭建项目

最初还是根据官网安装 create-nuxt-app ,因为我是熟悉express,在选择的时候我还是采用的express

项目结构

这是我的项目结构我都有在里面写好 README.md

注明是什么?主要还是要说几个

-- components (组件文件,建议不要修改名称)
-- layouts    (布局文件默认是default.vue,不能修改名称)
-- pages      (页面文件,主要是用来生成路由,不能修改名称)
-- plugins    (插件,建议不要修改)
-- server     (node服务端渲染)
-- static     (静态文件)
-- store      (vuex,不能修改名称)
-- middleware (中间件)
复制代码

我会在下面的内容主要说着几个文件的作用

文件作用

components

这个很好理解就是放组件的地方,熟悉vue的都知道,我这里就不累赘了。

layouts

这个是页面的布局,在此之前你要须了解什么是视图 【传送门】 他的作用主要是类似于一个模板的最顶层,当你某些页面需要同一个组件,在没有使用layouts你可能需要用到的地方都引用你需要的组件或者是写在父子路由,但是如果你使用layouts话,你只需要在

-- layouts
---- blog.vue
复制代码

layouts > blog.vue 文件引用你需要的组件,在你需要的页面使用这个布局

<template>
<!-- Your template -->
</template>
<script>
export default {
  layout: 'blog'
}
</script>
复制代码

注意的地方的是你的布局只能写在最外层,什么是最外层,学习路由你就知道了

pages

这个文件也是我们开发vue中常见的页面文件夹,但是不同的是因为nuxt.js是没有路由文件的,他的路由文件是通过page夹的文件层级生成出来的,来个简单的例子

-- pages
---- index.vue
---- test.vue
---- name
------ index.vue
------ age.vue
复制代码

类似这样的目录结构生成出来的路由为

/          指向的pages文件夹下面的index.vue文件
/test      指向的pages文件夹下面的test.vue文件
/name      指向的pages文件夹下面的index.vue文件
/name/age  指向的pages文件夹下面的age.vue文件
复制代码

细心的你会发现 index.vue 这个文件命名其实的用处很大的,如果你是想访问/name这个路由路径有两种办法创建文件一种是

-- pages
---- name.vue
复制代码

或者是

-- pages
---- name
------ index.vue
复制代码

第二种他是可以拓展你的路由路径,在name文件夹下面的文件除了index.vue其他都会编译为他的children

说明

如果你想做路由匹配,这块也是可以做到的。如404页面

-- pages
---- _.vue
------ index.vue
复制代码

或者是你路径匹配才能进入页面,你可以这么做

-- pages
---- order
------ index.vue
------ _status.vue
复制代码

这样你需要访问 /order/你需要的参数 ,你就可以进入pages>order>_status.vue,如果你需要做验证,可以借助 validate 这个函数进行验证

validate({ params }) {
    // 必须是number类型
    return /^\d+$/.test(params.status)
  },
复制代码

类似express /^\/order\/(\d+)$/ ,如果你想要知道更多的路由知识,你可以去官网看 路由

layouts 我说的最外层就是指的是pages文件夹下的第一级文件,只能在这一级引用 layouts 布局,其他的地方引用是没有效果的。

plugins

主要是用于引用第三方插件,UI框架或者是自己的库

例如,我先写一些自己的工具方法

文件名
-- plugins
---- VRFCT.js
---- common.js

--------------------------------------------------------------------------

VRFCT.js
/**
 * 判断数据类型
 * @param {检查的值:Any} value 
 */
function getType(value) {
    var typer = Object.prototype.toString
    var typeStr = typer.call(value)
    typeStr = typeStr.replace(/.*\s(\w+)\]/g, '$1')
    return typeStr.toLowerCase()
}
const install = function(Vue) { //通过install方法挂载到Vue原型上去
    Vue.prototype._getType = getType;
}
export default install

--------------------------------------------------------------------------

common.js
import Vue from 'vue';
import VRFCT from './VRFCT';
Vue.use(VRFCT);
复制代码

nuxt.config.js 文件中找到

plugins: [{ src: '~/plugins/common', ssr: true }],
复制代码

这样我们就可以使用全局使用 this._getType 来判断类型了。 需要说明的是 ssr是属性是是否服务端渲染,默认是客户端渲染(false); 在2.4版本后采用的是 mode:client|server , client:客户端|server:服务端 如果你对于这个plugins感兴趣的话可以看一下我项目中写的 plugins 或者移步到官网 plugins

server

node服务,根据你自己想要的去写逻辑,我主要是配置node代理,读取静态文件, 这是我的 server>index.js 文件 地址

static

就是我们常见的静态文件 我们可以通过node默认获取static文件的内容

-- server
---- index.js

--------------------------------------------------------------------------

app.use(express.static('static'))
复制代码

store

这个是vuex的文件目录,他也是通过文件夹的层级去生成对应的vuex文件,如果你对于vuex还不怎么了解的话,可以推荐你看官网 vuex 或者我也写了一篇文章vuex

-- store
---- index.js
---- sex.js
---- name
------ index.js
------ age.js
复制代码

假如我们在 store>index.js

const state = () => ({
    counter: 0
});

const getters = {
    getCounter(state) {
        return state.counter;
    }
}

const mutations = {
    increment(state) {
        state.counter++
    }
}

const actions = {
    // 异步方法
    actionCounter(context) {
        // 异步改变对话框的状态
        context.commit(increment)
    }
}


export default {
    state,
    getters,
    mutations,
    actions
}
这里我们不需要写namespaced: true, //用于在全局引用此文件里的方法时标识这一个的文件名,因为本身他就是通过文件名生成对应的vuex文件
复制代码

想要调用 store>index.jsgetters--getCounter 方法

const state = () => ({
    counter: 0
});
const getters = {
    getCounter(state) {
        return state.counter;
    }
}
const mutations = {
    increment(state) {
        state.counter++
    }
}
const actions = {
    // 异步方法
    actionCounter(context) {
        // 异步改变对话框的状态
        context.commit(increment)
    }
}
export default {
    state,
    getters,
    mutations,
    actions
}
复制代码

我们可以在需要的页面使用

import { mapGetters } from "vuex";
  computed: {
    // 获取状态仓库的batch
    ...mapGetters({
      counter: "getCounter"
    })
  },
复制代码

文件的结构说明

-- store
---- index.js
---- order.js
---- name
------ index.js
------ age.js
复制代码

类似这样的目录我们的调用getters就会有所不同

-- store
---- index.js
import { mapGetters } from "vuex";
  computed: {
    // 获取状态仓库的batch
    ...mapGetters({
      counter: "定义的方法"
    })
  },
 -- store 
 ---- order.js
 import { mapGetters } from "vuex";
  computed: {
    // 获取状态仓库的batch
    ...mapGetters('order',{
      counter: "定义的方法"
    })
  },
 -- store 
 ---- name
 ------ index.js
  import { mapGetters } from "vuex";
  computed: {
    // 获取状态仓库的batch
    ...mapGetters('name',{
      counter: "定义的方法"
    })
  },
 -- store 
 ---- name
 ------ age.js
   import { mapGetters } from "vuex";
  computed: {
    // 获取状态仓库的batch
    ...mapGetters('name/age',{
      counter: "定义的方法"
    })
  },
复制代码

middleware

这里是中间件,这里你可以通过中间件做一些验证token操作

<template>
  <h1>Secret page</h1>
</template>

<script>
export default {
  middleware: 'authenticated'
}
</script>
复制代码
-- middleware
---- authenticated.js

export default function ({ isServer, store, req }) {
  if (isServer && !req) return
  const loggedUser = isServer ? getUserFromCookie(req) : getUserFromLocalStorage()
  store.commit('SET_USER', loggedUser)
}
复制代码

你可以看到一些变量如 req isServer store 这些是 context (上下文内容),关于它的知识,你可以看官网 详细的内容

我来评几句
登录后评论

已发表评论数()

相关站点

+订阅
热门文章