vue学习之路(路由)
路由是什么
一句话,查找资源的一种方式
路由的分类
- 前端路由:通过动态改变 url 实现,不会和后端服务器发生交互
- 后端路由:资源通常放在服务器上
前端路由
- 哈希模式:监听 url 中的
#
后面的内容变化/锚点 - 历史记录:
window.history
对象,监听popstate
事件
SPA
- SPA:单页面应用程序
- 目标:不刷新页面,实现 url 的变化和更新视图 / ajax
锚点的作用
学习路由之前先回忆下锚点
- 锚点可以改变url地址,实现在当前页面内部的不同区域之间跳转
- 因为是在当前页面中跳转,所以页面不会刷新
- 所以使用锚点可以完成SPA的两大目标:即可以改变url,又不想刷新页面
<body>
<nav>
<a href="#list1">国内新闻</a>
<a href="#list2">娱乐新闻</a>
</nav>
<ul id="list1">
<li><a href="">I have a dream</a></li>
<li><a href="">I have a dream</a></li>
<li><a href="">I have a dream</a></li>
</ul>
<ul id="list2" style="position: relative; top: 40em">
<li><a href="">娱乐新闻title</a></li>
<li><a href="">娱乐新闻title</a></li>
<li><a href="">娱乐新闻title</a></li>
</ul>
<a href="#" style="position: absolute; right: 1em; bottom: 1em">回到顶部</a>
</body>
基于锚点的哈希路由模式
通过hashchange
事件来监听变化
<nav>
<a href="#/list1">国内新闻</a>
<a href="#/list2">娱乐新闻</a>
</nav>
<!-- 该区域专用于显示路由的内容 -->
<div class="route-view"></div>
<script>
let list1 = `
<ul id="list1">
<li><a href="">I have a dream</a></li>
<li><a href="">I have a dream</a></li>
<li><a href="">I have a dream</a></li>
</ul>
`;
let list2 = `
<ul id="list2">
<li><a href="">娱乐新闻title</a></li>
<li><a href="">娱乐新闻title</a></li>
<li><a href="">娱乐新闻title</a></li>
</ul>
`;
// 获取路由的内容显示区元素
const routeView = document.querySelector(".route-view");
// console.log(routeView);
// 锚点使用 location.hash
// window.location:描述的是当前的url信息
// console.log(location.hash);
// hashchange:Url中的锚点变化时会自动触发这个事件
window.addEventListener("hashchange", show);
// window.addEventListener("load", show);
// 只要dom树创建完成就触发,load:要等js执行完成和图片加载完成才触发
window.addEventListener("DOMContentLoaded", show);
function show() {
switch (location.hash) {
case "#/list1":
routeView.innerHTML = list1;
break;
case "#/list2":
routeView.innerHTML = list2;
break;
default:
routeView.innerHTML = list1;
}
}
</script>
vue路由原理与实现
首先要下载 vue-router
库
<!-- 加载vue框架 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- 加载路由模块 -->
<script src="vue-router-dev/dist/vue-router.js"></script>
<nav class="app">
<!-- 1. vue 的路由是基于哈希实现,是用a标签的锚点来实现 -->
<router-link to="/list1">国内新闻</router-link>
<router-link to="/list2">娱乐新闻</router-link>
<!-- 2. 路由到的资源显示区域 -->
<router-view></router-view>
</nav>
<script>
// 1. 创建路由对象
const router = new VueRouter({
// 路由配置项
routes: [
// 每一个路由都是一个对象,每一个对象都对应着一个路由地址
{
path: "/list1",
component: {
template: `
<ul id="list1">
<li><a href="">I have a dream</a></li>
<li><a href="">I have a dream</a></li>
<li><a href="">I have a dream</a></li>
</ul>
`,
},
},
{
path: "/list2",
component: {
template: `
<ul id="list2">
<li><a href="">娱乐新闻title</a></li>
<li><a href="">娱乐新闻title</a></li>
<li><a href="">娱乐新闻title</a></li>
</ul>
`,
},
},
],
});
new Vue({
el:".app",
// 2. 注册路由
router:router,
})
</script>
还可以修整下代码 将component 中的对象提出去写到变量中
<!-- 加载vue框架 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- 加载路由模块 -->
<script src="vue-router-dev/dist/vue-router.js"></script>
<nav class="app">
<!-- 1. vue 的路由是基于哈希实现,是用a标签的锚点来实现 -->
<router-link to="/list1">国内新闻</router-link>
<router-link to="/list2">娱乐新闻</router-link>
<!-- 2. 路由到的资源显示区域 -->
<router-view></router-view>
</nav>
<script>
const list1 = {
template: `
<ul id="list1">
<li><a href="">I have a dream</a></li>
<li><a href="">I have a dream</a></li>
<li><a href="">I have a dream</a></li>
</ul>
`,
};
const list2 = {
template: `
<ul id="list2">
<li><a href="">娱乐新闻title</a></li>
<li><a href="">娱乐新闻title</a></li>
<li><a href="">娱乐新闻title</a></li>
</ul>
`,
};
// 1. 创建路由对象
const router = new VueRouter({
// 路由配置项
routes: [
// 每一个路由都是一个对象,每一个对象都对应着一个路由地址
{ path: "/list1", component: list1 },
{ path: "/list2", component: list2 },
],
});
new Vue({
el: ".app",
// 2. 注册路由
// router: router,
//属性名和同作用域属性值相同,可以只写一个
router,
});
</script>
用历史记录对象实现前端路由模式
<nav>
<a href="/list1">国际新闻</a>
<a href="/list2">娱乐新闻</a>
</nav>
<div class="router-view"></div>
<script>
const list1 = `
<ul id="list1">
<li><a href="">I have a dream</a></li>
<li><a href="">I have a dream</a></li>
<li><a href="">I have a dream</a></li>
</ul>
`;
const list2 = `
<ul id="list2">
<li><a href="">娱乐新闻title</a></li>
<li><a href="">娱乐新闻title</a></li>
<li><a href="">娱乐新闻title</a></li>
</ul>
`;
const routeView = document.querySelector(".router-view");
// 获取到所有的a.href
const links = document.querySelectorAll("nav a[href]");
links.forEach(
(link) =>
(link.onclick = (ev) => {
// 禁用a标签的默认行为
ev.preventDefault();
// history.pushState(状态对象,标题,url) 将url写到地址栏
history.pushState(null, "", link.href);
// 手动更新了url,但是popstate事件监听不到这个变化,需要这个调用一个函数
show();
})
);
window.addEventListener("popstate", show);
function show() {
// console.log(location.pathname);
switch (location.pathname) {
case "/list1":
routeView.innerHTML = list1;
break;
case "/list2":
routeView.innerHTML = list2;
break;
default:
routeView.innerHTML = list1;
}
}
</script>
这一波操作下来感觉官方支持的 vue-route 库更好理解