• Nuxt.js项目实战


    感悟

    经过几个周六周日的尝试,终于解决了服务端渲染中的常见问题,当SEO不在是问题的时候,或许才是我们搞前端的真正的春天,其中也遇到了一些小坑,Nuxt.js官方还是很给力的,提issue后很积极的给予帮助,再次感谢Nuxt.js的开发团队。

    路由鉴权

    第一个拦路虎就是登陆时候的鉴权问题,如何把token保存到本地。官方使用express-session解决这个问题,但是这样做后端也需要使用nodejs,而我们公司使用的PHP。转念一想或许cookie可以一试,于是我是这样做的:

    app.post('/api/login', function (req, res) {
      // 后台验证用户信息,并返回token
      async function login () {
        const { data } = await axiosServer.post('/login', req.body)
        return data
      }
    
      login().then(function (data) {
        // 把token存储到cookie中
        const { token } = data
        if (token) {
          res.cookie('token', token, {
            maxAge: 60000 * 60 * 24
          })
        }
        // 原封不动返回
        return res.json(data)
      })
    })
    

    我把登录请求用nodejs做了一次转发,把用户提交的数据传给后端,后端返回的token设置到cookie里,然后把数据返会给前端,前端再用vuex保存token状态,这样token同时存在于cookie和内存里,刷新页面也是正常的
    前端存储token:

      async nuxtServerInit ({ dispatch, commit }, { req, res }) {
        if (req.cookies && req.cookies.token) {
          // 存储token
          commit('SET_USER', req.cookies.token)
        }
      },
      // SET_USER
      SET_USER (state, token) {
        state.token = token
      },
    

    于是这个问题就这样解决了,所有需要存储到本地的数据都可以这样做来解决

    渲染组件内的数据

    另一个小问题是components里数据如何渲染。在Nuxt.js中只有page里的组件有fetchasyncData方法,所以当我们使用layout布局页面时如果组件需要请求数据,就无法渲染了,解决方法是在nuxtServerInit方法里初始化组件内的数据,如下:

      async nuxtServerInit ({ dispatch, commit }, { req, res }) {
        // 初始化组件内的数据
        await dispatch('ADMIN_INFO')
        await dispatch('TAGS')
        await dispatch('ARCHIVES')
      }
    

    这样组件内的数据也可渲染成功了

    过滤器的使用

    Nuxt.js的plugins设计的个人感觉还是很人性化的,用起来简直是不能再简单。在plugins新建一个filters.js,过滤器可以这样玩:

    import Vue from 'vue'
    // 时间格式化
    export function formatDate (date, fmt) {
      let newDate = new Date(date)
      if (/(y+)/.test(fmt)) {
        fmt = fmt.replace(RegExp.$1, (newDate.getFullYear() + '').substr(4 - RegExp.$1.length))
      }
      let o = {
        'M+': newDate.getMonth() + 1,
        'd+': newDate.getDate(),
        'h+': newDate.getHours(),
        'm+': newDate.getMinutes(),
        's+': newDate.getSeconds()
      }
      for (let k in o) {
        if (new RegExp(`(${k})`).test(fmt)) {
          let str = o[k] + ''
          fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? str : padLeftZero(str))
        }
      }
      return fmt
    }
    let filters = {
      formatDate
    }
    
    Object.keys(filters).forEach(key => {
      Vue.filter(key, filters[key])
    })
    export default filters
    

    然后在nuxt.config.js中注册一下:

      plugins: [
        '~plugins/filters.js'
      ]
    

    在组件中就可以这样happy的用起来了:

    <!-- 时间格式化 -->
    <div>
     <span>{{date | formatDate('yyyy-MM-dd')}}</span>
    </div>
    

    中间件

    比如说用户未登录状态下,通过路由闯入了需要鉴权的页面,我们可以自定义一些错误:

    // auth.js
    export default function ({ store, error }) {
    // 可通过组件的props接收error信息
      if (!store.state.token) {
        error({
          message: 'cookie失效或未登录,请登录后操作',
          statusCode: 403
        })
      }
    }
    
    

    在组件中使用该中间件:

    export default {
      middleware: 'auth',
      // 还可以把用户重定位到登录页
      fetch ({redirect, store}) {
        if (!store.state.token) {
          redirect('/login')
        }
      },
    }
    

    多级路由嵌套

    官方说这种情况用的较少,但是我发现用的挺多的,比如说不同分类又有不同分页,这样分类和分页都要是动态路由,如图所示:


    编译后的结果:

    项目部署

    大概在8月份时候,写了几篇关于如何部署nodejs项目的文章,回头看写的果然比较菜,随着时间推移,修复了一些错误,发现了一些错误,整体写的太乱。于是抽了一天时间,在新的服务器上一边实践一边记录,把上面几篇文章用gitbook汇总了一下,不在这里展开了,太长了,增加了自动部署的相关内容

    项目实践

    这个小项目是我在几月前写的,最近一月用Nuxt.js进行了重构,前端使用了Nuxt.js + vuex,后端使用了Nodejs + MongoDB, 用vue写了一个markdown编辑器,支持图片上传和服务端渲染,效果图:

    首页

    编辑器


    GitHub
    gitbook

  • 相关阅读:
    有用学习网址
    Pivot运算符用于在列和行之间
    st_MES_InsertIntoSalaryManage
    I00033 消除游戏
    I00033 消除游戏
    PHP版本的Graphviz样例之集群流程图
    PHP版本的Graphviz样例之集群流程图
    Graphviz样例之集群流程图
    Graphviz样例之集群流程图
    Graphviz样例之UML图
  • 原文地址:https://www.cnblogs.com/yesyes/p/7977161.html
Copyright © 2020-2023  润新知