使用 Node.js 在服务器端为 SRR 设置 vue-router 中的当前请求路由

Set current request route in vue-router for SRR in server-side with Node.js

简介

我从处理 request/response 的函数中获得了这个 Node.js 代码。为了解释我的问题,我将使用 Express.js 示例。那段代码不是我的问题的一部分,但我可以向您提供一个简单的上下文来帮助您回答我的问题。所以我的代码将放在 app.get 处理程序中,假设 app 是一个 Express.js 实例:

app.get("/", function (request, response, next) {
    // The code below could be here...
});
app.get("/test/", function (request, response, next) {
    // ...and here...
});
app.get("/*", function (request, response, next) {
    // ...and here...
});

我的代码

假设我的代码是 / 路由中的 运行,代码如下:

app.get("/", function (request, response, next) {
    var Vue = require("vue"),
        VueRouter = require("vue-router"),
        renderers = require("vue-server-renderer"),
        renderer = renderers.createRenderer();

    global.Vue = Vue;
    Vue.use(VueRouter);

    stream = renderer.renderToStream(new Vue({
        template: "<div><router-view></router-view><div>",
        router: new VueRouter({
            routes: [{
                path: '/', 
                component: { template: '<div>foo</div>' }
            }, { 
                path: '/test/', 
                component: { template: '<div>bar</div>' }
            }, { 
                path: '/*', 
                component: { template: '<div>baz</div>' }
            }]
        })
    }));

    response.write("<html><head><title>test</title></head><body>");

    stream.on('data', function (chunk) {
        response.write(chunk);
    });

    stream.on('end', function () {
        response.end('</body></html>');
    });
});

而调用response.end时,发送给客户端的内容是

<html><head><title>test</title></head><body><div server-rendered="true"><!----></div></body></html>

我们可以看到路由器应该显示组件的部分是 <!----> 所以我猜这是因为对于路由器来说,没有路由真正匹配我的代码。

问题

如果没有路由匹配,为什么结果不是下面的:

<html><head><title>test</title></head><body><div server-rendered="true"><div>baz</div></div></body></html>

如何通知我的路由器当前 url 是 / 以在这种情况下生成此代码:

<html><head><title>test</title></head><body><div server-rendered="true"><div>foo</div></div></body></html>

例如,如果我当前的请求来自 /test/

,则以下代码
<html><head><title>test</title></head><body><div server-rendered="true"><div>bar</div></div></body></html>

等等


回答

Thanks to the answer of Ilya Borovitinov (), my previous code become :

app.get("/", function (request, response, next) {
    var Vue = require("vue"),
        VueRouter = require("vue-router"),
        renderers = require("vue-server-renderer"),
        renderer = renderers.createRenderer(),
        router = new VueRouter({
            routes: [{
                path: '/', 
                component: { template: '<div>foo</div>' }
            }, { 
                path: '/test/', 
                component: { template: '<div>bar</div>' }
            }, { 
                path: '/*', 
                component: { template: '<div>baz</div>' }
            }]
        });

    global.Vue = Vue;
    Vue.use(VueRouter);

    stream = renderer.renderToStream(new Vue({
        template: "<div><router-view></router-view><div>",
        router: router
    }));

    /* THIS IS THE SOLUTION */
    router.push(request.url);

    response.write("<html><head><title>test</title></head><body>");

    stream.on('data', function (chunk) {
        response.write(chunk);
    });

    stream.on('end', function () {
        response.end('</body></html>');
    });
});

您正在尝试在未提供明确地址供路由器使用的环境中使用 vue-router。要真正强制路由器呈现正确的路径,您需要调用 router.push(currentUrl) 进行注册。