如何使SPA导航与将innerHTML用于内容的外部框架一起使用

问题描述 投票:0回答:1

在我的Vue.js应用程序中,我使用的是基于引导程序的框架,该框架会为我的header and a menu nav with links生成html,然后通过将innerHTML分配给安装点将其插入到页面中。

但是当我使用生成的内容进行导航时,由于链接未使用<router-link>,整个页面都会重新加载。

尝试修复:在Vue应用程序中,我在goto对象上分配了一种称为window的方法,该方法将执行程序化路由器导航。然后,我可以将javascript:window.goto("myPageName");作为href属性传递,但这带来了许多不良影响。

如何在不重新加载页面的情况下使链接清晰浏览?

(该框架需要jQuery作为依赖项,因此可以在解决方案中使用。)

vue.js navigation single-page-application vue-router
1个回答
0
投票

我能够使用MutationObserverwatches for subtree changes并在检测到通过.innerHTML添加的链接时添加了自定义点击处理程序。

使用此方法,我将vue-goto:myPageName指定为href属性,然后处理程序将使其变为SPA链接。

import { router } from "@/router";
import { store } from "@/store";

export const attrib = "vue-goto";
export const prefix = attrib + ":";

function onChange() {
    // find all links matching our custom prefix to which we have not yet added our custom handler
    const links = window.$(`a[href^='${prefix}']`).not(`[${attrib}]`);

    // add custom attribute for us to grab later
    links.attr(attrib, function() {
        // jQuery doesn't like arrow functions
        return window
            .$(this)
            .attr("href")
            .substr(prefix.length)
            .trim();
    });

    // Update href on the link to one that makes sense
    links.attr("href", function() {
        return router.resolve({
            name: window.$(this).attr(attrib), // grab attribute we saved earlier
            params: { lang: store.state.language }, // in our case, our pages are qualified by a language parameter
        }).href;
    });

    // Override default click navigation behaviour to use vue-router programmatic navigation
    links.click(function(e) {
        e.preventDefault(); // prevent default click
        const routeName = window.$(this).attr(attrib);
        const goto = {
            name: routeName,
            lang: store.state.language,
        };
        router.push(goto).catch(ex => {
            // add catch here so navigation promise errors aren't lost to the void causing headaches later
            // eslint-disable-next-line no-console
            console.error(
                `Error occurred during navigation from injected [${prefix}${routeName}] link`,
                "\n",
                ex,
            );
        });
    });
}

let observer;
export function init() {
    if (observer) observer.unobserve(document.body);
    observer = new MutationObserver(onChange);
    observer.observe(document.body, {
        characterData: false,
        childList: true,
        subtree: true, // important, we want to see all changes not just at toplevel
        attributes: false,
    });
}
init();
© www.soinside.com 2019 - 2024. All rights reserved.