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

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

创建文件


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

初始化html文件



  
    
    
    Document
    
  
  
    
组件1 组件2

初始化hom1和home2

//home1.js

export function home1Page() {
    document.querySelector("#app").innerHTML = homePageTemplate;
}
const homePageTemplate = `
组件1
`; //home2.js export function home2Page() { document.querySelector("#app").innerHTML = componentPageTemplate; } const componentPageTemplate = `
组件2
`;

创建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

        这段代码的目的是创建一个能够观察对象属性变化的代理对象。当使用 reactive 函数创建代理对象后,如果对代理对象进行属性的读取或写入操作,将会触发相应的 getset 操作,从而实现对对象的监听。

        同时,每次属性被写入时,都会调用 effective 回调函数

// 监听页面 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();
}

//将得到的hash地址栏内容进行解析拆分,得到自己想要的内容。
function getRouteroptions(hash) {
    const options = {
        //路由配置选项
        name: "",
        params: "",
        query: ""
    }
    //hash不存在时
    if (!hash || hash == "#home1") {
        options.name = "home1";
    } else {
        //提取name params query信息
        //     0    1      2
        //
        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
}

至此功能就实现了

原生JS实现组件切换(不刷新页面)_第1张图片

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
)

//将得到的hash地址栏内容进行解析拆分,得到自己想要的内容。
function getRouteroptions(hash) {
    const options = {
        //路由配置选项
        name: "",
        params: "",
        query: ""
    }
    if (!hash || hash == "#home1") {
        options.name = "home1";
    } else {
        //提取name params query信息
        //     0    1      2
        //
        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
}

你可能感兴趣的:(javascript,前端,开发语言)