探究对VueRouter的Hash模式进行外部监听

这篇具有很好参考价值的文章主要介绍了探究对VueRouter的Hash模式进行外部监听。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

探究对VueRouter的Hash模式进行外部监听(未实现)

VueRouter的hash模式的普遍印象是监听hashchange事件从而改变页面显示的组件,然而在真实场景下会出现hashchange事件无效的情况,本文据此展来了一系列实践操作。

搭建Demo

通过serve开启一个本地服务器对外暴露一个html文件可以快速搭建Demo

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Hash路由问题</title>
    <script src="http://localhost:3000/libs/vue.global.js"></script>
    <script src="http://localhost:3000/libs/vue-router.global.js"></script>
</head>
<body>
    <div id="app">
        <h1>Vue Router</h1>
        <p>
            <router-link to="/">主页</router-link>
            <router-link to="/apple">Go to Apple</router-link>
            <router-link to="/banana">Go to Banana</router-link>
            <router-link to="/orange">Go to Orange</router-link>
        </p>
        <P>下方为路由页面</P>
        <router-view></router-view>
    </div>
    <script>
        const Home = { template: "<div>水果</div>" };
        const Apple = { template: "<div>Apple</div>" };
        const Banana = { template: "<div>Banana</div>" };
        const Orange = { template: "<div>Orange</div>" };

        const router = VueRouter.createRouter({
            history: VueRouter.createWebHashHistory(),
            routes: [
                { path: "/", component: Home },
                { path: "/apple", component: Apple },
                { path: "/banana", component: Banana },
                { path: "/orange", component: Orange },
            ],
        });

        const app = Vue.createApp({});
        app.use(router);
        app.mount("#app");
    </script>
</body>
</html>

测试hashchange

window.addEventListener("hashchange", () => {
    console.log("页面Hash值发生变化!");
});

很简单嘛,给window添加hashchange事件监听。然而实际操作下来,没有任何作用。
vue监听hashchange事件,前端

不管怎么改路由,hashchange事件都没有被触发,打开控制台输入location.hash却能看见hash产生了变化。

vue监听hashchange事件,前端

探究原因

这篇文章有所描述:https://segmentfault.com/q/1010000040105060

vue-router的hash表面上是改变hash值,实际上调用的却是pushState和replaceState的API,能够在不触发hashchange事件的情况下替换hash值。

寻求新方法

既然他使用的是pushState和replaceState,那么监听这两个不就行了。很遗憾,原生并不支持这两个事件的监听。原生支持的是popState,此事件会在back()的情况下触发,pushState和replaceState并不会触发此事件。

在Vue-Router源码中可以看到,他手动重写了pushState和replaceState,为其添加了事件监听器,从而实现路由跳转。

function useHistoryListeners(base, historyState, currentLocation, replace) {
        let listeners = [];
        let teardowns = [];
        // TODO: should it be a stack? a Dict. Check if the popstate listener
        // can trigger twice
        let pauseState = null;
        const popStateHandler = ({ state, }) => {
            const to = createCurrentLocation(base, location);
            const from = currentLocation.value;
            const fromState = historyState.value;
            let delta = 0;
            if (state) {
                currentLocation.value = to;
                historyState.value = state;
                // ignore the popstate and reset the pauseState
                if (pauseState && pauseState === from) {
                    pauseState = null;
                    return;
                }
                delta = fromState ? state.position - fromState.position : 0;
            }
            else {
                replace(to);
            }
            // Here we could also revert the navigation by calling history.go(-delta)
            // this listener will have to be adapted to not trigger again and to wait for the url
            // to be updated before triggering the listeners. Some kind of validation function would also
            // need to be passed to the listeners so the navigation can be accepted
            // call all listeners
            listeners.forEach(listener => {
                listener(currentLocation.value, from, {
                    delta,
                    type: NavigationType.pop,
                    direction: delta
                        ? delta > 0
                            ? NavigationDirection.forward
                            : NavigationDirection.back
                        : NavigationDirection.unknown,
                });
            });
        };
        function pauseListeners() {
            pauseState = currentLocation.value;
        }
        function listen(callback) {
            // set up the listener and prepare teardown callbacks
            listeners.push(callback);
            const teardown = () => {
                const index = listeners.indexOf(callback);
                if (index > -1)
                    listeners.splice(index, 1);
            };
            teardowns.push(teardown);
            return teardown;
        }
        function beforeUnloadListener() {
            const { history } = window;
            if (!history.state)
                return;
            history.replaceState(assign({}, history.state, { scroll: computeScrollPosition() }), '');
        }
        function destroy() {
            for (const teardown of teardowns)
                teardown();
            teardowns = [];
            window.removeEventListener('popstate', popStateHandler);
            window.removeEventListener('beforeunload', beforeUnloadListener);
        }
        // set up the listeners and prepare teardown callbacks
        window.addEventListener('popstate', popStateHandler);
        // TODO: could we use 'pagehide' or 'visibilitychange' instead?
        // https://developer.chrome.com/blog/page-lifecycle-api/
        window.addEventListener('beforeunload', beforeUnloadListener, {
            passive: true,
        });
        return {
            pauseListeners,
            listen,
            destroy,
        };
    }

