Vue2的路由和異步請求方式
1.路由
1.1路由的作用
在傳統(tǒng)的Web應(yīng)用中個,每個URL對應(yīng)網(wǎng)站中的一個頁面;但在SPA(單頁面應(yīng)用中),由于只有一個頁面,如果要實現(xiàn)不同URL在相同頁面顯示不同的路由,就需要根據(jù)URL來跟換Web組件,這需要額外的路由技術(shù)來實現(xiàn)。
例如以下三個頁面,頭部和底部都是相同的,而中間需要根據(jù)URL的不同,顯示不同的中間組件,這時就需要路由。
1.2使用CLI3創(chuàng)建帶路由功能的Vue2項目(案例)
(1)創(chuàng)建vue項目
vue create funnyshop‐vue2
(2)選擇手動設(shè)置特性(Manually select features)
(3)添加路由特性選項
(4)使用歷史模式路由等特性項目特性
1.3 路由使用入門
1.3.1 項目路由規(guī)劃
根據(jù)功能結(jié)構(gòu),我們可以把手機微商界面分割為若干個子組件。
具體子組件功能如下所示
組件名稱 | 功能描述 |
HeaderPart | 網(wǎng)頁頭部的導(dǎo)航和搜索框 |
FooterPart | 頁面底部的導(dǎo)航 |
ProductList | 產(chǎn)品列表 |
Login | 登錄 |
Cart | 購物車 |
ProductDetail | 產(chǎn)品詳情 |
(1)在index.html頁面中導(dǎo)入全局樣式(可選)
<!DOCTYPE HTML> <html lang="en"> <head> <meta charset="UTF‐8"> <title>Document</title> <meta name="viewport" content="width=device‐width, initial‐scale=1.0, maximum‐scale=1.0, minimum‐scale=1.0, user‐scalable=no" <link rel="stylesheet" href="<%= BASE_URL %>css/base.css" rel="external nofollow" > <link rel="stylesheet" href="<%= BASE_URL %>css/page.css" rel="external nofollow" > </head> <body> <div id="app"></div> </body> </html>
(2)項目根組件App.vue
在項目根組件中導(dǎo)入公共子組件(headerpart、footerpart)和根據(jù)路由加載的部分(routerview)
<template> <div class="pageWrapper"> <header‐part /> <div class="pageBreak"></div> <router‐view></router‐view> <div class="pageBreak"></div> <footer‐part /> </div> </template> <script> import HeaderPart from './components/HeaderPart.vue' import FooterPart from './components/FooterPart.vue' export default { name:"app", components:{HeaderPart, FooterPart} } </script>
其中不是我們定義的組件,而是vue的路由組件,只是一個占位符,用于顯示不同url下所 需要加載的變化部分。
1.3.2 路由映射定義
帶router的vue2項目創(chuàng)建后,src目錄下會多出一個名為“router.js”的文件,該文件用于定義路由規(guī)則, 也就是不同的URL路徑下所要加載的Vue子組件對應(yīng)關(guān)系和參數(shù)傳遞規(guī)則。
import Vue from 'vue' import Router from 'vue‐router' import ProductList from './components/ProductList.vue' import Login from './components/Login.vue' import ProductDetail from './components/ProductDetail.vue' import Cart from './components/Cart.vue' Vue.use(Router) export default new Router({ mode: 'history', base: process.env.BASE_URL, routes: [ { path: '/', name: 'home', component: ProductList }, { path: '/product‐list', name: 'product‐list', component: ProductList }, { path:'/login', name:'login', component: Login }, { path:'/product/:id', name:'product', component: ProductDetail }, { path:'/cart', name:'cart', component: Cart }, ] })
routes配置中的每一項代表一條路由規(guī)則。
path是URL路徑,可以定義路徑參數(shù)(如“/product/:id”中的id);name是路由名稱,用于引用; component指定加載的組件名稱。
完成組件劃分(*.vue)和路由映射(router.js)后,應(yīng)用就可以根據(jù)路由規(guī)則顯示不同的頁面內(nèi)容了。
1.3.3 通過路由連接(替代<a>)切換頁面內(nèi)容
傳統(tǒng)的超鏈接<a href="...">會使頁面發(fā)生同步跳轉(zhuǎn),在SPA應(yīng)用中只有一張頁面,內(nèi)容的切換全部是異 步方式的。
(1)通過<router-link> 組件實現(xiàn)“跳轉(zhuǎn)”
routerlink是一個路由組件,可以理解為異步的跳轉(zhuǎn)連接標(biāo)簽(<a>)
routerlink的to屬性可以設(shè)置切換的URL。to后面可以設(shè)置“靜態(tài)的URL”或者綁定“一個路由項對象”,例 如下面的兩個示例,前者設(shè)置URL,后者綁定一個定義了的路由對象。
<router‐link to="/login">登錄</router‐link> <router‐link :to="{name:'cart'}">購物車</router‐link>。
(2)通過推送路由變更$router.push(),從而實現(xiàn)“跳轉(zhuǎn)”
配置好路由的項目中,我們可以在任意Vue組件內(nèi)部,通過this.$router訪問路由對象,通過 $router.push()方法,我們可以向路由推送跳轉(zhuǎn),實現(xiàn)組件的切換。
this.$router.push({name:"product‐list", query:{"name":val}});
1.3.4 路由參數(shù)的獲取
(1)路徑參數(shù)與獲取 我們在路由映射中(router.js)定義了以下一項:
{ path:'/product/:id', name:'product', component: ProductDetail }
也就是在跳轉(zhuǎn)到ProductDetail組件時,我們會傳入名為id的路徑參數(shù)。
例如,在產(chǎn)品列表中有以下路由連接,點擊后實際的URL可能為 “/product/5”,其中5是id參數(shù)。
<router‐link :to="{name:'product',params:{id:item.id}}">產(chǎn)品1連接</router‐link>
這時,我們可以在目標(biāo)組件ProductDetail中,通過 “$route.params.參數(shù)名” 獲取到路徑參數(shù)值:
let id = this.$route.params.id;
(2)查詢字符串參數(shù)的獲取
路徑參數(shù)是URL路徑的一部分,通常只能用于傳遞必要參數(shù)(一定要提供的參數(shù)),對于可選參數(shù)就應(yīng) 該使用查詢字符串的方式來傳遞,例如:“search?name=abc&page=101”。
對于查詢字符串參數(shù),我們可以通過以下方式傳遞。
searchByProductName(e){ var val = e.target.value; this.$router.push({name:"product‐list", query:{"name":val}}); }
上述路由推送會產(chǎn)生類似這樣的URL:“productlist?name=xxxx” 這時,我們可以在目標(biāo)組件ProducList中,通過“$router.query.參數(shù)名”獲取查詢字符串參數(shù)值。
let searchName = this.$route.query.name
2 異步請求
2.1 后端RESTful Web服務(wù)和代理
(1)后端RESTful Web服務(wù)
SPA一般都采用前后端分離的開發(fā)方式。后端可以使用任何的服務(wù)器端Web技術(shù),諸如JavaEE、 PHP、Node.js、Python等等,后端提供基于RESTful風(fēng)格的Web服務(wù),接收前端請求并返回JSON格式 的數(shù)據(jù)。
這里使用基于Spring Boot的MVC技術(shù)提供后端服務(wù),具體細(xì)節(jié)略去,僅在這里描述所提供的服務(wù)接 口。
URL | 功能 |
http://localhost:9090/api/products/latest | 獲取最新的4種產(chǎn)品,返回JSON格式數(shù)據(jù) |
http://localhost:9090/api/products/1 | 獲取id=1的商品明細(xì)信息 |
http://localhost:9090/api/products?name=青瓷 | 模糊查詢名稱中包含“青瓷”的產(chǎn)品信息,返回 JSON格式數(shù)據(jù) |
具體請求效果如下圖所示。
(2)服務(wù)的代理
作為前后端分離的項目,后端和前端往往不是運行在同一個服務(wù)器中的。例如上述開發(fā)中,后端的 JavaEE服務(wù)是運行在Tomcat服務(wù)器(Spring Boot內(nèi)嵌的容器)中的,而前端則是使用Node.js提供的測 試服務(wù)器。前者域名為“localhost:9090”,而后者是“localhost:3000”。這時,如果前端通過AJAX技術(shù)請 求后端數(shù)據(jù),就會遇到JavaScript請求不能跨域執(zhí)行的問題而無法請求。要解決這個問題,要么就需要 使用jsonp協(xié)議(跨域JSON協(xié)議),要么就要把前后端兩個服務(wù)器通過代理服務(wù)器代理到同一個域名之 下。在實際部署中,我們可以通過Nginx等靜態(tài)資源服務(wù)器實現(xiàn)代理,而在開發(fā)中Vue項目可以直接配置 后端代理,把lcoalhost:9090的域名請求代理到localhost:3000域名之下。
在項目根目錄下添加 “vue.config.js” 文件,這時vue項目的配置文件,在其中可以設(shè)置開發(fā)服務(wù)器的端 口 “port” 和后端Web服務(wù)的代理“proxy”。
module.exports = { devServer: { port: 3000, proxy: { '/api': { target: 'http://localhost:9090', // target host }, } } };
如上所示,當(dāng)我們請求 “localhost:3000/api/xxx” 時,請求被代理到了 “http://localhost:9090/api/xxx”, 這樣前后端就不存在跨域問題了。
2.2 使用 axois 組件請求后端數(shù)據(jù)
(1)Promise與fetch API
傳統(tǒng)的靜態(tài)網(wǎng)頁是通過XMLHttpRequest對象實現(xiàn)對后端數(shù)據(jù)的異步請求的(例如jQuery的$.ajax),請 求成功后需要執(zhí)行回調(diào)函數(shù)。
這種傳統(tǒng)的回調(diào)在復(fù)雜的使用環(huán)境中往往會一個接一個的嵌套,讓代碼陷入難以維護(hù)的“Callback地 獄”。新一代的JavaScript(ES6),不再建議使用XMLHttpRequest,而是用一種叫Promise的方式組織 代碼,讓我們不用陷入到回調(diào)的連環(huán)套中,而是用平面的方式來處理所有回調(diào)。新一代的瀏覽器中都支 持一個名為fetch的API方法,可以實現(xiàn)Promise方式的請求。
(2)axios組件
fetch API雖然基于Promise已經(jīng)很好用了,但fetch功能還是過于原始,在實際應(yīng)用中我們可能還需要一 些攔截器等擴(kuò)展模塊。
為此 vue 的作者推薦我們使用一個名為 axios 的JavaScript擴(kuò)展包來實現(xiàn)后臺請 求功能。axios有良好的Promise和攔截器機制。
2.3 axios的使用
axios的詳細(xì)使用請參考互聯(lián)網(wǎng) https://www.npmjs.com/package/axios,這里只是簡單介紹。
(1)為Vue項目添加axios
在項目根目錄中執(zhí)行以下Node指令:
vue add axios
(2)axios基本用法
Method | Api |
Get | axios.get(url).then(successCallback).catch(errorHandler) |
Post | axios.post(url, data).then(successCallback).catch(errorHandler) |
Put | axios.put(url, data).then(successCallback).catch(errorHandler) |
Delete | axios.delete(url).then(successCallback).catch(errorHandler) |
(3)axios的攔截器
axios可以在(組件的)請求或相應(yīng)處理的之前插入攔截器,統(tǒng)一處理異步請求中的公共問題。
例如我們可以在react程序入口“index.js”中添加如下代碼,統(tǒng)一在請求發(fā)出前添加jwt請求頭,或者在響 應(yīng)出錯時定位到頁面。
import axios from 'axios'; //請求前處理 axios.interceptors.request.use( config => { const token = window.localStorage.getItem("jwt‐token"); if(token) config.headers={'Authorization': 'Bearer '+token}; return config; }, error=>{ return Promise.reject(error); } ); //響應(yīng)前處理 axios.interceptors.response.use( response => { return response; }, error => { const httpCode = error.response.status; if(httpCode>=400 && httpCode<600){ window.location.href="/error" rel="external nofollow" ; } return Promise.reject(error); } );
2.4 在項目中實現(xiàn)請求
下面演示了ProductList組件中如何向后端請求商品信息。
<template> <div class="contentWrapper"> <h4 class="contentTitle">新品上架:</h4> <div class="productListWrapper"> <div class="productWrapper" v‐for="(item,i) in products" :key="i"> <router‐link :to="{name:'product',params:{id:item.id}}"> <img :src="'images/content/'+item.id+'‐1.jpg'" alt=""/> </router‐link> <div class="productInfoWrapper"> <span class="productTitle">{{item.name}}</span> <a class="purchaseButton">¥{{item.unitPrice}} 購買</a> </div> </div> </div> </div> </template> <script> export default { name: 'product‐list', data(){ return { products:[] }; }, mounted(){ this.fetchData(); }, methods:{ fetchData(){ if(this.$route.query.name){ this.axios.get("/api/products?name="+this.$route.query.name).then(res=>this }else{ this.axios.get("/api/products/latest").then(res=>this.products=res.data); } } } } </script>
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
vue路由傳參方式的方式總結(jié)及獲取參數(shù)詳解
vue 路由傳參的使用場景一般都是應(yīng)用在父路由跳轉(zhuǎn)到子路由時,攜帶參數(shù)跳轉(zhuǎn),下面這篇文章主要給大家介紹了關(guān)于vue路由傳參方式的方式總結(jié)及獲取參數(shù)的相關(guān)資料,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-07-07詳解用webpack2.0構(gòu)建vue2.0超詳細(xì)精簡版
本篇文章主要介紹了詳解用webpack2.0構(gòu)建vue2.0超詳細(xì)精簡版,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-04-04詳解在vue-cli項目中使用mockjs(請求數(shù)據(jù)刪除數(shù)據(jù))
本篇文章主要介紹了在vue-cli項目中使用mockjs(請求數(shù)據(jù)刪除數(shù)據(jù)),具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-10-10Vue內(nèi)聯(lián)處理器中訪問方法和訪問事件參數(shù)詳解
在 Vue 3 中,使用組合式 API 時,可以通過內(nèi)聯(lián)事件處理器來直接在模板中編寫事件處理邏輯,內(nèi)聯(lián)事件處理器不僅可以直接執(zhí)行簡單的操作,還可以調(diào)用組件中的方法,并訪問事件參數(shù),下面將詳細(xì)講解如何在內(nèi)聯(lián)事件處理器中調(diào)用方法以及訪問事件參數(shù),需要的朋友可以參考下2024-12-12前端實現(xiàn)Vue組件頁面跳轉(zhuǎn)的多種方式小結(jié)
這篇文章主要為大家詳細(xì)介紹了前端實現(xiàn)Vue組件頁面跳轉(zhuǎn)的多種方式,文中的示例代碼講解詳細(xì),具有一定的參考價值,有需要的小伙伴可以了解下2024-02-02