Skip to content
On this page

vue-ssr 2.集成vue-router


安装依赖

jsx
yarn add vue-router

配置路由

创建两个路由对应的页面,方便测试

  • src/views/Foo.vue

    jsx
    <template>
    	<div>Foo page</div>
    </template>
    
    <script>
    export default {
    	name: "Foo",
    };
    </script>
    
    <style scoped>
    div {
    	background: red;
    }
    </style>
    
  • src/views/Bar.vue

    jsx
    <template>
    	<div>Bar page</div>
    </template>
    
    <script>
    export default {
    	name: "Bar",
    };
    </script>
    
    <style scoped>
    div {
    	background-color: blue;
    }
    </style>
    
  • App.vue 添加路由组件进行切换

    jsx
    <template>
    	<!-- app节点必须在此处定义,否则客户端交互失效,所以防止这里统一管理 -->
    	<div id="app">
    		<button @click="add">click me</button>
    		<div>counter: {{ counter }}</div>
    		<router-link to="/">foo</router-link>
    		<router-link to="/bar">bar</router-link>
    		<router-view></router-view>
    	</div>
    </template>
    
    <script>
    export default {
    	name: "App",
    	data() {
    		return { counter: 1 };
    	},
    	methods: {
    		add() {
    			this.counter++;
    		},
    	},
    };
    </script>
    
    <style lang="scss" scoped></style>
    
  • src/router/index.js:配置路由文件

    jsx
    import Vue from "vue";
    import Router from "vue-router";
    
    import Foo from "../views/Foo.vue";
    import Bar from "../views/Bar.vue";
    
    Vue.use(Router);
    
    export default function () {
    	const router = new Router({
    		mode: 'history',
    		routes: [
    			{
    				path: '/', component: Foo
    			},
    			{
    				path: '/bar', component: Bar
    			},
    			{
    				path: '*', component: {
    					render(h) {
    						return h("div", {}, "not found 404");
    					}
    				}
    			},
    		]
    	});
    
    	return router;
    }
    
  • src/app.js : 引入router 创建路由

    jsx
    import Vue from "vue";
    import App from "./App.vue"
    import createRouter from "./router";
    
    export default () => {
    	const router = createRouter();
    	const app = new Vue({
    		router,
    		render: h => h(App)
    	});
    	return { app, router }
    }
    

至此vue-router 集成完成,但是会有个问题,从首页切至bar页面按回车会导致404

解决:刷新本地路由bar页面地址会导致404问题

  • src/server-entry.js:利用vue-router 的push 和onReady接口解决
jsx
import createApp from "./app.js";

export default function (context) {
	const { url } = context;
	return new Promise((resolve, reject) => {
		const { app, router } = createApp();
		//! 说明:如果当前使用的是前端路由,比如:/bar 回车就会导致404,
		//! 解决办法:利用vue-router的push和onReady接口解决
		//! 1. 让其跳入前端路由
		router.push(url);
		//! 2. 路由渲染完毕,准备进入匹配的路由
		router.onReady(() => {
			const matchComponents = router.getMatchedComponents();
			if (matchComponents.length === 0) {
				return reject({ code: 404 });
			} else {
				Promise.all(matchComponents.map(component => {
					if (component.asyncData) {
						return component.asyncData();
					}
				})).then(() => {
					resolve(app);
				});
			}
		});
	});
}

示例代码:传送门

总结

  • 本地的路由按回车是会404的,所以服务端渲染需要先让前端路由跳转渲染,等路由页面渲染好等待跳转onReady触发时再进行返回

以上:如发现有问题,欢迎留言指出,我及时更正

Released under the MIT License.