1. 路由介绍
我们可以总结一下从早期网站开发到现代单页应用(SPA)的发展过程及其关键概念:
-
早期的服务器端渲染 (SSR):
-
早期的网站开发中,服务器负责生成完整的 HTML 页面,并将其发送给客户端展示。
-
每个 URL 对应一个特定的控制器(Controller),该控制器负责处理请求并生成相应的 HTML 内容。
-
这种方式有利于搜索引擎优化(SEO),因为搜索引擎可以轻松抓取完整的 HTML 内容。
-
缺点是页面更新时需要重新加载整个页面,导致用户体验不佳,且 HTML 和业务逻辑混杂在一起,难以维护。
-
-
前后端分离:
-
随着 Ajax 技术的出现,前后端分离成为可能。
-
在这种模式下,后端提供 API 接口返回数据,前端通过 JavaScript (如 Ajax 请求) 获取这些数据,并动态地渲染到用户界面上。
-
这种模式提高了开发效率,使前后端职责更加清晰,后端专注于数据处理,前端专注于 UI 和交互。
-
这种模式也适用于移动应用开发,因为后端可以提供统一的数据接口供不同平台调用。
-
-
单页应用 (SPA):
-
SPA 是一种构建 Web 应用的方式,它使用单一 HTML 页面,并依赖 JavaScript 动态更新页面的不同部分。
-
SPA 使用前端路由来管理页面状态,这意味着用户在应用内导航时,浏览器地址栏中的 URL 会改变,但不会触发页面的整体重载。
-
这种方式提供了更好的用户体验,因为它减少了页面加载时间和上下文切换的感觉。
-
SPA 的实现通常涉及到前端框架如 Vue.js、React 或 Angular,它们都提供了相应的路由管理解决方案(例如 Vue Router)。
-
-
前端路由:
URL和前端页面的映射关系。
-----> vue router前端路由的核心是什么呢?
改变URL,但是页面不进行整体的刷新。
2. 前端路由的核心:改变URL,但是页面不进行整体的刷新
在单页应用(SPA)中,前端路由的核心是改变URL的同时,不进行页面的整体刷新。这使得应用能够提供更加流畅的用户体验,类似于桌面应用。前端路由的实现主要有两种方式:使用URL的hash和使用HTML5的history API。
1. URL的hash
URL的hash指的是URL中#符号后面的部分。例如,http://example.com/#/about
中的#/about
就是hash部分。使用hash可以改变URL而不触发页面的刷新。
基本操作:
-
设置hash:
window.location.hash = '#/home';
这会将URL设置为
http://example.com/#/home
,但页面不会重新加载。 -
监听hash变化:
window.addEventListener('hashchange', () => { console.log('Hash changed:', window.location.hash); });
通过监听
hashchange
事件,我们可以在hash变化时执行相应的逻辑。
2. HTML5的history API
HTML5的history API提供了一组方法来操作浏览器的历史记录,而不触发页面的刷新。主要方法包括pushState
、replaceState
、back
、forward
和go
。
基本操作:
-
pushState:
history.pushState({}, '', '/home');
这会将一个新的条目添加到浏览器历史记录栈中,并将URL设置为
/home
,但不会触发页面刷新。 -
replaceState:
history.replaceState({}, '', '/home');
这会替换当前的历史记录条目,而不是添加一个新的条目。
-
back、forward和go:
history.back(); // 相当于 history.go(-1) history.forward(); // 相当于 history.go(1) history.go(-1); // 后退一页 history.go(1); // 前进一页
监听popstate事件:
当使用pushState
或replaceState
改变URL时,不会触发popstate
事件。但当用户点击浏览器的后退或前进按钮时,会触发popstate
事件。
window.addEventListener('popstate', (event) => { console.log('Location changed:', window.location.pathname); });
3. 路由的基本使用
3.1 声明式导航-导航链接
在现代前端框架(如Vue.js、React等)中,声明式导航是一种通过定义导航链接来处理页面路由的方式。声明式导航使用HTML标签和框架提供的组件来定义页面间的导航,而不是通过编写JavaScript代码来进行页面跳转。这使得代码更简洁、易读和易于维护。
Vue.js 中的声明式导航
Vue.js 提供了 vue-router
这个库来处理路由。通过 vue-router
,我们可以使用 <router-link>
组件来定义导航链接。
首先,定义路由配置:
// router.js
import Vue from 'vue';
import Router from 'vue-router';
import Home from './components/Home.vue';
import About from './components/About.vue';Vue.use(Router);export default new Router({routes: [{path: '/',name: 'Home',component: Home},{path: '/about',name: 'About',component: About}]
});
然后,在模板中使用 <router-link>
进行声明式导航:
<template><div><nav><router-link to="/">Home</router-link><router-link to="/about">About</router-link></nav><router-view></router-view></div>
</template>
在这个例子中,<router-link>
组件会生成相应的 <a>
标签,并自动处理导航逻辑。当用户点击链接时,URL 会更新,但不会触发页面刷新。
3.2 声明式导航-查询参数传参
在现代前端框架Vue.js中,声明式导航不仅可以用于定义简单的页面导航链接,还可以通过查询参数传递数据。这种方式允许我们在导航链接中包含参数,从而使目标页面能够根据传递的参数进行不同的处理。
在 Vue.js 中,我们可以使用 vue-router
的 query
选项来传递查询参数。
首先,定义路由配置:
// router.js
import Vue from 'vue';
import Router from 'vue-router';
import Home from './components/Home.vue';
import About from './components/About.vue';Vue.use(Router);export default new Router({routes: [{path: '/',name: 'Home',component: Home},{path: '/about',name: 'About',component: About}]
});
然后,在模板中使用 <router-link>
进行声明式导航,并传递查询参数:
<template><div><nav><router-link :to="{ path: '/about', query: { id: 123 }}">About</router-link></nav><router-view></router-view></div>
</template>
在目标组件中,您可以通过 $route.query
来获取查询参数:
// About.vue
<template><div><h1>About Page</h1><p>Query ID: {{ id }}</p></div>
</template><script>
export default {computed: {id() {return this.$route.query.id;}}
};
</script>
3.3 声明式导航-动态路由传参
3.3.1 动态路由传参方式
配置动态路由
- 动态路由后面的参数可以随便起名,但要有语义
const router = new VueRouter({routes: [...,{ path: '/search/:words', component: Search }]})
配置导航链接
- to="/path/参数值
对应页面组件接受参数
- $route.params.参数名
- params后面的参数名要和动态路由配置的参数保持一致
3.3.2 查询参数传参 VS 动态路由传参
查询参数传参 (比较适合传多个参数)
- 跳转:to="/path?参数名=值&参数名2=值"
- 获取:$route.query.参数名
动态路由传参 (优雅简洁,传单个参数比较方便)、
- 配置动态路由:path: "/path/:参数名"
- 跳转:to="/path/参数值"
- 获取:$route.params.参数名
3.4 编程式导航-两种路由跳转方式
3.5 编程式导航-name命名路由传参
1.name 命名路由跳转传参 (query传参)
this.$router.push({name: '路由名字',query: {参数名1: '参数值1',参数名2: '参数值2'}})
2.name 命名路由跳转传参 (动态路由传参)
this.$router.push({name: '路由名字',params: {参数名: '参数值',}})