<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Vue路由 on Last Stand</title><link>https://amatsuzero.github.io/LastStand/tags/vue%E8%B7%AF%E7%94%B1/</link><description>Recent content in Vue路由 on Last Stand</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Tue, 17 Dec 2024 00:00:00 +0800</lastBuildDate><atom:link href="https://amatsuzero.github.io/LastStand/tags/vue%E8%B7%AF%E7%94%B1/index.xml" rel="self" type="application/rss+xml"/><item><title>vue路由</title><link>https://amatsuzero.github.io/LastStand/posts/frontend/vue/vue-018/</link><pubDate>Sat, 05 Oct 2024 00:00:00 +0800</pubDate><guid>https://amatsuzero.github.io/LastStand/posts/frontend/vue/vue-018/</guid><description>&lt;h2 id="从后端路由开始"&gt;从后端路由开始&lt;/h2&gt;
&lt;p&gt;路由这个概念最先是后端出现的。在以前用模板引擎开发页面时，经常会看到这样&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;http://www.xxx.com/login
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;大致流程可以看成这样：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;浏览器发出请求&lt;/li&gt;
&lt;li&gt;服务器监听到80端口（或443）有请求过来，并解析url路径&lt;/li&gt;
&lt;li&gt;根据服务器的路由配置，返回相应信息（可以是 html 字串，也可以是 json 数据，图片等）&lt;/li&gt;
&lt;li&gt;浏览器根据数据包的 Content-Type 来决定如何解析数据&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;简单来说路由就是用来跟后端服务器进行交互的一种方式，通过不同的路径，来请求不同的资源，请求不同的页面是路由的其中一种功能。&lt;/p&gt;
&lt;h2 id="前端路由"&gt;前端路由&lt;/h2&gt;
&lt;h4 id="1-hash-模式"&gt;1. hash 模式&lt;/h4&gt;
&lt;p&gt;随着 ajax 的流行，异步数据请求交互运行在不刷新浏览器的情况下进行。而异步交互体验的更高级版本就是 SPA —— 单页应用。单页应用不仅仅是在页面交互是无刷新的，连页面跳转都是无刷新的，为了实现单页应用，所以就有了前端路由。 类似于服务端路由，前端路由实现起来其实也很简单，就是匹配不同的 url 路径，进行解析，然后动态的渲染出区域 html 内容。但是这样存在一个问题，就是 url 每次变化的时候，都会造成页面的刷新。那解决问题的思路便是在改变 url 的情况下，保证页面的不刷新。在 2014 年之前，大家是通过 hash 来实现路由，url hash 就是类似于：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;http://www.xxx.com/#/login
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这种 #。后面 hash 值的变化，并不会导致浏览器向服务器发出请求，浏览器不发出请求，也就不会刷新页面。另外每次 hash 值的变化，还会触发&lt;code&gt;hashchange&lt;/code&gt; 这个事件，通过这个事件我们就可以知道 hash 值发生了哪些变化。然后我们便可以监听&lt;code&gt;hashchange&lt;/code&gt;来实现更新页面部分内容的操作：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;matchAndUpdate&lt;/span&gt; () {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// todo 匹配 hash 做 dom 更新操作
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;window.&lt;span style="color:#a6e22e"&gt;addEventListener&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;hashchange&amp;#39;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;matchAndUpdate&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="2-history-模式"&gt;2. history 模式&lt;/h4&gt;
&lt;p&gt;14年后，因为HTML5标准发布。多了两个 API，&lt;code&gt;pushState&lt;/code&gt; 和 &lt;code&gt;replaceState&lt;/code&gt;，通过这两个 API 可以改变 url 地址且不会发送请求。同时还有&lt;code&gt;popstate&lt;/code&gt; 事件。通过这些就能用另一种方式来实现前端路由了，但原理都是跟 hash 实现相同的。用了 HTML5 的实现，单页路由的 url 就不会多出一个#，变得更加美观。但因为没有 # 号，所以当用户刷新页面之类的操作时，浏览器还是会给服务器发送请求。为了避免出现这种情况，所以这个实现需要服务器的支持，需要把所有路由都重定向到根页面。&lt;/p&gt;</description></item></channel></rss>