项目作者: Kim09AI

项目描述 :
基于vue的nuxt框架cnode社区服务端渲染
高级语言: Vue
项目地址: git://github.com/Kim09AI/nuxt-cnode.git
创建时间: 2018-03-26T01:08:52Z
项目社区:https://github.com/Kim09AI/nuxt-cnode

开源协议:

关键词:
nuxt nuxt-cnode vue

下载


nuxt-cnode

基于vue的nuxt框架仿的cnode社区服务端渲染,主要是为了seo优化以及首屏加载速度

线上地址 http://nuxt-cnode.foreversnsd.cn
github地址 https://github.com/Kim09AI/nuxt-cnode

技术栈

  • vue
  • vue-router
  • vuex
  • nuxt
  • axios
  • simplemde
  • ES6/7
  • stylus

目录结构

  1. ├─npm-shrinkwrap.json
  2. ├─nuxt.config.js # nuxt配置文件
  3. ├─package.json
  4. ├─README.md
  5. ├─utils
  6. | ├─axios.js # axios封装
  7. | ├─index.js # 工具函数
  8. | scroll.js # 滚动条操作函数
  9. ├─store # store
  10. | ├─actions.js
  11. | ├─getters.js
  12. | ├─index.js
  13. | ├─mutation-types.js
  14. | ├─mutations.js
  15. | ├─README.md
  16. | state.js
  17. ├─static # 静态资源
  18. | ├─favicon.ico
  19. | README.md
  20. ├─plugins # vue实例化之前执行的插件
  21. | ├─component.js # 注册全局组件
  22. | ├─filter.js # 注册全局filter
  23. | ├─README.md
  24. | ssrAccessToken.js # 服务端渲染时保存access_token,供服务端请求时的api获取
  25. ├─pages # 页面级组件
  26. | ├─index.vue # 首页
  27. | ├─login.vue # 登录页
  28. | ├─README.md
  29. | ├─user
  30. | | ├─messages.vue # 未读消息页
  31. | | ├─_id
  32. | | | ├─index.vue # 用户信息页
  33. | | | collections.vue # 用户收藏的主题页
  34. | ├─topic
  35. | | ├─create.vue # topic创建页,复用为编辑页
  36. | | ├─_id
  37. | | | index.vue # topic详情页
  38. ├─mixins # mixins
  39. | index.js
  40. ├─middleware # 中间件,页面渲染之前执行
  41. | ├─auth.js # 用户权限中间件
  42. | ├─checkRoute.js # 主要是对404页面的重定向
  43. | README.md
  44. ├─layouts # 布局
  45. | ├─default.vue
  46. | README.md
  47. ├─filters # 全局filter
  48. | index.js
  49. ├─components
  50. | ├─alert.vue # 提示组件
  51. | ├─backTop.vue
  52. | ├─clientPanel.vue
  53. | ├─commentList.vue # 评论列表
  54. | ├─commonFooter.vue
  55. | ├─commonHeader.vue
  56. | ├─mainLayout.vue # 页面内的主布局,划分左右两栏
  57. | ├─markdown.vue # 基于simplemde封装的组件
  58. | ├─messageList.vue # 消息列表
  59. | ├─pageNav.vue # 分页组件
  60. | ├─panel.vue
  61. | ├─README.md
  62. | ├─tabHeader.vue
  63. | ├─topicCreatePanel.vue
  64. | ├─topicList.vue # 文章列表
  65. | userInfoPanel.vue
  66. ├─assets
  67. | ├─README.md
  68. | ├─css
  69. | | ├─common.styl
  70. | | ├─icon.styl
  71. | | ├─index.styl
  72. | | ├─mixin.styl
  73. | | ├─reset.styl
  74. | | simplemdecover.styl
  75. ├─api # 请求api
  76. | index.js

实现的功能

  • 首页
  • topic详情页
  • 新建topic
  • 编辑topic
  • 收藏topic
  • 用户收藏的topic
  • 取消收藏topic
  • 新建topic的评论
  • 新建评论的评论
  • 点赞评论
  • 个人信息及用户信息
  • 登录/退出
  • 未读消息页

只要做服务端渲染,不管是vue还是react,都必然会遇到cookie共享的问题,因为在服务器上不会为请求自动带cookie,所以需要手动来为请求带上cookie,以下方法主要是借鉴vue-srr导出一个创建app、router、store工厂函数的方法,导出一个创建axios的工厂函数,然后把创建的axios实例注入store,建立store与axios一一对应的关系,
然后就可以通过store.$axios或state.$axios去请求就会自动带cookie了

  1. export const nuxtServerInit = async ({ commit, dispatch, state }, { req }) => {
  2. let accessToken = parseCookieByName(req.headers.cookie, 'access_token')
  3. if (!!accessToken) {
  4. try {
  5. let res = await state.$axios.checkAccesstoken(accessToken)
  6. if (res.success) {
  7. let userDetail = await state.$axios.getUserDetail(res.loginname)
  8. userDetail.data.id = res.id
  9. // 提交登录状态及用户信息
  10. dispatch('setUserInfo', {
  11. loginState: true,
  12. user: userDetail.data,
  13. accessToken: accessToken
  14. })
  15. }
  16. } catch (e) {
  17. console.log('fail in nuxtServerInit', e.message)
  18. }
  19. }
  20. }

导出一个创建axios的工厂函数

  1. class CreateAxios extends Api {
  2. constructor(store) {
  3. super(store)
  4. this.store = store
  5. }
  6. getAccessToken() {
  7. return this.store.state.accessToken
  8. }
  9. get(url, config = {}) {
  10. let accessToken = this.getAccessToken()
  11. config.params = config.params || {}
  12. accessToken && (config.params.accesstoken = accessToken)
  13. return axios.get(url, config)
  14. }
  15. post(url, data = {}, config = {}) {
  16. let accessToken = this.getAccessToken()
  17. accessToken && (data.accesstoken = accessToken)
  18. return axios.post(url, qs.stringify(data), config)
  19. }
  20. // 返回服务端渲染结果时会用JSON.stringify对state处理,因为store与$axios实例循环引用会导致无法序列化
  21. // 添加toJSON绕过JSON.stringify
  22. toJSON() {}
  23. }
  24. export default CreateAxios

在创建store时创建axios并把axios注入store

  1. const createStore = () => {
  2. let store = new Vuex.Store({
  3. state,
  4. getters,
  5. mutations,
  6. actions
  7. })
  8. store.$axios = store.state.$axios = new CreateAxios(store)
  9. if (process.browser) {
  10. let replaceState = store.replaceState.bind(store)
  11. store.replaceState = (...args) => {
  12. replaceState(...args)
  13. store.state.$axios = store.$axios
  14. replaceState = null
  15. }
  16. }
  17. return store
  18. }
  19. export default createStore

之后就可以在asyncData函数中使用store.$axios、在组件内使用this.$store.$axios、在axtion中使用state.$axios或rootState.$axios发起请求了,这些请求都会自动的带上cookie中的东西

若该项目对你有帮助,欢迎 star

Build Setup

  1. # install dependencies
  2. $ npm install # Or yarn install
  3. # serve with hot reload at localhost:3000
  4. $ npm run dev
  5. # build for production and launch server
  6. $ npm run build
  7. $ npm start
  8. # generate static project
  9. $ npm run generate

For detailed explanation on how things work, checkout the Nuxt.js docs.