mirror of
				https://github.com/KevinMidboe/vue-js-modal.git
				synced 2025-10-29 18:00:20 +00:00 
			
		
		
		
	Created ssr demo and moved csr to a sub-folder + rebuild
This commit is contained in:
		| Before Width: | Height: | Size: 1.2 MiB After Width: | Height: | Size: 1.2 MiB | 
| Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 76 KiB | 
| @@ -37,7 +37,7 @@ module.exports = { | ||||
|   resolve: { | ||||
|     alias: { | ||||
|       'vue$': 'vue/dist/vue.esm.js', | ||||
| 		  'plugin': path.resolve(__dirname, "../dist/client.index.js") | ||||
| 		  'plugin': path.resolve(__dirname, "../../dist/index.js") | ||||
|     } | ||||
|   }, | ||||
|   devServer: { | ||||
							
								
								
									
										62
									
								
								demo/server_side_rendering/.nuxt/App.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								demo/server_side_rendering/.nuxt/App.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,62 @@ | ||||
| <template> | ||||
|   <div id="__nuxt"> | ||||
|     <nuxt-loading ref="loading"></nuxt-loading> | ||||
|     <component v-if="layout" :is="layout"></component> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import NuxtLoading from './components/nuxt-loading.vue' | ||||
|  | ||||
|  | ||||
| let layouts = { | ||||
|  | ||||
|   "_default": () => import('/Users/yev/Projects/vue/vue-js-modal/demo/server/node_modules/nuxt/dist/app/layouts/default.vue'  /* webpackChunkName: "layouts/default" */) | ||||
|  | ||||
| } | ||||
|  | ||||
| export default { | ||||
|   head: {"meta":[],"link":[],"style":[],"script":[]}, | ||||
|   data: () => ({ | ||||
|     layout: null, | ||||
|     layoutName: '' | ||||
|   }), | ||||
|    | ||||
|   mounted () { | ||||
|     this.$loading = this.$refs.loading | ||||
|     this.$nuxt.$loading = this.$loading | ||||
|   }, | ||||
|    | ||||
|   methods: { | ||||
|     setLayout (layout) { | ||||
|       if (!layout || !layouts['_' + layout]) layout = 'default' | ||||
|       this.layoutName = layout | ||||
|       let _layout = '_' + layout | ||||
|       this.layout = layouts[_layout] | ||||
|       return this.layout | ||||
|     }, | ||||
|     loadLayout (layout) { | ||||
|       if (!layout || !layouts['_' + layout]) layout = 'default' | ||||
|       let _layout = '_' + layout | ||||
|       if (typeof layouts[_layout] !== 'function') { | ||||
|         return Promise.resolve(layouts[_layout]) | ||||
|       } | ||||
|       return layouts[_layout]() | ||||
|       .then((Component) => { | ||||
|         layouts[_layout] = Component | ||||
|         return layouts[_layout] | ||||
|       }) | ||||
|       .catch((e) => { | ||||
|         if (this.$nuxt) { | ||||
|           return this.$nuxt.error({ statusCode: 500, message: e.message }) | ||||
|         } | ||||
|         console.error(e) | ||||
|       }) | ||||
|     } | ||||
|   }, | ||||
|   components: { | ||||
|     NuxtLoading | ||||
|   } | ||||
| } | ||||
| </script> | ||||
|  | ||||
							
								
								
									
										417
									
								
								demo/server_side_rendering/.nuxt/client.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										417
									
								
								demo/server_side_rendering/.nuxt/client.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,417 @@ | ||||
| 'use strict' | ||||
|  | ||||
| import Vue from 'vue' | ||||
| import middleware from './middleware' | ||||
| import { createApp, NuxtError } from './index' | ||||
| import { applyAsyncData, sanitizeComponent, getMatchedComponents, getMatchedComponentsInstances, flatMapComponents, getContext, middlewareSeries, promisify, getLocation, compile } from './utils' | ||||
| const noopData = () => { return {} } | ||||
| const noopFetch = () => {} | ||||
| let _lastPaths = [] | ||||
| let _lastComponentsFiles = [] | ||||
|  | ||||
| let app | ||||
| let router | ||||
|  | ||||
|  | ||||
| function mapTransitions(Components, to, from) { | ||||
|   return Components.map((Component) => { | ||||
|     let transition = Component.options.transition | ||||
|     if (typeof transition === 'function') { | ||||
|       return transition(to, from) | ||||
|     } | ||||
|     return transition | ||||
|   }) | ||||
| } | ||||
|  | ||||
| function loadAsyncComponents (to, from, next) { | ||||
|   const resolveComponents = flatMapComponents(to, (Component, _, match, key) => { | ||||
|     if (typeof Component === 'function' && !Component.options) { | ||||
|       return new Promise(function (resolve, reject) { | ||||
|         const _resolve = (Component) => { | ||||
|           Component = sanitizeComponent(Component) | ||||
|           match.components[key] = Component | ||||
|           resolve(Component) | ||||
|         } | ||||
|         Component().then(_resolve).catch(reject) | ||||
|       }) | ||||
|     } | ||||
|     Component = sanitizeComponent(Component) | ||||
|     match.components[key] = Component | ||||
|     return match.components[key] | ||||
|   }) | ||||
|   const fromPath = from.fullPath.split('#')[0] | ||||
|   const toPath = to.fullPath.split('#')[0] | ||||
|   this._hashChanged = (fromPath === toPath) | ||||
|   if (!this._hashChanged) { | ||||
|     this.$loading.start && this.$loading.start() | ||||
|   } | ||||
|   Promise.all(resolveComponents) | ||||
|   .then(() => next()) | ||||
|   .catch((err) => { | ||||
|     let statusCode = err.statusCode || err.status || (err.response && err.response.status) || 500 | ||||
|     this.error({ statusCode, message: err.message }) | ||||
|     next(false) | ||||
|   }) | ||||
| } | ||||
|  | ||||
| function callMiddleware (Components, context, layout) { | ||||
|   // if layout is undefined, only call global middleware | ||||
|   let midd = [] | ||||
|   let unknownMiddleware = false | ||||
|   if (typeof layout !== 'undefined') { | ||||
|     midd = [] // exclude global middleware if layout defined (already called before) | ||||
|     if (layout.middleware) { | ||||
|       midd = midd.concat(layout.middleware) | ||||
|     } | ||||
|     Components.forEach((Component) => { | ||||
|       if (Component.options.middleware) { | ||||
|         midd = midd.concat(Component.options.middleware) | ||||
|       } | ||||
|     }) | ||||
|   } | ||||
|   midd = midd.map((name) => { | ||||
|     if (typeof middleware[name] !== 'function') { | ||||
|       unknownMiddleware = true | ||||
|       this.error({ statusCode: 500, message: 'Unknown middleware ' + name }) | ||||
|     } | ||||
|     return middleware[name] | ||||
|   }) | ||||
|   if (unknownMiddleware) return | ||||
|   return middlewareSeries(midd, context) | ||||
| } | ||||
|  | ||||
| async function render (to, from, next) { | ||||
|   if (this._hashChanged) return next() | ||||
|   let layout | ||||
|   let nextCalled = false | ||||
|   const _next = function (path) { | ||||
|     this.$loading.finish && this.$loading.finish() | ||||
|     if (nextCalled) return | ||||
|     nextCalled = true | ||||
|     next(path) | ||||
|   } | ||||
|   let context = getContext({ to, isClient: true, next: _next.bind(this), error: this.error.bind(this) }, app) | ||||
|   let Components = getMatchedComponents(to) | ||||
|   this._context = context | ||||
|   this._dateLastError = this.$options._nuxt.dateErr | ||||
|   this._hadError = !!this.$options._nuxt.err | ||||
|   if (!Components.length) { | ||||
|     // Default layout | ||||
|     await callMiddleware.call(this, Components, context) | ||||
|     if (context._redirected) return | ||||
|     layout = await this.loadLayout(typeof NuxtError.layout === 'function' ? NuxtError.layout(context) : NuxtError.layout) | ||||
|     await callMiddleware.call(this, Components, context, layout) | ||||
|     if (context._redirected) return | ||||
|     this.error({ statusCode: 404, message: 'This page could not be found.' }) | ||||
|     return next() | ||||
|   } | ||||
|   // Update ._data and other properties if hot reloaded | ||||
|   Components.forEach(function (Component) { | ||||
|     if (Component._Ctor && Component._Ctor.options) { | ||||
|       Component.options.asyncData = Component._Ctor.options.asyncData | ||||
|       Component.options.fetch = Component._Ctor.options.fetch | ||||
|     } | ||||
|   }) | ||||
|   this.setTransitions(mapTransitions(Components, to, from)) | ||||
|   try { | ||||
|     // Set layout | ||||
|     await callMiddleware.call(this, Components, context) | ||||
|     if (context._redirected) return | ||||
|     layout = Components[0].options.layout | ||||
|     if (typeof layout === 'function') { | ||||
|       layout = layout(context) | ||||
|     } | ||||
|     layout = await this.loadLayout(layout) | ||||
|     await callMiddleware.call(this, Components, context, layout) | ||||
|     if (context._redirected) return | ||||
|     // Pass validation? | ||||
|     let isValid = true | ||||
|     Components.forEach((Component) => { | ||||
|       if (!isValid) return | ||||
|       if (typeof Component.options.validate !== 'function') return | ||||
|       isValid = Component.options.validate({ | ||||
|         params: to.params || {}, | ||||
|         query : to.query  || {} | ||||
|       }) | ||||
|     }) | ||||
|     if (!isValid) { | ||||
|       this.error({ statusCode: 404, message: 'This page could not be found.' }) | ||||
|       return next() | ||||
|     } | ||||
|     await Promise.all(Components.map((Component, i) => { | ||||
|       // Check if only children route changed | ||||
|       Component._path = compile(to.matched[i].path)(to.params) | ||||
|       if (!this._hadError && Component._path === _lastPaths[i] && (i + 1) !== Components.length) { | ||||
|         return Promise.resolve() | ||||
|       } | ||||
|       let promises = [] | ||||
|       // asyncData method | ||||
|       if (Component.options.asyncData && typeof Component.options.asyncData === 'function') { | ||||
|         var promise = promisify(Component.options.asyncData, context) | ||||
|         promise.then((asyncDataResult) => { | ||||
|           applyAsyncData(Component, asyncDataResult) | ||||
|           this.$loading.increase && this.$loading.increase(30) | ||||
|         }) | ||||
|         promises.push(promise) | ||||
|       } | ||||
|       if (Component.options.fetch) { | ||||
|         var p = Component.options.fetch(context) | ||||
|         if (!p || (!(p instanceof Promise) && (typeof p.then !== 'function'))) { p = Promise.resolve(p) } | ||||
|         p.then(() => this.$loading.increase && this.$loading.increase(30)) | ||||
|         promises.push(p) | ||||
|       } | ||||
|       return Promise.all(promises) | ||||
|     })) | ||||
|     _lastPaths = Components.map((Component, i) => compile(to.matched[i].path)(to.params)) | ||||
|     this.$loading.finish && this.$loading.finish() | ||||
|     // If not redirected | ||||
|     if (!nextCalled) { | ||||
|       next() | ||||
|     } | ||||
|   } catch (error) { | ||||
|     _lastPaths = [] | ||||
|     error.statusCode = error.statusCode || error.status || (error.response && error.response.status) || 500 | ||||
|     let layout = NuxtError.layout | ||||
|     if (typeof layout === 'function') { | ||||
|       layout = layout(context) | ||||
|     } | ||||
|     this.loadLayout(layout) | ||||
|     .then(() => { | ||||
|       this.error(error) | ||||
|       next(false) | ||||
|     }) | ||||
|   } | ||||
| } | ||||
|  | ||||
| // Fix components format in matched, it's due to code-splitting of vue-router | ||||
| function normalizeComponents (to, ___) { | ||||
|   flatMapComponents(to, (Component, _, match, key) => { | ||||
|     if (typeof Component === 'object' && !Component.options) { | ||||
|       // Updated via vue-router resolveAsyncComponents() | ||||
|       Component = Vue.extend(Component) | ||||
|       Component._Ctor = Component | ||||
|       match.components[key] = Component | ||||
|     } | ||||
|     return Component | ||||
|   }) | ||||
| } | ||||
|  | ||||
| // When navigating on a different route but the same component is used, Vue.js | ||||
| // will not update the instance data, so we have to update $data ourselves | ||||
| function fixPrepatch (to, ___) { | ||||
|   if (this._hashChanged) return | ||||
|   Vue.nextTick(() => { | ||||
|     let instances = getMatchedComponentsInstances(to) | ||||
|     _lastComponentsFiles = instances.map((instance, i) => { | ||||
|       if (!instance) return ''; | ||||
|       if (_lastPaths[i] === instance.constructor._path && typeof instance.constructor.options.data === 'function') { | ||||
|         let newData = instance.constructor.options.data.call(instance) | ||||
|         for (let key in newData) { | ||||
|           Vue.set(instance.$data, key, newData[key]) | ||||
|         } | ||||
|       } | ||||
|       return instance.constructor.options.__file | ||||
|     }) | ||||
|     // hide error component if no error | ||||
|     if (this._hadError && this._dateLastError === this.$options._nuxt.dateErr) { | ||||
|       this.error() | ||||
|     } | ||||
|     // Set layout | ||||
|     let layout = this.$options._nuxt.err ? NuxtError.layout : to.matched[0].components.default.options.layout | ||||
|     if (typeof layout === 'function') { | ||||
|       layout = layout(this._context) | ||||
|     } | ||||
|     this.setLayout(layout) | ||||
|     // hot reloading | ||||
|     setTimeout(() => hotReloadAPI(this), 100) | ||||
|   }) | ||||
| } | ||||
|  | ||||
| // Special hot reload with asyncData(context) | ||||
| function hotReloadAPI (_app) { | ||||
|   if (!module.hot) return | ||||
|   let $components = [] | ||||
|   let $nuxt = _app.$nuxt | ||||
|   while ($nuxt && $nuxt.$children && $nuxt.$children.length) { | ||||
|     $nuxt.$children.forEach(function (child, i) { | ||||
|       if (child.$vnode.data.nuxtChild) { | ||||
|         let hasAlready = false | ||||
|         $components.forEach(function (component) { | ||||
|           if (component.$options.__file === child.$options.__file) { | ||||
|             hasAlready = true | ||||
|           } | ||||
|         }) | ||||
|         if (!hasAlready) { | ||||
|           $components.push(child) | ||||
|         } | ||||
|       } | ||||
|       $nuxt = child | ||||
|     }) | ||||
|   } | ||||
|   $components.forEach(addHotReload.bind(_app)) | ||||
| } | ||||
|  | ||||
| function addHotReload ($component, depth) { | ||||
|   if ($component.$vnode.data._hasHotReload) return | ||||
|   $component.$vnode.data._hasHotReload = true | ||||
|   var _forceUpdate = $component.$forceUpdate.bind($component.$parent) | ||||
|   $component.$vnode.context.$forceUpdate = () => { | ||||
|     let Components = getMatchedComponents(router.currentRoute) | ||||
|     let Component = Components[depth] | ||||
|     if (!Component) return _forceUpdate() | ||||
|     if (typeof Component === 'object' && !Component.options) { | ||||
|       // Updated via vue-router resolveAsyncComponents() | ||||
|       Component = Vue.extend(Component) | ||||
|       Component._Ctor = Component | ||||
|     } | ||||
|     this.error() | ||||
|     let promises = [] | ||||
|     const next = function (path) { | ||||
|       this.$loading.finish && this.$loading.finish() | ||||
|       router.push(path) | ||||
|     } | ||||
|     let context = getContext({ route: router.currentRoute, isClient: true, hotReload: true, next: next.bind(this), error: this.error }, app) | ||||
|     this.$loading.start && this.$loading.start() | ||||
|     callMiddleware.call(this, Components, context) | ||||
|     .then(() => { | ||||
|       // If layout changed | ||||
|       if (depth !== 0) return Promise.resolve() | ||||
|       let layout = Component.options.layout || 'default' | ||||
|       if (typeof layout === 'function') { | ||||
|         layout = layout(context) | ||||
|       } | ||||
|       if (this.layoutName === layout) return Promise.resolve() | ||||
|       let promise = this.loadLayout(layout) | ||||
|       promise.then(() => { | ||||
|         this.setLayout(layout) | ||||
|         Vue.nextTick(() => hotReloadAPI(this)) | ||||
|       }) | ||||
|       return promise | ||||
|     }) | ||||
|     .then(() => { | ||||
|       return callMiddleware.call(this, Components, context, this.layout) | ||||
|     }) | ||||
|     .then(() => { | ||||
|       // Call asyncData(context) | ||||
|       let pAsyncData = promisify(Component.options.asyncData || noopData, context) | ||||
|       pAsyncData.then((asyncDataResult) => { | ||||
|         applyAsyncData(Component, asyncDataResult) | ||||
|         this.$loading.increase && this.$loading.increase(30) | ||||
|       }) | ||||
|       promises.push(pAsyncData) | ||||
|       // Call fetch() | ||||
|       Component.options.fetch = Component.options.fetch || noopFetch | ||||
|       let pFetch = Component.options.fetch(context) | ||||
|       if (!pFetch || (!(pFetch instanceof Promise) && (typeof pFetch.then !== 'function'))) { pFetch = Promise.resolve(pFetch) } | ||||
|       pFetch.then(() => this.$loading.increase && this.$loading.increase(30)) | ||||
|       promises.push(pFetch) | ||||
|       return Promise.all(promises) | ||||
|     }) | ||||
|     .then(() => { | ||||
|       this.$loading.finish && this.$loading.finish() | ||||
|       _forceUpdate() | ||||
|       setTimeout(() => hotReloadAPI(this), 100) | ||||
|     }) | ||||
|   } | ||||
| } | ||||
|  | ||||
| // Load vue app | ||||
| const NUXT = window.__NUXT__ || {} | ||||
| if (!NUXT) { | ||||
|   throw new Error('[nuxt.js] cannot find the global variable __NUXT__, make sure the server is working.') | ||||
| } | ||||
| // Get matched components | ||||
| const resolveComponents = function (router) { | ||||
|   const path = getLocation(router.options.base) | ||||
|   return flatMapComponents(router.match(path), (Component, _, match, key, index) => { | ||||
|     if (typeof Component === 'function' && !Component.options) { | ||||
|       return new Promise(function (resolve, reject) { | ||||
|         const _resolve = (Component) => { | ||||
|           Component = sanitizeComponent(Component) | ||||
|           if (NUXT.serverRendered) { | ||||
|             applyAsyncData(Component, NUXT.data[index]) | ||||
|           } | ||||
|           match.components[key] = Component | ||||
|           resolve(Component) | ||||
|         } | ||||
|         Component().then(_resolve).catch(reject) | ||||
|       }) | ||||
|     } | ||||
|     Component = sanitizeComponent(Component) | ||||
|     match.components[key] = Component | ||||
|     return Component | ||||
|   }) | ||||
| } | ||||
|  | ||||
| function nuxtReady (app) { | ||||
|   window._nuxtReadyCbs.forEach((cb) => { | ||||
|     if (typeof cb === 'function') { | ||||
|       cb(app) | ||||
|     } | ||||
|   }) | ||||
|   // Special JSDOM | ||||
|   if (typeof window._onNuxtLoaded === 'function') { | ||||
|     window._onNuxtLoaded(app) | ||||
|   } | ||||
|   // Add router hooks | ||||
|   router.afterEach(function (to, from) { | ||||
|     app.$nuxt.$emit('routeChanged', to, from) | ||||
|   }) | ||||
| } | ||||
|  | ||||
| createApp() | ||||
| .then(async (__app) => { | ||||
|   app = __app.app | ||||
|   router = __app.router | ||||
|    | ||||
|   const Components = await Promise.all(resolveComponents(router)) | ||||
|   const _app = new Vue(app) | ||||
|   const layout = NUXT.layout || 'default' | ||||
|   await _app.loadLayout(layout) | ||||
|   _app.setLayout(layout) | ||||
|   const mountApp = () => { | ||||
|     _app.$mount('#__nuxt') | ||||
|     Vue.nextTick(() => { | ||||
|       // Hot reloading | ||||
|       hotReloadAPI(_app) | ||||
|       // Call window.onNuxtReady callbacks | ||||
|       nuxtReady(_app) | ||||
|     }) | ||||
|   } | ||||
|   _app.setTransitions = _app.$options._nuxt.setTransitions.bind(_app) | ||||
|   if (Components.length) { | ||||
|     _app.setTransitions(mapTransitions(Components, router.currentRoute)) | ||||
|     _lastPaths = router.currentRoute.matched.map((route) => compile(route.path)(router.currentRoute.params)) | ||||
|     _lastComponentsFiles = Components.map((Component) => Component.options.__file) | ||||
|   } | ||||
|   _app.error = _app.$options._nuxt.error.bind(_app) | ||||
|   _app.$loading = {} // to avoid error while _app.$nuxt does not exist | ||||
|   if (NUXT.error) _app.error(NUXT.error) | ||||
|   // Add router hooks | ||||
|   router.beforeEach(loadAsyncComponents.bind(_app)) | ||||
|   router.beforeEach(render.bind(_app)) | ||||
|   router.afterEach(normalizeComponents) | ||||
|   router.afterEach(fixPrepatch.bind(_app)) | ||||
|   if (NUXT.serverRendered) { | ||||
|     mountApp() | ||||
|     return | ||||
|   } | ||||
|   render.call(_app, router.currentRoute, router.currentRoute, function (path) { | ||||
|     if (path) { | ||||
|       let mounted = false | ||||
|       router.afterEach(function () { | ||||
|         if (mounted) return | ||||
|         mounted = true | ||||
|         mountApp() | ||||
|       }) | ||||
|       router.push(path) | ||||
|       return | ||||
|     } | ||||
|     normalizeComponents(router.currentRoute, router.currentRoute) | ||||
|     fixPrepatch.call(_app, router.currentRoute, router.currentRoute) | ||||
|     mountApp() | ||||
|   }) | ||||
| }) | ||||
| .catch((err) => { | ||||
|   console.error('[nuxt.js] Cannot load components', err) // eslint-disable-line no-console | ||||
| }) | ||||
							
								
								
									
										64
									
								
								demo/server_side_rendering/.nuxt/components/nuxt-child.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								demo/server_side_rendering/.nuxt/components/nuxt-child.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,64 @@ | ||||
| import Vue from 'vue' | ||||
|  | ||||
| const transitionsKeys = [ | ||||
|   'name', | ||||
|   'mode', | ||||
|   'css', | ||||
|   'type', | ||||
|   'duration', | ||||
|   'enterClass', | ||||
|   'leaveClass', | ||||
|   'enterActiveClass', | ||||
|   'enterActiveClass', | ||||
|   'leaveActiveClass', | ||||
|   'enterToClass', | ||||
|   'leaveToClass' | ||||
| ] | ||||
| const listenersKeys = [ | ||||
|   'beforeEnter', | ||||
|   'enter', | ||||
|   'afterEnter', | ||||
|   'enterCancelled', | ||||
|   'beforeLeave', | ||||
|   'leave', | ||||
|   'afterLeave', | ||||
|   'leaveCancelled' | ||||
| ] | ||||
|  | ||||
| export default { | ||||
|   name: 'nuxt-child', | ||||
|   functional: true, | ||||
|   render (h, { parent, data }) { | ||||
|     data.nuxtChild = true | ||||
|  | ||||
|     const transitions = parent.$nuxt.nuxt.transitions | ||||
|     const defaultTransition = parent.$nuxt.nuxt.defaultTransition | ||||
|     let depth = 0 | ||||
|     while (parent) { | ||||
|       if (parent.$vnode && parent.$vnode.data.nuxtChild) { | ||||
|         depth++ | ||||
|       } | ||||
|       parent = parent.$parent | ||||
|     } | ||||
|     data.nuxtChildDepth = depth | ||||
|     const transition = transitions[depth] || defaultTransition | ||||
|     let transitionProps = {} | ||||
|     transitionsKeys.forEach((key) => { | ||||
|       if (typeof transition[key] !== 'undefined') { | ||||
|         transitionProps[key] = transition[key] | ||||
|       } | ||||
|     }) | ||||
|     let listeners = {} | ||||
|     listenersKeys.forEach((key) => { | ||||
|       if (typeof transition[key] === 'function') { | ||||
|         listeners[key] = transition[key] | ||||
|       } | ||||
|     }) | ||||
|     return h('transition', { | ||||
|       props: transitionProps, | ||||
|       on: listeners | ||||
|     }, [ | ||||
|       h('router-view', data) | ||||
|     ]) | ||||
|   } | ||||
| } | ||||
							
								
								
									
										66
									
								
								demo/server_side_rendering/.nuxt/components/nuxt-error.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								demo/server_side_rendering/.nuxt/components/nuxt-error.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,66 @@ | ||||
| <template> | ||||
|   <div class="error-page"> | ||||
|     <div> | ||||
|       <h1 class="error-code">{{ error.statusCode }}</h1> | ||||
|       <div class="error-wrapper-message"> | ||||
|         <h2 class="error-message">{{ error.message }}</h2> | ||||
|       </div> | ||||
|       <p v-if="error.statusCode === 404"><nuxt-link class="error-link" to="/">Back to the home page</nuxt-link></p> | ||||
|     </div> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| export default { | ||||
|   name: 'nuxt-error', | ||||
|   props: ['error'], | ||||
|   head () { | ||||
|     return { | ||||
|       title: this.error.message || 'An error occured' | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style scoped> | ||||
| .error-page { | ||||
|   color: #000; | ||||
|   background: #fff; | ||||
|   top: 0; | ||||
|   bottom: 0; | ||||
|   left: 0; | ||||
|   right: 0; | ||||
|   position: absolute; | ||||
|   font-family: "SF UI Text", "Helvetica Neue", "Lucida Grande"; | ||||
|   text-align: center; | ||||
|   padding-top: 20%; | ||||
| } | ||||
| .error-code { | ||||
|   display: inline-block; | ||||
|   font-size: 24px; | ||||
|   font-weight: 500; | ||||
|   vertical-align: top; | ||||
|   border-right: 1px solid rgba(0, 0, 0, 0.298039); | ||||
|   margin: 0px 20px 0px 0px; | ||||
|   padding: 10px 23px; | ||||
| } | ||||
| .error-wrapper-message { | ||||
|   display: inline-block; | ||||
|   text-align: left; | ||||
|   line-height: 49px; | ||||
|   height: 49px; | ||||
|   vertical-align: middle; | ||||
| } | ||||
| .error-message { | ||||
|   font-size: 14px; | ||||
|   font-weight: normal; | ||||
|   margin: 0px; | ||||
|   padding: 0px; | ||||
| } | ||||
| .error-link { | ||||
|   color: #00BCD4; | ||||
|   font-weight: normal; | ||||
|   text-decoration: none; | ||||
|   font-size: 14px; | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										9
									
								
								demo/server_side_rendering/.nuxt/components/nuxt-link.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								demo/server_side_rendering/.nuxt/components/nuxt-link.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| import Vue from 'vue' | ||||
|  | ||||
| export default { | ||||
|   name: 'nuxt-link', | ||||
|   functional: true, | ||||
|   render (h, { data, children }) { | ||||
|     return h('router-link', data, children) | ||||
|   } | ||||
| } | ||||
							
								
								
									
										103
									
								
								demo/server_side_rendering/.nuxt/components/nuxt-loading.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								demo/server_side_rendering/.nuxt/components/nuxt-loading.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,103 @@ | ||||
| <template> | ||||
|   <div class="progress" :style="{ | ||||
|     'width': percent+'%', | ||||
|     'height': height, | ||||
|     'background-color': canSuccess? color : failedColor, | ||||
|     'opacity': show ? 1 : 0 | ||||
|   }"></div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import Vue from 'vue' | ||||
|  | ||||
| export default { | ||||
|   name: 'nuxt-loading', | ||||
|   data () { | ||||
|     return { | ||||
|       percent: 0, | ||||
|       show: false, | ||||
|       canSuccess: true, | ||||
|       duration: 5000, | ||||
|       height: '2px', | ||||
|       color: 'black', | ||||
|       failedColor: 'red', | ||||
|     } | ||||
|   }, | ||||
|   methods: { | ||||
|     start () { | ||||
|       this.show = true | ||||
|       this.canSuccess = true | ||||
|       if (this._timer) { | ||||
|         clearInterval(this._timer) | ||||
|         this.percent = 0 | ||||
|       } | ||||
|       this._cut = 10000 / Math.floor(this.duration) | ||||
|       this._timer = setInterval(() => { | ||||
|         this.increase(this._cut * Math.random()) | ||||
|         if (this.percent > 95) { | ||||
|           this.finish() | ||||
|         } | ||||
|       }, 100) | ||||
|       return this | ||||
|     }, | ||||
|     set (num) { | ||||
|       this.show = true | ||||
|       this.canSuccess = true | ||||
|       this.percent = Math.floor(num) | ||||
|       return this | ||||
|     }, | ||||
|     get () { | ||||
|       return Math.floor(this.percent) | ||||
|     }, | ||||
|     increase (num) { | ||||
|       this.percent = this.percent + Math.floor(num) | ||||
|       return this | ||||
|     }, | ||||
|     decrease (num) { | ||||
|       this.percent = this.percent - Math.floor(num) | ||||
|       return this | ||||
|     }, | ||||
|     finish () { | ||||
|       this.percent = 100 | ||||
|       this.hide() | ||||
|       return this | ||||
|     }, | ||||
|     pause () { | ||||
|       clearInterval(this._timer) | ||||
|       return this | ||||
|     }, | ||||
|     hide () { | ||||
|       clearInterval(this._timer) | ||||
|       this._timer = null | ||||
|       setTimeout(() => { | ||||
|         this.show = false | ||||
|         Vue.nextTick(() => { | ||||
|           setTimeout(() => { | ||||
|             this.percent = 0 | ||||
|           }, 200) | ||||
|         }) | ||||
|       }, 500) | ||||
|       return this | ||||
|     }, | ||||
|     fail () { | ||||
|       this.canSuccess = false | ||||
|       return this | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style scoped> | ||||
| .progress { | ||||
|   position: fixed; | ||||
|   top: 0px; | ||||
|   left: 0px; | ||||
|   right: 0px; | ||||
|   height: 2px; | ||||
|   width: 0%; | ||||
|   transition: width 0.2s, opacity 0.4s; | ||||
|   opacity: 1; | ||||
|   background-color: #efc14e; | ||||
|   z-index: 999999; | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										53
									
								
								demo/server_side_rendering/.nuxt/components/nuxt.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								demo/server_side_rendering/.nuxt/components/nuxt.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,53 @@ | ||||
| <template> | ||||
|   <nuxt-error v-if="nuxt.err" :error="nuxt.err"></nuxt-error> | ||||
|   <nuxt-child v-else></nuxt-child> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import Vue from 'vue' | ||||
| import NuxtChild from './nuxt-child' | ||||
| import NuxtError from './nuxt-error.vue' | ||||
|  | ||||
| export default { | ||||
|   name: 'nuxt', | ||||
|   beforeCreate () { | ||||
|     Vue.util.defineReactive(this, 'nuxt', this.$root.$options._nuxt) | ||||
|   }, | ||||
|   created () { | ||||
|     // Add this.$nuxt in child instances | ||||
|     Vue.prototype.$nuxt = this | ||||
|     // Add this.$root.$nuxt | ||||
|     this.$root.$nuxt = this | ||||
|     // Bind $nuxt.setLayout(layout) to $root.setLayout | ||||
|     this.setLayout = this.$root.setLayout.bind(this.$root) | ||||
|     // add to window so we can listen when ready | ||||
|     if (typeof window !== 'undefined') { | ||||
|       window.$nuxt = this | ||||
|     } | ||||
|     // Add $nuxt.error() | ||||
|     this.error = this.$root.error | ||||
|   }, | ||||
|    | ||||
|   mounted () { | ||||
|     if (this.$root.$loading && this.$root.$loading.start) { | ||||
|       this.$loading = this.$root.$loading | ||||
|     } | ||||
|   }, | ||||
|   watch: { | ||||
|     'nuxt.err': 'errorChanged' | ||||
|   }, | ||||
|   methods: { | ||||
|     errorChanged () { | ||||
|       if (this.nuxt.err && this.$loading) { | ||||
|         if (this.$loading.fail) this.$loading.fail() | ||||
|         if (this.$loading.finish) this.$loading.finish() | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|    | ||||
|   components: { | ||||
|     NuxtChild, | ||||
|     NuxtError | ||||
|   } | ||||
| } | ||||
| </script> | ||||
							
								
								
									
										123
									
								
								demo/server_side_rendering/.nuxt/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								demo/server_side_rendering/.nuxt/index.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,123 @@ | ||||
| 'use strict' | ||||
|  | ||||
| import Vue from 'vue' | ||||
| import Meta from 'vue-meta' | ||||
| import { createRouter } from './router.js' | ||||
|  | ||||
| import NuxtChild from './components/nuxt-child.js' | ||||
| import NuxtLink from './components/nuxt-link.js' | ||||
| import NuxtError from './components/nuxt-error.vue' | ||||
| import Nuxt from './components/nuxt.vue' | ||||
| import App from './App.vue' | ||||
|  | ||||
| import { getContext } from './utils' | ||||
|  | ||||
| if (process.browser) { | ||||
|   // window.onNuxtReady(() => console.log('Ready')) hook | ||||
|   // Useful for jsdom testing or plugins (https://github.com/tmpvar/jsdom#dealing-with-asynchronous-script-loading) | ||||
|   window._nuxtReadyCbs = [] | ||||
|   window.onNuxtReady = function (cb) { | ||||
|     window._nuxtReadyCbs.push(cb) | ||||
|   } | ||||
| } | ||||
|  | ||||
| // Import SSR plugins | ||||
| let plugin0 = require('~plugins/vue-js-modal') | ||||
| plugin0 = plugin0.default || plugin0 | ||||
|  | ||||
|  | ||||
| // Component: <nuxt-child> | ||||
| Vue.component(NuxtChild.name, NuxtChild) | ||||
| // Component: <nuxt-link> | ||||
| Vue.component(NuxtLink.name, NuxtLink) | ||||
| // Component: <nuxt> | ||||
| Vue.component(Nuxt.name, Nuxt) | ||||
|  | ||||
| // vue-meta configuration | ||||
| Vue.use(Meta, { | ||||
|   keyName: 'head', // the component option name that vue-meta looks for meta info on. | ||||
|   attribute: 'data-n-head', // the attribute name vue-meta adds to the tags it observes | ||||
|   ssrAttribute: 'data-n-head-ssr', // the attribute name that lets vue-meta know that meta info has already been server-rendered | ||||
|   tagIDKeyName: 'hid' // the property name that vue-meta uses to determine whether to overwrite or append a tag | ||||
| }) | ||||
|  | ||||
| const defaultTransition = {"name":"page","mode":"out-in"} | ||||
|  | ||||
| async function createApp (ssrContext) { | ||||
|    | ||||
|   const router = createRouter() | ||||
|  | ||||
|   if (process.server && ssrContext && ssrContext.url) { | ||||
|     await new Promise((resolve, reject) => { | ||||
|       router.push(ssrContext.url, resolve, reject) | ||||
|     }) | ||||
|   } | ||||
|  | ||||
|   if (process.browser) { | ||||
|      | ||||
|   } | ||||
|  | ||||
|   // root instance | ||||
|   // here we inject the router and store to all child components, | ||||
|   // making them available everywhere as `this.$router` and `this.$store`. | ||||
|   let app = { | ||||
|     router, | ||||
|      | ||||
|     _nuxt: { | ||||
|       defaultTransition: defaultTransition, | ||||
|       transitions: [ defaultTransition ], | ||||
|       setTransitions (transitions) { | ||||
|         if (!Array.isArray(transitions)) { | ||||
|           transitions = [ transitions ] | ||||
|         } | ||||
|         transitions = transitions.map((transition) => { | ||||
|           if (!transition) { | ||||
|             transition = defaultTransition | ||||
|           } else if (typeof transition === 'string') { | ||||
|             transition = Object.assign({}, defaultTransition, { name: transition }) | ||||
|           } else { | ||||
|             transition = Object.assign({}, defaultTransition, transition) | ||||
|           } | ||||
|           return transition | ||||
|         }) | ||||
|         this.$options._nuxt.transitions = transitions | ||||
|         return transitions | ||||
|       }, | ||||
|       err: null, | ||||
|       dateErr: null, | ||||
|       error (err) { | ||||
|         err = err || null | ||||
|         if (typeof err === 'string') { | ||||
|           err = { statusCode: 500, message: err } | ||||
|         } | ||||
|         this.$options._nuxt.dateErr = Date.now() | ||||
|         this.$options._nuxt.err = err; | ||||
|         return err | ||||
|       } | ||||
|     }, | ||||
|     ...App | ||||
|   } | ||||
|  | ||||
|   const next = ssrContext ? ssrContext.next : (location) => app.router.push(location) | ||||
|   const ctx = getContext({ | ||||
|     isServer: !!ssrContext, | ||||
|     isClient: !ssrContext, | ||||
|     route: router.currentRoute, | ||||
|     next, | ||||
|      | ||||
|     req: ssrContext ? ssrContext.req : undefined, | ||||
|     res: ssrContext ? ssrContext.res : undefined, | ||||
|   }, app) | ||||
|   delete ctx.error | ||||
|  | ||||
|   // Inject external plugins | ||||
|    | ||||
|   if (typeof plugin0 === 'function') { | ||||
|     await plugin0(ctx) | ||||
|   } | ||||
|    | ||||
|  | ||||
|   return { app, router } | ||||
| } | ||||
|  | ||||
| export { createApp, NuxtError } | ||||
							
								
								
									
										3
									
								
								demo/server_side_rendering/.nuxt/layouts/default.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								demo/server_side_rendering/.nuxt/layouts/default.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| <template> | ||||
|   <nuxt/> | ||||
| </template> | ||||
							
								
								
									
										1
									
								
								demo/server_side_rendering/.nuxt/middleware.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								demo/server_side_rendering/.nuxt/middleware.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| export default {} | ||||
							
								
								
									
										52
									
								
								demo/server_side_rendering/.nuxt/router.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								demo/server_side_rendering/.nuxt/router.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,52 @@ | ||||
| 'use strict' | ||||
|  | ||||
| import Vue from 'vue' | ||||
| import Router from 'vue-router' | ||||
|  | ||||
| Vue.use(Router) | ||||
|  | ||||
|  | ||||
| const _ddfbdcce = () => import('/Users/yev/Projects/vue/vue-js-modal/demo/server/pages/index.vue' /* webpackChunkName: "pages/index" */) | ||||
|  | ||||
|  | ||||
|  | ||||
| const scrollBehavior = (to, from, savedPosition) => { | ||||
|   // savedPosition is only available for popstate navigations. | ||||
|   if (savedPosition) { | ||||
|     return savedPosition | ||||
|   } else { | ||||
|     let position = {} | ||||
|     // if no children detected | ||||
|     if (to.matched.length < 2) { | ||||
|       // scroll to the top of the page | ||||
|       position = { x: 0, y: 0 } | ||||
|     } | ||||
|     else if (to.matched.some((r) => r.components.default.options.scrollToTop)) { | ||||
|       // if one of the children has scrollToTop option set to true | ||||
|       position = { x: 0, y: 0 } | ||||
|     } | ||||
|     // if link has anchor,  scroll to anchor by returning the selector | ||||
|     if (to.hash) { | ||||
|       position = { selector: to.hash } | ||||
|     } | ||||
|     return position | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
| export function createRouter () { | ||||
|   return new Router({ | ||||
|     mode: 'history', | ||||
|     base: '/', | ||||
|     linkActiveClass: 'nuxt-link-active', | ||||
|     linkExactActiveClass: 'nuxt-link-exact-active', | ||||
|     scrollBehavior, | ||||
|     routes: [ | ||||
|   		{ | ||||
| 			path: "/", | ||||
| 			component: _ddfbdcce, | ||||
| 			name: "index" | ||||
| 		} | ||||
|     ] | ||||
|   }) | ||||
| } | ||||
							
								
								
									
										178
									
								
								demo/server_side_rendering/.nuxt/server.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										178
									
								
								demo/server_side_rendering/.nuxt/server.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,178 @@ | ||||
| 'use strict' | ||||
|  | ||||
| import Vue from 'vue' | ||||
| import { stringify } from 'querystring' | ||||
| import { omit } from 'lodash' | ||||
| import middleware from './middleware' | ||||
| import { createApp, NuxtError } from './index' | ||||
| import { applyAsyncData, sanitizeComponent, getMatchedComponents, getContext, middlewareSeries, promisify, urlJoin } from './utils' | ||||
| const debug = require('debug')('nuxt:render') | ||||
| debug.color = 4 // force blue color | ||||
|  | ||||
| const isDev = true | ||||
|  | ||||
| // This exported function will be called by `bundleRenderer`. | ||||
| // This is where we perform data-prefetching to determine the | ||||
| // state of our application before actually rendering it. | ||||
| // Since data fetching is async, this function is expected to | ||||
| // return a Promise that resolves to the app instance. | ||||
| export default async (context) => { | ||||
|   // create context.next for simulate next() of beforeEach() when wanted to redirect | ||||
|   context.redirected = false | ||||
|   context.next = function (opts) { | ||||
|     context.redirected = opts | ||||
|     // if nuxt generate | ||||
|     if (!context.res) { | ||||
|       context.nuxt.serverRendered = false | ||||
|       return | ||||
|     } | ||||
|     opts.query = stringify(opts.query) | ||||
|     opts.path = opts.path + (opts.query ? '?' + opts.query : '') | ||||
|     if (opts.path.indexOf('http') !== 0 && ('/' !== '/' && opts.path.indexOf('/') !== 0)) { | ||||
|       opts.path = urlJoin('/', opts.path) | ||||
|     } | ||||
|     context.res.writeHead(opts.status, { | ||||
|       'Location': opts.path | ||||
|     }) | ||||
|     context.res.end() | ||||
|   } | ||||
|   const { app, router } = await createApp(context) | ||||
|   const _app = new Vue(app) | ||||
|   const _noopApp = new Vue({ render: (h) => h('div') }) | ||||
|   // Add store to the context | ||||
|    | ||||
|   // Add route to the context | ||||
|   context.route = router.currentRoute | ||||
|   // Nuxt object | ||||
|   context.nuxt = { layout: 'default', data: [], error: null, serverRendered: true } | ||||
|   // Add meta infos | ||||
|   context.meta = _app.$meta() | ||||
|   // Error function | ||||
|   context.error = _app.$options._nuxt.error.bind(_app) | ||||
|  | ||||
|   const s = isDev && Date.now() | ||||
|   let ctx = getContext(context, app) | ||||
|   let Components = [] | ||||
|   let promises = getMatchedComponents(router.match(context.url)).map((Component) => { | ||||
|     return new Promise((resolve, reject) => { | ||||
|       if (typeof Component !== 'function' || Component.super === Vue) return resolve(sanitizeComponent(Component)) | ||||
|       const _resolve = (Component) => resolve(sanitizeComponent(Component)) | ||||
|       Component().then(_resolve).catch(reject) | ||||
|     }) | ||||
|   }) | ||||
|   try { | ||||
|     Components = await Promise.all(promises) | ||||
|   } catch (err) { | ||||
|     // Throw back error to renderRoute() | ||||
|     throw err | ||||
|   } | ||||
|   // nuxtServerInit | ||||
|    | ||||
|     let promise = Promise.resolve() | ||||
|    | ||||
|   await promise | ||||
|   // Call global middleware (nuxt.config.js) | ||||
|   let midd = [] | ||||
|   midd = midd.map((name) => { | ||||
|     if (typeof middleware[name] !== 'function') { | ||||
|       context.nuxt.error = context.error({ statusCode: 500, message: 'Unknown middleware ' + name }) | ||||
|     } | ||||
|     return middleware[name] | ||||
|   }) | ||||
|   if (!context.nuxt.error) { | ||||
|     await middlewareSeries(midd, ctx) | ||||
|   } | ||||
|   if (context.redirected) return _noopApp | ||||
|   // Set layout | ||||
|   let layout = Components.length ? Components[0].options.layout : NuxtError.layout | ||||
|   if (typeof layout === 'function') layout = layout(ctx) | ||||
|   await _app.loadLayout(layout) | ||||
|   layout = _app.setLayout(layout) | ||||
|   // Set layout to __NUXT__ | ||||
|   context.nuxt.layout = _app.layoutName | ||||
|   // Call middleware (layout + pages) | ||||
|   midd = [] | ||||
|   if (layout.middleware) midd = midd.concat(layout.middleware) | ||||
|   Components.forEach((Component) => { | ||||
|     if (Component.options.middleware) { | ||||
|       midd = midd.concat(Component.options.middleware) | ||||
|     } | ||||
|   }) | ||||
|   midd = midd.map((name) => { | ||||
|     if (typeof middleware[name] !== 'function') { | ||||
|       context.nuxt.error = context.error({ statusCode: 500, message: 'Unknown middleware ' + name }) | ||||
|     } | ||||
|     return middleware[name] | ||||
|   }) | ||||
|   if (!context.nuxt.error) { | ||||
|     await middlewareSeries(midd, ctx) | ||||
|   } | ||||
|   if (context.redirected) return _noopApp | ||||
|   // Call .validate() | ||||
|   let isValid = true | ||||
|   Components.forEach((Component) => { | ||||
|     if (!isValid) return | ||||
|     if (typeof Component.options.validate !== 'function') return | ||||
|     isValid = Component.options.validate({ | ||||
|       params: context.route.params || {}, | ||||
|       query: context.route.query  || {} | ||||
|     }) | ||||
|   }) | ||||
|   // If .validate() returned false | ||||
|   if (!isValid) { | ||||
|     // Don't server-render the page in generate mode | ||||
|     if (context._generate) { | ||||
|       context.nuxt.serverRendered = false | ||||
|     } | ||||
|     // Call the 404 error by making the Components array empty | ||||
|     Components = [] | ||||
|   } | ||||
|   // Call asyncData & fetch hooks on components matched by the route. | ||||
|   let asyncDatas = await Promise.all(Components.map((Component) => { | ||||
|     let promises = [] | ||||
|     if (Component.options.asyncData && typeof Component.options.asyncData === 'function') { | ||||
|       let promise = promisify(Component.options.asyncData, ctx) | ||||
|       // Call asyncData(context) | ||||
|       promise.then((asyncDataResult) => { | ||||
|         applyAsyncData(Component, asyncDataResult) | ||||
|         return asyncDataResult | ||||
|       }) | ||||
|       promises.push(promise) | ||||
|     } else promises.push(null) | ||||
|     // call fetch(context) | ||||
|     if (Component.options.fetch) promises.push(Component.options.fetch(ctx)) | ||||
|     else promises.push(null) | ||||
|     return Promise.all(promises) | ||||
|   })) | ||||
|   // If no Components found, returns 404 | ||||
|   if (!Components.length) { | ||||
|     context.nuxt.error = context.error({ statusCode: 404, message: 'This page could not be found.' }) | ||||
|   } | ||||
|    | ||||
|     if (asyncDatas.length) debug('Data fetching ' + context.url + ': ' + (Date.now() - s) + 'ms') | ||||
|    | ||||
|   // datas are the first row of each | ||||
|   context.nuxt.data = asyncDatas.map((r) => (r[0] || {})) | ||||
|   // If an error occured in the execution | ||||
|   if (_app.$options._nuxt.err) { | ||||
|     context.nuxt.error = _app.$options._nuxt.err | ||||
|   } | ||||
|    | ||||
|    | ||||
|   // If no error, return main app | ||||
|   if (!context.nuxt.error) { | ||||
|     return _app | ||||
|   } | ||||
|   // Load layout for error page | ||||
|   layout = (typeof NuxtError.layout === 'function' ? NuxtError.layout(ctx) : NuxtError.layout) | ||||
|   context.nuxt.layout = layout || '' | ||||
|   await _app.loadLayout(layout) | ||||
|   _app.setLayout(layout) | ||||
|   return _app | ||||
|     // if (typeof error === 'string') { | ||||
|     //   error = { statusCode: 500, message: error } | ||||
|     // } | ||||
|     // context.nuxt.error = context.error(error) | ||||
|     //  | ||||
|     // return _app | ||||
| } | ||||
							
								
								
									
										368
									
								
								demo/server_side_rendering/.nuxt/utils.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										368
									
								
								demo/server_side_rendering/.nuxt/utils.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,368 @@ | ||||
| 'use strict' | ||||
| import Vue from 'vue' | ||||
|  | ||||
| const noopData = () => ({}) | ||||
|  | ||||
| export function applyAsyncData (Component, asyncData = {}) { | ||||
|   const ComponentData = Component.options.data || noopData | ||||
|   Component.options.data = function () { | ||||
|     const data =  ComponentData.call(this) | ||||
|     return { ...data, ...asyncData } | ||||
|   } | ||||
|   if (Component._Ctor && Component._Ctor.options) { | ||||
|     Component._Ctor.options.data = Component.options.data | ||||
|   } | ||||
| } | ||||
|  | ||||
| export function sanitizeComponent (Component) { | ||||
|   if (!Component.options) { | ||||
|     Component = Vue.extend(Component) // fix issue #6 | ||||
|     Component._Ctor = Component | ||||
|   } else { | ||||
|     Component._Ctor = Component | ||||
|     Component.extendOptions = Component.options | ||||
|   } | ||||
|   // For debugging purpose | ||||
|   if (!Component.options.name && Component.options.__file) { | ||||
|     Component.options.name = Component.options.__file | ||||
|   } | ||||
|   return Component | ||||
| } | ||||
|  | ||||
| export function getMatchedComponents (route) { | ||||
|   return [].concat.apply([], route.matched.map(function (m) { | ||||
|     return Object.keys(m.components).map(function (key) { | ||||
|       return m.components[key] | ||||
|     }) | ||||
|   })) | ||||
| } | ||||
|  | ||||
| export function getMatchedComponentsInstances (route) { | ||||
|   return [].concat.apply([], route.matched.map(function (m) { | ||||
|     return Object.keys(m.instances).map(function (key) { | ||||
|       return m.instances[key] | ||||
|     }) | ||||
|   })) | ||||
| } | ||||
|  | ||||
| export function flatMapComponents (route, fn) { | ||||
|   return Array.prototype.concat.apply([], route.matched.map(function (m, index) { | ||||
|     return Object.keys(m.components).map(function (key) { | ||||
|       return fn(m.components[key], m.instances[key], m, key, index) | ||||
|     }) | ||||
|   })) | ||||
| } | ||||
|  | ||||
| export function getContext (context, app) { | ||||
|   let ctx = { | ||||
|     isServer: !!context.isServer, | ||||
|     isClient: !!context.isClient, | ||||
|     isDev: true, | ||||
|     app: app, | ||||
|      | ||||
|     route: (context.to ? context.to : context.route), | ||||
|     payload: context.payload, | ||||
|     error: context.error, | ||||
|     base: '/', | ||||
|     env: {}, | ||||
|     hotReload: context.hotReload || false | ||||
|   } | ||||
|   const next = context.next | ||||
|   ctx.params = ctx.route.params || {} | ||||
|   ctx.query = ctx.route.query || {} | ||||
|   ctx.redirect = function (status, path, query) { | ||||
|     if (!status) return | ||||
|     ctx._redirected = true // Used in middleware | ||||
|     // if only 1 or 2 arguments: redirect('/') or redirect('/', { foo: 'bar' }) | ||||
|     if (typeof status === 'string' && (typeof path === 'undefined' || typeof path === 'object')) { | ||||
|       query = path || {} | ||||
|       path = status | ||||
|       status = 302 | ||||
|     } | ||||
|     next({ | ||||
|       path: path, | ||||
|       query: query, | ||||
|       status: status | ||||
|     }) | ||||
|   } | ||||
|   if (context.req) ctx.req = context.req | ||||
|   if (context.res) ctx.res = context.res | ||||
|   return ctx | ||||
| } | ||||
|  | ||||
| export function middlewareSeries (promises, context) { | ||||
|   if (!promises.length || context._redirected) { | ||||
|     return Promise.resolve() | ||||
|   } | ||||
|   return promisify(promises[0], context) | ||||
|   .then(() => { | ||||
|     return middlewareSeries(promises.slice(1), context) | ||||
|   }) | ||||
| } | ||||
|  | ||||
| export function promisify (fn, context) { | ||||
|   let promise | ||||
|   if (fn.length === 2) { | ||||
|     // fn(context, callback) | ||||
|     promise = new Promise((resolve) => { | ||||
|       fn(context, function (err, data) { | ||||
|         if (err) { | ||||
|           context.error(err) | ||||
|         } | ||||
|         data = data || {} | ||||
|         resolve(data) | ||||
|       }) | ||||
|     }) | ||||
|   } else { | ||||
|     promise = fn(context) | ||||
|   } | ||||
|   if (!promise || (!(promise instanceof Promise) && (typeof promise.then !== 'function'))) { | ||||
|     promise = Promise.resolve(promise) | ||||
|   } | ||||
|   return promise | ||||
| } | ||||
|  | ||||
| // Imported from vue-router | ||||
| export function getLocation (base) { | ||||
|   var path = window.location.pathname | ||||
|   if (base && path.indexOf(base) === 0) { | ||||
|     path = path.slice(base.length) | ||||
|   } | ||||
|   return (path || '/') + window.location.search + window.location.hash | ||||
| } | ||||
|  | ||||
| export function urlJoin () { | ||||
|   return [].slice.call(arguments).join('/').replace(/\/+/g, '/') | ||||
| } | ||||
|  | ||||
| // Imported from path-to-regexp | ||||
|  | ||||
| /** | ||||
|  * Compile a string to a template function for the path. | ||||
|  * | ||||
|  * @param  {string}             str | ||||
|  * @param  {Object=}            options | ||||
|  * @return {!function(Object=, Object=)} | ||||
|  */ | ||||
| export function compile (str, options) { | ||||
|   return tokensToFunction(parse(str, options)) | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * The main path matching regexp utility. | ||||
|  * | ||||
|  * @type {RegExp} | ||||
|  */ | ||||
| const PATH_REGEXP = new RegExp([ | ||||
|   // Match escaped characters that would otherwise appear in future matches. | ||||
|   // This allows the user to escape special characters that won't transform. | ||||
|   '(\\\\.)', | ||||
|   // Match Express-style parameters and un-named parameters with a prefix | ||||
|   // and optional suffixes. Matches appear as: | ||||
|   // | ||||
|   // "/:test(\\d+)?" => ["/", "test", "\d+", undefined, "?", undefined] | ||||
|   // "/route(\\d+)"  => [undefined, undefined, undefined, "\d+", undefined, undefined] | ||||
|   // "/*"            => ["/", undefined, undefined, undefined, undefined, "*"] | ||||
|   '([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))' | ||||
| ].join('|'), 'g') | ||||
|  | ||||
| /** | ||||
|  * Parse a string for the raw tokens. | ||||
|  * | ||||
|  * @param  {string}  str | ||||
|  * @param  {Object=} options | ||||
|  * @return {!Array} | ||||
|  */ | ||||
| function parse (str, options) { | ||||
|   var tokens = [] | ||||
|   var key = 0 | ||||
|   var index = 0 | ||||
|   var path = '' | ||||
|   var defaultDelimiter = options && options.delimiter || '/' | ||||
|   var res | ||||
|  | ||||
|   while ((res = PATH_REGEXP.exec(str)) != null) { | ||||
|     var m = res[0] | ||||
|     var escaped = res[1] | ||||
|     var offset = res.index | ||||
|     path += str.slice(index, offset) | ||||
|     index = offset + m.length | ||||
|  | ||||
|     // Ignore already escaped sequences. | ||||
|     if (escaped) { | ||||
|       path += escaped[1] | ||||
|       continue | ||||
|     } | ||||
|  | ||||
|     var next = str[index] | ||||
|     var prefix = res[2] | ||||
|     var name = res[3] | ||||
|     var capture = res[4] | ||||
|     var group = res[5] | ||||
|     var modifier = res[6] | ||||
|     var asterisk = res[7] | ||||
|  | ||||
|     // Push the current path onto the tokens. | ||||
|     if (path) { | ||||
|       tokens.push(path) | ||||
|       path = '' | ||||
|     } | ||||
|  | ||||
|     var partial = prefix != null && next != null && next !== prefix | ||||
|     var repeat = modifier === '+' || modifier === '*' | ||||
|     var optional = modifier === '?' || modifier === '*' | ||||
|     var delimiter = res[2] || defaultDelimiter | ||||
|     var pattern = capture || group | ||||
|  | ||||
|     tokens.push({ | ||||
|       name: name || key++, | ||||
|       prefix: prefix || '', | ||||
|       delimiter: delimiter, | ||||
|       optional: optional, | ||||
|       repeat: repeat, | ||||
|       partial: partial, | ||||
|       asterisk: !!asterisk, | ||||
|       pattern: pattern ? escapeGroup(pattern) : (asterisk ? '.*' : '[^' + escapeString(delimiter) + ']+?') | ||||
|     }) | ||||
|   } | ||||
|  | ||||
|   // Match any characters still remaining. | ||||
|   if (index < str.length) { | ||||
|     path += str.substr(index) | ||||
|   } | ||||
|  | ||||
|   // If the path exists, push it onto the end. | ||||
|   if (path) { | ||||
|     tokens.push(path) | ||||
|   } | ||||
|  | ||||
|   return tokens | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Prettier encoding of URI path segments. | ||||
|  * | ||||
|  * @param  {string} | ||||
|  * @return {string} | ||||
|  */ | ||||
| function encodeURIComponentPretty (str) { | ||||
|   return encodeURI(str).replace(/[\/?#]/g, function (c) { | ||||
|     return '%' + c.charCodeAt(0).toString(16).toUpperCase() | ||||
|   }) | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Encode the asterisk parameter. Similar to `pretty`, but allows slashes. | ||||
|  * | ||||
|  * @param  {string} | ||||
|  * @return {string} | ||||
|  */ | ||||
| function encodeAsterisk (str) { | ||||
|   return encodeURI(str).replace(/[?#]/g, function (c) { | ||||
|     return '%' + c.charCodeAt(0).toString(16).toUpperCase() | ||||
|   }) | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Expose a method for transforming tokens into the path function. | ||||
|  */ | ||||
| function tokensToFunction (tokens) { | ||||
|   // Compile all the tokens into regexps. | ||||
|   var matches = new Array(tokens.length) | ||||
|  | ||||
|   // Compile all the patterns before compilation. | ||||
|   for (var i = 0; i < tokens.length; i++) { | ||||
|     if (typeof tokens[i] === 'object') { | ||||
|       matches[i] = new RegExp('^(?:' + tokens[i].pattern + ')$') | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   return function (obj, opts) { | ||||
|     var path = '' | ||||
|     var data = obj || {} | ||||
|     var options = opts || {} | ||||
|     var encode = options.pretty ? encodeURIComponentPretty : encodeURIComponent | ||||
|  | ||||
|     for (var i = 0; i < tokens.length; i++) { | ||||
|       var token = tokens[i] | ||||
|  | ||||
|       if (typeof token === 'string') { | ||||
|         path += token | ||||
|  | ||||
|         continue | ||||
|       } | ||||
|  | ||||
|       var value = data[token.name] | ||||
|       var segment | ||||
|  | ||||
|       if (value == null) { | ||||
|         if (token.optional) { | ||||
|           // Prepend partial segment prefixes. | ||||
|           if (token.partial) { | ||||
|             path += token.prefix | ||||
|           } | ||||
|  | ||||
|           continue | ||||
|         } else { | ||||
|           throw new TypeError('Expected "' + token.name + '" to be defined') | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       if (Array.isArray(value)) { | ||||
|         if (!token.repeat) { | ||||
|           throw new TypeError('Expected "' + token.name + '" to not repeat, but received `' + JSON.stringify(value) + '`') | ||||
|         } | ||||
|  | ||||
|         if (value.length === 0) { | ||||
|           if (token.optional) { | ||||
|             continue | ||||
|           } else { | ||||
|             throw new TypeError('Expected "' + token.name + '" to not be empty') | ||||
|           } | ||||
|         } | ||||
|  | ||||
|         for (var j = 0; j < value.length; j++) { | ||||
|           segment = encode(value[j]) | ||||
|  | ||||
|           if (!matches[i].test(segment)) { | ||||
|             throw new TypeError('Expected all "' + token.name + '" to match "' + token.pattern + '", but received `' + JSON.stringify(segment) + '`') | ||||
|           } | ||||
|  | ||||
|           path += (j === 0 ? token.prefix : token.delimiter) + segment | ||||
|         } | ||||
|  | ||||
|         continue | ||||
|       } | ||||
|  | ||||
|       segment = token.asterisk ? encodeAsterisk(value) : encode(value) | ||||
|  | ||||
|       if (!matches[i].test(segment)) { | ||||
|         throw new TypeError('Expected "' + token.name + '" to match "' + token.pattern + '", but received "' + segment + '"') | ||||
|       } | ||||
|  | ||||
|       path += token.prefix + segment | ||||
|     } | ||||
|  | ||||
|     return path | ||||
|   } | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Escape a regular expression string. | ||||
|  * | ||||
|  * @param  {string} str | ||||
|  * @return {string} | ||||
|  */ | ||||
| function escapeString (str) { | ||||
|   return str.replace(/([.+*?=^!:()[\]|\/\\])/g, '\\$1') | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Escape the capturing group by escaping special characters and meaning. | ||||
|  * | ||||
|  * @param  {string} group | ||||
|  * @return {string} | ||||
|  */ | ||||
| function escapeGroup (group) { | ||||
|   return group.replace(/([=!:$\/()])/g, '\\$1') | ||||
| } | ||||
							
								
								
									
										3
									
								
								demo/server_side_rendering/nuxt.config.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								demo/server_side_rendering/nuxt.config.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| module.exports = { | ||||
|   plugins: ['~plugins/vue-js-modal'] | ||||
| } | ||||
							
								
								
									
										4044
									
								
								demo/server_side_rendering/package-lock.json
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										4044
									
								
								demo/server_side_rendering/package-lock.json
									
									
									
										generated
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										10
									
								
								demo/server_side_rendering/package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								demo/server_side_rendering/package.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| { | ||||
|   "name": "nuxt-hello", | ||||
|   "scripts": { | ||||
|     "start": "nuxt" | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "vue-js-modal": "github:euvl/vue-js-modal#dcf3291623d9fe54bcbf0ca48c0ed35865b8871a", | ||||
|     "nuxt": "^1.0.0-alpha.4" | ||||
|   } | ||||
| } | ||||
							
								
								
									
										19
									
								
								demo/server_side_rendering/pages/index.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								demo/server_side_rendering/pages/index.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | ||||
| <template> | ||||
|   <div> | ||||
|     <modal name="foo">bar</modal> | ||||
|     <button @click="$modal.show('foo')"> | ||||
|       Open modal | ||||
|     </button> | ||||
|     <p>Hi from {{ name }}</p> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| export default { | ||||
|   asyncData ({ req }) { | ||||
|     return { | ||||
|       name: req ? 'server' : 'client' | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </script> | ||||
							
								
								
									
										4
									
								
								demo/server_side_rendering/plugins/vue-js-modal.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								demo/server_side_rendering/plugins/vue-js-modal.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | ||||
| import Vue from 'vue' | ||||
| import VModal from 'vue-js-modal/dist/ssr.index.js' | ||||
|  | ||||
| Vue.use(VModal) | ||||
		Reference in New Issue
	
	Block a user