SPA路由实现

路由

前端路由

根据对应路由地址渲染不同的内容

前端的分类

页面路由(刷新)

根据对应的地址访问不同的页面(location.href location.assign location.replace)

hash路由(不会刷新)

根据对应的hash地址来渲染不同的内容(onhashchange)

通过location.hash来获取对应的hash值,通过onhashchange来进行监听

history路由(不会刷新)

1.根据对应的history页面的地址来渲染不同的内容(onpopstate)

2.通过replaceState和pushState来改变state的值和页面的地址

3.通过history.back history.go

history.forward来触发对应的onpopstate时间

后端路由

根据对应的路由地址访问对应的接口

SPA

单页面应用程序

整一个应用只有一个页面,name对应的页面调整就没有意义了,所以对应的SPA的路由实现就主要是hash模式和history模式.在后续的vue或者对应的react中,他主要做的是SPA的应用,那么对应的主要采用hash和history,hash的监听能直接触发而histort的监听不能直接触发,所以默认的模式就是hash模式.

class VueRouter {

    constructor(option) {

        //获取传入的配置

        this.routes = option['routes']

        this.handlerLoad()

    }

    //处理hash改变的监听 需要渲染的元素

    obServer(element) {

        this.el = element

        window.onhashchange = () => {

            this.render()

        }

    }

    //渲染的方法

    render() {

        let _this = this

        //获取当前hash值 去除#

        let hash = location.hash.slice(1)

        //去this.routes比较

        this.routes.forEach(route => {

            if (hash == route.path) {

                _this.el.querySelector('router-view').innerHTML = route.component.template

            }

        });

    }

    //a标签变化

    handlerLink() {

        let _this = this

        //获取所有的router-link

        let linkList = this.el.querySelectorAll('router-link')

        Array.from(linkList).forEach(link => {

            //找到对应的to属性

            let path = link.getAttribute('to')

            //创建a标签 将他的to地址赋值href属性

            let a = document.createElement('a')

            a.href = "#" + path

            a.innerHTML = link.innerHTML

            _this.el.replaceChild(a, link)

        })

    }

    //在打开的时候前面自动+#/


handlerLoad(){

        window.onload = ()=>{

            location.hash = '/'

        }

    }

}

class Vue {

    constructor(option) {

        this.el = document.querySelector(option.el)

        this.router = option.router

        this.router.obServer(this.el)

        //第一次渲染

        this.router.render()

        this.router.handlerLink()

    }

}

history实现

class VueRouter {

    constructor(option) {

        //获取传入的路由配置

        this.routes = option.routes

    }

    obServer(element) {

        //需要挂载的el对象

        this.el = element

        //监听onpopstate事件

        window.onpopstate = () => {

            //读取path根据路径匹配渲染不同的内容

            this.render(location.pathname)

        }

    }

    render(path) {

        let _this = this

        //匹配

        // 遍历路由配置

        this.routes.forEach(route => {

            //判断对应的path地址是否等于route的path地址

            if (path == route.path) {

                //渲染

                let view = _this.el.querySelector('router-view')

                view.innerHTML = route.component.template

            }

        });

    }

    handlerLoad() {

        window.onload = () => {

            //替换当前路径

            history.replaceState('', '', './')

            //第一次渲染

            this.render('/')

        }

    }

    hanlderLink() {

        let _this = this

        let list = []

        //获取所有的router-link

        let linkList = this.el.querySelectorAll('router-link')

        Array.from(linkList).forEach(link => {

            //找到对应的to属性

            let path = link.getAttribute('to')

            //创建a标签 将他的to地址赋值href属性

            let a = document.createElement('a')

            a.href = path

            a.innerHTML = link.innerHTML

            _this.el.replaceChild(a, link)

            list.push(a)

        })

        //给a添加点击事件

        //获取所有的a list

        list.forEach(a => {

            a.addEventListener('click', function (e) {

                e = e || window.event

                //禁止a默认行为

                e.preventDefault();

                history.pushState('', '', a.href)

                //渲染

                _this.render(location.pathname)

            })

        })

    }

}

class Vue {

    constructor(option) {

        this.el = document.querySelector(option.el)

        this.router = option.router

        //监听传入当前的el元素

        this.router.obServer(this.el)

        this.router.handlerLoad()

        this.router.hanlderLink()

    }

}

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 路由 前端路由 根据对应路由地址渲染不同的内容 前端的分类 页面路由(刷新) 根据对应的地址访问不同的页面( lo...
    疯油精阅读 318评论 0 0
  • Vue Router 是Vue.js[http://cn.vuejs.org/]官方的路由管理器。它和 Vue.j...
    SY阅读 783评论 0 0
  • 前沿 置身世外只为暗中观察!!!Hello大家好,我是魔王哪吒!重学巩固你的Vuejs知识体系,如果有哪些知识点遗...
    lessonSam阅读 1,234评论 0 13
  • 1.背景介绍 vue router是vue.js官方的路由管理器,它和vue.js的核心深度集成,让构建单页面应用...
    expecto_5357阅读 508评论 0 1
  • 这里说的Vue中的路由是指前端路由,与后端路由有所区别。我们可以使用url来获取服务器的资源,而这种url与资源的...
    一颗脑袋阅读 695评论 0 0

友情链接更多精彩内容