原生JS实现组件切换(不刷新页面)

news2024/11/29 6:34:09

        这是通过原生Es6实现的组件切换,代码很简单,原理和各种框架原理大致相同。

创建文件


├── component:存放组件
│   ├── home1.js:组件1
│   ├── home2.js:组件2
├── index.html
├── index.js

初始化html文件

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      .home1 {
        background-color: #e33a3a;
        width: 200px;
        height: 200px;
      }
      .home2 {
        background-color: #6ce11e;
        width: 200px;
        height: 200px;
      }
    </style>
  </head>
  <body>
    <div id="app"></div>
    <a href="#/home1">组件1</a>
    <a href="#/home2">组件2</a>

    <!-- type="module",必须带这个,因为后面会使用部分的ES6(模块化) -->
    <script src="./index.js" type="module"></script>

  </body>
</html>

初始化hom1和home2

//home1.js

export function home1Page() {
    document.querySelector("#app").innerHTML = homePageTemplate;
}
const homePageTemplate = `
<div class="home1">
    <div>组件1</div>
</div>`;


//home2.js

export function home2Page() {
    document.querySelector("#app").innerHTML = componentPageTemplate;
}
const componentPageTemplate = `
<div class="home2">
    <div>组件2</div>
</div>`;

创建index.js

index.js我们一步一步刨析

1、创建路由表

首页先创建一个路由表,在不同的路由下执行不同的方法。

import { home1Page } from "./component/home1.js";
import { home2Page } from "./component/home2.js";
//路由表
const routers = [
    {
        name: "home1",
        path: "/home1",
        component: home1Page
    },
    {
        name: "home2",
        path: "/home2",
        component: home2Page,
    }
];
2、监听hash
// 监听页面 load和hashchange 事件,事件触发后对代理对象赋值

//hash变化
window.addEventListener("hashchange", () => {
    hashProxy.hash = window.location.hash;
});
//页面初始化
window.addEventListener("load", () => {
    hashProxy.hash = window.location.hash;
})

// 数据响应式处理
const hashProxy = reactive(
    {
        hash: ""
    },
    effective
)

// obj是要变成响应式的对象,effective是一个回调函数,在对象属性发生变化时会被调用
function reactive(obj, effective) {
    return new Proxy(obj, {
        get(obj, key) {
            return Reflect.get(obj, key);
        },
        set(obj, key, value) {
            let set = Reflect.set(obj, key, value);
            effective();
            return set;
        },
    });
}

//数据响应式执行函数
let effective = () => {
    consoel.log("hash变化了");
    changeComponent()
};
3、数据变化调用方法
//组件渲染方法
function changeComponent() {
   //将路径带入方法中得到options
    let options = getRouteroptions(hashProxy.hash);
    
    //过滤路由表,得到对应组件的方法
    const [{ component }] = routers.filter(
        (router) => router.name == options.name
    );

    //调用组件对应的方法,实现页面切换
    component();
}

function getRouteroptions(hash) {
    const options = {
        //路由配置选项
        name: "",
        params: "",
        query: ""
    }
    //hash不存在时
    if (!hash || hash == "#home1") {
        options.name = "home1";
    } else {
        //提取name params query信息
        //     0    1      2
        //<a href='#/name/:params?query1=value1?query2=value2'></a>
        try {
            const routerArr = hash.slice(1).split("/");
            options.name = routerArr[1];
            // const paramsArr = routerArr[2].split("?");
            // options.params = paramsArr[0].slice(1);
            // options.query = paramsArr.slice(1);
        } catch (error) {
            options.name = "404";
        }
    }
    return options
}

至此功能就实现了

 

index.js完整代码

import { home1Page } from "./component/home1.js";
import { home2Page } from "./component/home2.js";
//路由表
const routers = [
    {
        name: "home1",
        path: "/home1",
        component: home1Page
    },
    {
        name: "home2",
        path: "/home2",
        component: home2Page,
    }
];

// 监听页面 load和hashchange 事件,事件触发后对代理对象赋值
window.addEventListener("hashchange", () => {
    hashProxy.hash = window.location.hash;
});

window.addEventListener("load", () => {
    hashProxy.hash = window.location.hash;
})

function changeComponent() {
    let options = getRouteroptions(hashProxy.hash);
    const [{ component }] = routers.filter(
        (router) => router.name == options.name
    );
    component();
}