结语

本次操作对vue-router有了更深的理解,如果有朋友有监听vue-router内hash变化的思路欢迎私信交流~文章来源地址https://www.toymoban.com/news/detail-831157.html

到了这里,关于探究对VueRouter的Hash模式进行外部监听的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • vue3切换路由模式——Hash 、histoary

    1、history模式 使用createWebHistory 2、hash模式 使用createWebHashHistory 综上所述: history 对应 createWebHistory hash 对应 createWebHashHistory

    2024年02月02日
    浏览(47)
  • vue路由的两种模式 hash与history

    Vue 路由是 Vue.js 框架提供的一种机制,用于实现单页面应用(Single-Page Application,简称 SPA)中的前端路由功能。它允许通过定义不同的路由路径和对应的组件,来管理应用程序中不同页面或视图的展示和切换。 Vue 路由使用了浏览器的 History API 或 hash(#)来实现路由导航。通

    2024年02月10日
    浏览(52)
  • VueRouter的两种模式

    前后端分离: 利用Ajax,可以在不刷新浏览器的情况下异步数据请求交互。 前端路由: 匹配不同的url路径,进行解析,加载不同组件,动态渲染内容,不会向后端发出请求。(VueRouter) 单页应用SPA(只有一个html文件),页面交互和页面刷新都是无刷新的。前后端分离+前端路

    2024年02月08日
    浏览(41)
  • 路由hash模式改成history模式的前端vue配置与后端配置

    示例项目地址:http://172.00.00.000:8888/Web/static/index.html/index ,其中: /Web/static/ 表示项目部署路径,每个人的路径不一样,vue默认路径是根路径/,如果你项目不是部署在根路径,那就需要修改一些配置 index.html 表示项目入口文件 /index 表示项目首页的路由地址 vue前端配置 1.配置路

    2024年02月15日
    浏览(51)
  • vue3如何切换hash/history两种路由模式

    本文介绍了在vue3中,如何使用history和hash两种路由模式的方法 1、history模式 使用createWebHistory 2、hash模式 使用createWebHashHistory 综上所述: history 对应 createWebHistory hash 对应 createWebHashHistory

    2024年02月13日
    浏览(42)
  • vue钉钉授权第三方网页登录,扫码登录,vue hash模式下回调地址错误踩坑

    vue接入钉钉登录及遇到的问题 在index.html中引入 钉钉的配置使用后端配置好的,通过接口返回,参数主要是重定向的url地址(需要encode),和client_id。 代码如下: 扫码完成之后,页面会重定向到配置的地址上,附带authCode就是需要这个参数 在created生命周期中使用自己项目的

    2024年02月13日
    浏览(98)
  • VUE之VueRouter页面跳转

    参考视频 参考demo及视频资料 VUE之基本部署及VScode常用插件 VUE之基本组成和使用 VUE之Bootstrap和Element-UI的使用 VUE之axios使用,跨域问题,拦截器添加Token

    2024年02月14日
    浏览(34)
  • Vue学习笔记 之 History 路由 和 Hash 路由的区别 及 History 模式时,Nginx的配置方式

    一、History 模式、Hash 模式   Vue Router 是 Vue.js 官方的路由管理器,用于构建单页应用的前端路由。它允许你通过定义路由配置来映射不同的 URL 到对应的组件,实现页面间的跳转和导航。Vue Router 支持两种路由模式:history 模式和 hash 模式。 1、History 模式   在 History 模式

    2024年02月07日
    浏览(38)
  • Vue3 中 keepAlive 如何搭配 VueRouter 来更自由的控制页面的状态缓存?

    在 vue 中,默认情况下,一个组件实例在被替换掉后会被销毁。这会导致它丢失其中所有已变化的状态——当这个组件再一次被显示时,会创建一个只带有初始状态的新实例。但是 vue 提供了 keep-alive 组件,它可以将一个动态组件包装起来从而实现组件切换时候保留其状态。本篇

    2024年02月11日
    浏览(62)
  • vue项目打包_以生产环境prod模式打包_vue-cli-service 不是内部或外部命令,也不是可运行的程序---vue工作笔记0025

    打开命令行: 首先执行npm install  不执行会报错:   npm run build:prod --scripts-prepend-node-path=auto 然后再这样执行就是以生产环境模式打包了.

    2024年02月05日
    浏览(58)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包