diff --git a/package-lock.json b/package-lock.json index 884385c..7eb4495 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7922,7 +7922,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", - "dev": true, "requires": { "randombytes": "^2.1.0" } diff --git a/package.json b/package.json index d887d93..c1f1a3c 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "axios": "0.21.1", "bulma": "0.9.1", "express": "4.17.1", + "serialize-javascript": "5.0.1", "vue": "2.6.12", "vue-router": "3.4.9", "vue-server-renderer": "2.6.12", diff --git a/server.js b/server.js index 56210de..fa5ee51 100644 --- a/server.js +++ b/server.js @@ -1,6 +1,7 @@ const express = require('express'); const path = require('path'); const fs = require('fs'); +const serialize = require('serialize-javascript'); const { createBundleRenderer } = require('vue-server-renderer'); @@ -30,13 +31,24 @@ if (process.env.NODE_ENV === 'development') { app.get('/*', (req, res) => { const renderer = createBundleRenderer(appBundle); - renderer.renderToString({ url: req.url }, (err, html) => { + const context = { url: req.url }; + + renderer.renderToString(context, (err, html) => { if (err) { console.log(err); return res.status(500).send('server error'); } - const ssrIndexHTML = indexHTML.replace('{{APP}}', html); + let ssrIndexHTML = indexHTML.replace('{{APP}}', html); + ssrIndexHTML = ssrIndexHTML.replace( + '{{STATE}}', + `` + ); res.write(ssrIndexHTML); res.end(); diff --git a/src/app.js b/src/app.js index 281aca9..31b23d4 100644 --- a/src/app.js +++ b/src/app.js @@ -1,18 +1,47 @@ import Vue from 'vue'; import AppLayout from './theme/AppLayout.vue'; -import router from './router'; -import store from './vuex-state'; +// import router from './router'; +import { createRouter } from './router'; +// import store from './vuex-state'; +import { createStore } from './vuex-state'; import './styles/index.scss'; // Vue.config.productionTip = false; -Vue.config.devtools = true; +if (typeof window !== 'undefined') { + Vue.config.devtools = true; +} -const app = new Vue({ - store, - router, - // render: (h) => h(AppLayout), - ...AppLayout -}); +// const app = new Vue({ +// store, +// router, +// // render: (h) => h(AppLayout), +// ...AppLayout +// }); -export { app, router, store }; +// export { app, router, store }; + +const createApp = () => { + const router = createRouter(); + + const store = createStore(); + + const app = new Vue({ + store, + router, + // render: (h) => h(AppLayout), + ...AppLayout + }); + return { app, router, store }; +}; + +// export function createApp() { +// const app = new Vue({ +// store, +// router, +// // render: (h) => h(AppLayout), +// ...AppLayout +// }); +// return { app, router, store }; +// } +export { createApp }; diff --git a/src/client-entry.js b/src/client-entry.js index 2466285..624def7 100644 --- a/src/client-entry.js +++ b/src/client-entry.js @@ -1,5 +1,19 @@ -import { app, router } from './app'; +// import { app, router, store } from './app'; +import { createApp } from './app'; + +const { app, router, store } = createApp(); + +if (window.__INITIAL_STATE__) { + // We initialize the store state with the data injected from the server + // console.log(store); + // store.replaceState(window.__INITIAL_STATE__); + store.replaceState(window.__INITIAL_STATE__); + + delete window.__INITIAL_STATE__; + + console.log(store); +} router.onReady(() => { - app.$mount('#app'); + app.$mount('#app', true); }); diff --git a/src/network/index.js b/src/network/index.js index 1a9f0f6..ecb19ae 100644 --- a/src/network/index.js +++ b/src/network/index.js @@ -23,7 +23,7 @@ const getPosts = async categoryId => { return [ { id: 0, - title: { rendered: 'Opps, too busy rigth now' }, + title: { rendered: 'Opps, too busy rigth now from getPosts' }, content: { rendered: 'Please try leater' }, rest_api_enabler: { Link: '/#' } } diff --git a/src/router/index.js b/src/router/index.js index 665d921..db0b6c0 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -44,13 +44,25 @@ const routes = [ } ]; -const router = new VueRouter({ - mode: 'history', - // linkExactActiveClass: 'is-active', - linkActiveClass: 'is-active', - scrollBehavior: (to, from, savedPosition) => ({ y: 0 }), - // base: process.env.BASE_URL, - routes -}); - -export default router; +// const router = new VueRouter({ +// mode: 'history', +// // linkExactActiveClass: 'is-active', +// linkActiveClass: 'is-active', +// scrollBehavior: (to, from, savedPosition) => ({ y: 0 }), +// // base: process.env.BASE_URL, +// routes +// }); + +// export default router; + +const createRouter = () => + new VueRouter({ + mode: 'history', + // linkExactActiveClass: 'is-active', + linkActiveClass: 'is-active', + scrollBehavior: (to, from, savedPosition) => ({ y: 0 }), + // base: process.env.BASE_URL, + routes + }); + +export { createRouter }; diff --git a/src/server-entry.js b/src/server-entry.js index feb9f76..0cdff41 100644 --- a/src/server-entry.js +++ b/src/server-entry.js @@ -1,21 +1,52 @@ -import { app, router, store } from './app'; +// import { app, router, store } from './app'; + +// export default context => { +// console.log(context); +// router.push(context.url); +// return new Promise((resolve, reject) => { +// // set server-side router's location + +// // wait until router has resolved possible async components and hooks +// router.onReady(() => { +// const matchedComponents = router.getMatchedComponents(); +// // console.log(matchedComponents); +// // no matched routes, reject with 404 +// if (!matchedComponents.length) { +// return reject({ code: 404 }); +// } + +// matchedComponents.map(component => { +// if (component.asyncData) { +// return component.asyncData(store, router.currentRoute).then(() => { +// context.initialState = store.state; +// console.log(context.initialState.postsModule.posts); +// resolve(app); +// }); +// } +// resolve(app); +// }); + +// // the Promise should resolve to the app instance so it can be rendered +// }, reject); +// }); +// // return app; +// }; + +import { createApp } from './app'; export default context => { - router.push(context.url); + const { app, router, store } = createApp(); + // console.log(context); return new Promise((resolve, reject) => { - // set server-side router's location + router.push(context.url); - // wait until router has resolved possible async components and hooks router.onReady(() => { - const matchedComponents = router.getMatchedComponents(); - // no matched routes, reject with 404 - if (!matchedComponents.length) { - return reject({ code: 404 }); - } + context.rendered = () => { + context.state = store.state; + console.log(context.state); + }; - // the Promise should resolve to the app instance so it can be rendered resolve(app); }, reject); }); - // return app; }; diff --git a/src/theme/PostList.vue b/src/theme/PostList.vue index 4a366b1..82157e3 100644 --- a/src/theme/PostList.vue +++ b/src/theme/PostList.vue @@ -36,6 +36,13 @@ import { mapGetters, mapActions } from 'vuex'; export default { name: 'PostList', + // async asyncData(store, route) { + // // console.log(route.params.id); + // return await store.dispatch('postsModule/fetchPosts', route.params.id); + // }, + async serverPrefetch() { + await this.fetchPosts(this.id); + }, components: { 'post-card': PostCard }, @@ -53,6 +60,7 @@ export default { }, async created() { + // console.log('from postList created'); await this.fetchPosts(this.id); // console.log(this.profile); }, diff --git a/src/vuex-state/index.js b/src/vuex-state/index.js index f588ed1..345344b 100644 --- a/src/vuex-state/index.js +++ b/src/vuex-state/index.js @@ -8,21 +8,33 @@ import postsModule from './modules/posts'; Vue.use(Vuex); -const state = { +const state = () => ({ isAuthenticated: false, profile: {} -}; +}); const getters = { isAuthenticated: state => state.isAuthenticated, profile: state => state.profile }; -export default new Vuex.Store({ - strict: process.env.NODE_ENV !== 'production', - modules: { postsModule }, - state, - mutations, - actions, - getters -}); +// export default new Vuex.Store({ +// strict: process.env.NODE_ENV !== 'production', +// modules: { postsModule }, +// state, +// mutations, +// actions, +// getters +// }); + +const createStore = () => + new Vuex.Store({ + strict: process.env.NODE_ENV !== 'production', + modules: { postsModule }, + state, + mutations, + actions, + getters + }); + +export { createStore }; diff --git a/src/vuex-state/modules/posts/actions.js b/src/vuex-state/modules/posts/actions.js index 03ff591..9805e63 100644 --- a/src/vuex-state/modules/posts/actions.js +++ b/src/vuex-state/modules/posts/actions.js @@ -22,7 +22,6 @@ const actions = { break; default: postsUpdate = errorPost; - return; } commit(types.GET_POSTS, postsUpdate); } diff --git a/template/index.html b/template/index.html index 5079e85..d65dc09 100644 --- a/template/index.html +++ b/template/index.html @@ -5,6 +5,7 @@ Document + {{STATE}}