function reactive(obj, effective) {
    return new Proxy(obj, {
        get(obj, key) {
            return Reflect.get(obj, key);
        },
        set(obj, key, value) {
            let set = Reflect.set(obj, key, value);
            effective();
            return set;
        },
    });
}

//数据响应式执行函数
let effective = () => changeComponent();

// 数据响应式处理
const hashProxy = reactive(
    {
        hash: ""
    },
    effective
)

function getRouteroptions(hash) {
    const options = {
        //路由配置选项
        name: "",
        params: "",
        query: ""
    }
    if (!hash || hash == "#home1") {
        options.name = "home1";
    } else {
        //提取name params query信息
        //     0    1      2
        //<a href='#/name/:params?query1=value1?query2=value2'></a>
        try {
            const routerArr = hash.slice(1).split("/");
            options.name = routerArr[1];
            // const paramsArr = routerArr[2].split("?");
            // options.params = paramsArr[0].slice(1);
            // options.query = paramsArr.slice(1);
        } catch (error) {
            options.name = "404";
        }
    }
    return options
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1322190.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

台湾虾皮本土店铺:如何在台湾虾皮本土店铺开展电商业务

在台湾地区&#xff0c;虾皮&#xff08;Shopee&#xff09;是一款备受欢迎的电商平台。虾皮拥有强大的技术团队、丰富的电商经验和对市场的深刻理解。虾皮本土店铺凭借其在出售、物流、回款、售后、仓储等方面的一条龙服务&#xff0c;为广大卖家提供了全方位的保障和支持。如…

VSCode报错插件Error lens

1.点击左侧扩展图标→搜索“error lens”→点击“安装” 2.安装成功页面如下&#xff1a; 3.代码测试一下&#xff1a;书写代码的过程中会出现红色提醒或红色报错 4.另外推荐小伙伴们安装中文插件&#xff0c;学习过程中会比较实用方便&#xff0c;需要安装中文插件的小伙伴请点…

【性能测试】资深老鸟带你,一篇打通负载与压力测试的区别...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 负载测试 是通过…

【lesson17】MySQL表的基本操作--表去重、聚合函数和group by

文章目录 MySQL表的基本操作介绍插入结果查询&#xff08;表去重&#xff09;建表插入数据操作 聚合函数建表插入数据操作 group by&#xff08;分组&#xff09;建表插入数据操作 MySQL表的基本操作介绍 CRUD : Create(创建), Retrieve(读取)&#xff0c;Update(更新)&#x…

2.vue学习(8-7)

文章目录 8.数据绑定9.el与data的2种写法 8.数据绑定 单向数据绑定就是我们学的v-bind的方式&#xff0c;vue对象变了&#xff0c;页面才变。但是页面变了&#xff0c;vue对象不会变。 双向数据绑定需要用v-model&#xff0c;就能实现双向的改变。 注意&#xff1a;不是所有的…

我的4096创作纪念日

机缘 岁月如梭&#xff0c;时光一晃已经在CSDN扎根4096天了。第一次注册CSDN好像还是在2012年&#xff0c;那会还没大学毕业。初入CSDN&#xff0c;只是把他当作自己编程时遇到问题的在线笔记记录而已&#xff0c;没想到无意间还帮助了其他遇到同样问题困扰的同学。而在这4096…

简析555电压检测电路

555定时器的简介 555定时器是一种多用途的数字——模拟混合集成电路&#xff0c;利用它能极方便地构成施密特触发器、单稳态触发器和多谐振荡器。由于使用灵活、方便&#xff0c;所以555定时器在波形的产生与交换、测量与控制、家用电器、电子玩具等许多领域中都得到了广泛应用…

idea添加外部jar包

在日常开发中在lib包的里面添加了外部的jar&#xff0c;如何将外部的包添加到java类库中&#xff0c;这样项目就可以引用相应的jar包&#xff0c;操作如下&#xff1a; 1.先将需要的jar复制到lib包如下&#xff0c;如下截图&#xff0c;图标前面没有箭头&#xff0c;表示还未添…

echart饼状图文字大小位置颜色调整属性

echart饼状图文字大小位置颜色调整属性 文字位置对应属性代码效果图 文字位置对应属性 1.图中‘1’的文字大小调整在‘legend’对象下的‘textStyle’属性里 2.图中‘2’的文字大小调整在‘tooltip’对象下的‘textStyle’属性里 3.图中‘3’的文字大小调整在‘series’对象下的…

flink 读取 apache paimon表,查看source的延迟时间 消费堆积情况

paimon source查看消费的数据延迟了多久 如果没有延迟 则显示0 官方文档 Metrics | Apache Paimon

什么是证券RPA?证券RPA解决什么问题?证券RPA实施难点在哪里?

RPA智能机器人&#xff0c;也称为“机器人流程自动化”、“软件机器人”&#xff0c;使用智能自动化技术来执行人类工人的重复性办公室任务。它结合API和用户界面(UI)交互来集成和执行企业和生产力应用程序之间的重复性任务。只要预先设计好使用规则&#xff0c;RPA就可以模拟人…

.NET 自定义中间件 判断是否存在 AllowAnonymousAttribute 特性 来判断是否需要身份验证

public Task InvokeAsync(HttpContext context){// 获取终点路由特性var endpointFeature context.Features.Get<IEndpointFeature>();// 获取是否定义了特性var attribute endpointFeature?.Endpoint?.Metadata?.GetMetadata<AllowAnonymousAttribute>();if …

项目中webpack优化配置(持续更新)

项目中webpack优化配置 1. 开发效率&#xff0c; 体验 DLL&#xff08;开发过程中减少构建时间和增加应用程序的性能&#xff09; 使用 DllPlugin 进行分包&#xff0c;使用 DllReferencePlugin(索引链接) 对 manifest.json 引用&#xff0c;让一些基本不会改动的代码先打包…

JVM调优排错专题

JVM调优排错专题 1 打开MAT报错 1 打开MAT报错 下载了linux版本的 MAT 软件&#xff0c;1.15.0版本。 下载地址&#xff1a;https://eclipse.dev/mat/downloads.php 运行时报错了。 错误截图 报错日志 wittasus:/usr/develop/mat$ ./MemoryAnalyzer Unrecognized option:…

【PHD申请文书】motivation letter|不限字数|Medical Imaging and Application

本文目录 APPLICATION ESSAYCriticism思考 Ref: https://essayforum.com/letters/tryst-technology-motivation-erasmus-degree-85383/ APPLICATION ESSAY My tryst with technology - motivation letter for Erasmus Degree in Medical Imaging and Application 原文机翻My…

视频素材网站全新上线,海量高清视频等你来探索~

亲爱的视频制作爱好者们&#xff0c;好消息来啦&#xff01;我们的视频素材网站全新上线啦&#xff01;这次我们为大家带来了海量的高清视频素材&#xff0c;无论是风景、城市、人物、动物还是各种特效、背景等&#xff0c;应有尽有&#xff0c;满足您在视频制作过程中的各种需…

WebMvcConfigurer接口详解及使用方式(Spring-WebMvc)

简介 如下图所示WebMvcConfigurer是spring-webmvc jar包下的一个接口&#xff0c;spring-webmvc jar包又来源于spring-boot-starter-web&#xff0c;所以要使用WebMvcConfigurer要引入spring-boot-starter-web依赖。WebMvcConfigurer接口提供了常用的web应用拦截方法。通过实现…

使用iframe后,鼠标点击位置和实际点击位置不一致

结论&#xff1a; 因为iframe域名和父页面域名不一致导致的 在本地启动项目的时候&#xff0c;鼠标指定的元素在iframe上&#xff0c;发现点击事件不起作用了 点击iframe里面的元素&#xff0c;发现也错位了&#xff0c; 上线之后&#xff0c;父页面部署的域名和iframe中src的…

WebCamTexture报错

使用WebCamTexture把相机的画面显示到 RawImage 上 using UnityEngine; using UnityEngine.UI;public class WebCamTextureTest : MonoBehaviour {public RawImage RawImage;private WebCamTexture _webCamTexture;private Color32[] _colorBuff;private Texture2D _texture2D…

TSINGSEE青犀边缘AI计算基于车辆结构化数据的车辆监控方案

随着人工智能技术的不断发展&#xff0c;边缘AI技术逐渐成为智能交通领域的研究热点。其中&#xff0c;基于边缘AI的车辆结构化数据技术与车辆监控系统是实现智能交通系统的重要手段之一。为了满足市场需求&#xff0c;TSINGSEE青犀边缘AI智能分析网关/视频智能分析平台推出了一…