基於vue的nuxt框架仿的cnode社區服務端渲染,主要是爲了seo優化以及首屏加載速度
線上地址 http://nuxt-cnode.foreversnsd.cn
github地址 https://github.com/Kim09AI/nu...css
├─npm-shrinkwrap.json ├─nuxt.config.js # nuxt配置文件 ├─package.json ├─README.md ├─utils | ├─axios.js # axios封裝 | ├─index.js # 工具函數 | └scroll.js # 滾動條操做函數 ├─store # store | ├─actions.js | ├─getters.js | ├─index.js | ├─mutation-types.js | ├─mutations.js | ├─README.md | └state.js ├─static # 靜態資源 | ├─favicon.ico | └README.md ├─plugins # vue實例化以前執行的插件 | ├─component.js # 註冊全局組件 | ├─filter.js # 註冊全局filter | ├─README.md | └ssrAccessToken.js # 服務端渲染時保存access_token,供服務端請求時的api獲取 ├─pages # 頁面級組件 | ├─index.vue # 首頁 | ├─login.vue # 登陸頁 | ├─README.md | ├─user | | ├─messages.vue # 未讀消息頁 | | ├─_id | | | ├─index.vue # 用戶信息頁 | | | └collections.vue # 用戶收藏的主題頁 | ├─topic | | ├─create.vue # topic建立頁,複用爲編輯頁 | | ├─_id | | | └index.vue # topic詳情頁 ├─mixins # mixins | └index.js ├─middleware # 中間件,頁面渲染以前執行 | ├─auth.js # 用戶權限中間件 | ├─checkRoute.js # 主要是對404頁面的重定向 | └README.md ├─layouts # 佈局 | ├─default.vue | └README.md ├─filters # 全局filter | └index.js ├─components | ├─alert.vue # 提示組件 | ├─backTop.vue | ├─clientPanel.vue | ├─commentList.vue # 評論列表 | ├─commonFooter.vue | ├─commonHeader.vue | ├─mainLayout.vue # 頁面內的主佈局,劃分左右兩欄 | ├─markdown.vue # 基於simplemde封裝的組件 | ├─messageList.vue # 消息列表 | ├─pageNav.vue # 分頁組件 | ├─panel.vue | ├─README.md | ├─tabHeader.vue | ├─topicCreatePanel.vue | ├─topicList.vue # 文章列表 | └userInfoPanel.vue ├─assets | ├─README.md | ├─css | | ├─common.styl | | ├─icon.styl | | ├─index.styl | | ├─mixin.styl | | ├─reset.styl | | └simplemdecover.styl ├─api # 請求api | └index.js
只要作服務端渲染,無論是vue仍是react,都必然會遇到cookie共享的問題,由於在服務器上不會爲請求自動帶cookie,因此須要手動來爲請求帶上cookie,如下方法主要是借鑑vue-srr導出一個建立app、router、store工廠函數的方法,導出一個建立axios的工廠函數,而後把建立的axios實例注入store,創建store與axios一一對應的關係,
而後就能夠經過store.$axios或state.$axios去請求就會自動帶cookie了vue
export const nuxtServerInit = async ({ commit, dispatch, state }, { req }) => { let accessToken = parseCookieByName(req.headers.cookie, 'access_token') if (!!accessToken) { try { let res = await state.$axios.checkAccesstoken(accessToken) if (res.success) { let userDetail = await state.$axios.getUserDetail(res.loginname) userDetail.data.id = res.id // 提交登陸狀態及用戶信息 dispatch('setUserInfo', { loginState: true, user: userDetail.data, accessToken: accessToken }) } } catch (e) { console.log('fail in nuxtServerInit', e.message) } } }
class CreateAxios extends Api { constructor(store) { super(store) this.store = store } getAccessToken() { return this.store.state.accessToken } get(url, config = {}) { let accessToken = this.getAccessToken() config.params = config.params || {} accessToken && (config.params.accesstoken = accessToken) return axios.get(url, config) } post(url, data = {}, config = {}) { let accessToken = this.getAccessToken() accessToken && (data.accesstoken = accessToken) return axios.post(url, qs.stringify(data), config) } // 返回服務端渲染結果時會用JSON.stringify對state處理,由於store與$axios實例循環引用會致使沒法序列化 // 添加toJSON繞過JSON.stringify toJSON() {} } export default CreateAxios
const createStore = () => { let store = new Vuex.Store({ state, getters, mutations, actions }) store.$axios = store.state.$axios = new CreateAxios(store) if (process.browser) { let replaceState = store.replaceState.bind(store) store.replaceState = (...args) => { replaceState(...args) store.state.$axios = store.$axios replaceState = null } } return store } export default createStore
以後就能夠在asyncData函數中使用store.$axios、在組件內使用this.$store.$axios、在axtion中使用state.$axios或rootState.$axios發起請求了,這些請求都會自動的帶上cookie中的東西node
若該項目對你有幫助,歡迎 star
# install dependencies $ npm install # Or yarn install # serve with hot reload at localhost:3000 $ npm run dev # build for production and launch server $ npm run build $ npm start # generate static project $ npm run generate
For detailed explanation on how things work, checkout the Nuxt.js docs.react