Vue-router路由 什麼是vue-router? 服務端路由指的是伺服器根據用戶訪問的 URL 路徑返回不同的響應結果。當我們在一個傳統的服務端渲染的 web 應用中點擊一個鏈接時,瀏覽器會從服務端獲得全新的 HTML,然後重新載入整個頁面。 然而,在單頁面應用中,客戶端的 JavaScrip ...
Vue-router路由
什麼是vue-router?
服務端路由指的是伺服器根據用戶訪問的 URL 路徑返回不同的響應結果。當我們在一個傳統的服務端渲染的 web 應用中點擊一個鏈接時,瀏覽器會從服務端獲得全新的 HTML,然後重新載入整個頁面。
然而,在單頁面應用中,客戶端的 JavaScript 可以攔截頁面的跳轉請求,動態獲取新的數據,然後在無需重新載入的情況下更新當前頁面。這樣通常可以帶來更順滑的用戶體驗,尤其是在更偏向“應用”的場景下,因為這類場景下用戶通常會在很長的一段時間中做出多次交互。
在這類單頁應用中,“路由”是在客戶端執行的。一個客戶端路由器的職責就是利用諸如 History API 或是 hashchange
事件這樣的瀏覽器 API 來管理應用當前應該渲染的視圖。
簡單來說,vue-router實現的是一個頁面,且頁面不變,只是內容在改變,由於頁面是由一個一個的組件堆積起來的,所以,vue-router不用改變頁面,它只需要將頁面內的組件更換就可以了,對於單個頁面來講,可以有很高的復用性,我們只需要關註組件的開發,前端的頁面永遠不會改,改變的只是路由引入的一個個組件。
安裝vue-router
如果一開始你是使用 npm init 命令來初始化的myvue項目,則是使用
npm install vue-router --save-dev
如果使用的是cnpm init初始化的,則使用
cnpm install vue-router --save-dev
註意下載一定要在myvue項目下,或者你初始化的那個項目名路徑下,一定不要隨便一個路徑就安裝
工程化模塊的使用
在使用一個模塊化工程的時候,必須要通過Vue.use()明確的安裝路由功能
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter);
import VueRouter from 'vue-router'
vue-router:就是剛剛下載的那個router,在此js文件下,使用VueRouter來代替它 這句話和Java的new關鍵字很像
VueRouter:在此js文件下使用這個名字來完成路由的功能,vue-router的功能被映射到VueRouter的身上了
Vue.use():此方法在引入官方的模塊工程後有,就好比Java的顯式聲明,無聲明是使用不了這個工程化模塊的
Vue-router測試
第一步:優化初始化項目
在使用 vue init webpack myvue一個項目後,其中很多的都是官方自帶了,我們需要的是一個乾凈的項目,所以需要刪除其它的文件
比如:assets包下全部刪除,components包下全部刪除
第二步:編寫一個自定義組件Content.vue和main.vue
組件的位置都是放在componemts包下的,我們上一步已經清理了此包,所以應該只有新建的這個組件
代碼內容:
<!--conten.vue--> <template> <div id="di1"> <h1>此是內容頁</h1> <h2>且它位於Content組件中</h2> </div> </template> <script> export default { name: "Content" } </script> <style scoped> #di1{ width: 200px; height: 80px; border: 2px solid blue; border-radius: 50px; margin: 10px auto; } h1{ color: aqua; } </style> <!--main.vue--> <template> <div id="di1"> <h1>此是主頁頁</h1> <h2>且它位於main組件中</h2> </div> </template> <script> export default { name: "main" } </script> <style scoped> #di1{ width: 200px; height: 80px; border: 2px solid red; border-radius: 50px; margin: 20px auto; } h1{ color: #8c4949; } </style>
第三步:在src建立route目錄
在此目錄建立index.js,用於建立路由路徑指向
代碼展示:
import Vue from "vue"; // 導入路由插件 import Router from 'vue-router'; //導入自定義定義的組件 import Content from "../components/Content"; import main from "../components/main"; Vue.use(Router); //配置路由 export default new Router({ routes: [ { //路由路徑 path: '/content', //路由名稱 name: 'context', //跳轉到的組件 component: Content }, { //路由路徑 path: '/main', //路由名稱 name: 'main', //跳轉到的組件 component: main } ] });
第四步:在main.js下引入路由屬性
代碼展示:
import Vue from 'vue' import App from './App' // 導入自定義的路由條目 import router from "./router"; //關閉生產模式給出的提示 Vue.config.productionTip = false /* eslint-disable no-new */ new Vue({ el: '#app', //配置路由,引入路由屬性 router, components: { App }, template: '<App/>' })
第五步:在App.vue中使用
使用此模板一定要註意配置,這是首頁,展示這塊就需要在這裡搭建模板
代碼展示:
<template> <div id="app"> <h1>Vur-Router</h1> <router-link to="/main">首頁</router-link> <router-link to="/content">內容頁</router-link> <!-- 請求到組件--> <router-view></router-view> <!-- 顯示組件--> </div> </template> <script> export default { name: 'App', } </script> <style> #app { font-family: 'Avenir', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>
第六步:使用路由
使用以下命令打包web
npm run dev
如果打包不成功,但是前面第一個初始項目是可以跑起來的話,很可能是vue-route版本不匹配,可以網上搜索vue-cil ,npm ,vue-route三個的版本區間
我這裡使用的是[email protected]版本是可以打包的
//先卸載以前的版本 npm uninstall vue-router //安裝.5 npm install [email protected]
如果還不行,可以自己去搜索三者版本推薦,或者參考下方:
- Vue CLI 4.5以下,對應的是Vue2;
- Vue CLI 4.5及以上,對應的是Vue3,也可以手動選擇Vue2 vue;
- 3.0以下相容的是element-ui前端組件庫;
- vue 3.0相容的是element-plus前端組件庫;
- vue2搭配vue-router3;
- vue3搭配vue-router4
ElementUI - Vue組合開發
elementUI地址:https://element.eleme.cn/#/zh-CN/component/layout
準備工作:
使用windos命令行準備
初始化一個項目:
vue init webpack hello-vue
進入新的目錄:
cd hello-vue
安裝vue-router
//國外鏡像
npm install vue-router --save-dev
//國內淘寶鏡像
cnpm install vue-router --save-dev
安裝elementUI
//國外鏡像
npm i elemnet-ui -S
//國內鏡像
cnpm i elemnet-ui -S
安裝vue環境依賴
//國外鏡像
npm install
//國內鏡像
cnpm install
啟動測試
npm run dev
部分npm命令解釋
- npm install moduleName :安裝模塊到項目下
- npm install -g moduleName:-g 是將模塊安裝到全局,具體安裝到那個位置,還需要看npm config prefix的位置
- npm install --save moduleName:--save是安裝模塊到項目目錄下,併在package文件的dependencies寫入依賴,-S為此命令的縮寫
- npm install --save-dev moduleName:--save-dev的意思是將模塊安裝到項目目錄下,併在package文件的devDependencies結點寫入依賴,-D為此命令的縮寫
實施組合開發
項目結構簡介:
- assets:用於存放資源文件
- components:用於存放Vue功能組件
- views:用於存放Vue視圖組件
- router:用於存放vue-router配置
確保項目中一開始就創建了以上目錄
第一步:在views目錄下,創建一個名為Main.vue的視圖組件
代碼展示:
<template> <div id="di"> <h1> 這是首頁</h1> </div> </template> <script> export default { name: "main" } </script> <style scoped> #di{ width: 400px; height: 300px; color: aqua; border: 2px solid blue; border-radius: 50px; margin: 0 auto; } </style>
第二步:在views目錄下,繼續創建一個Login.vue的視圖組件
此組件可以導入一些ElementUI的組件,其中el-*就是element組件的標識
代碼展示:
<template> <el-form :model="dynamicValidateForm" ref="dynamicValidateForm" label-width="100px" class="demo-dynamic"> <el-form-item prop="email" label="郵箱" :rules="[ { required: true, message: '請輸入郵箱地址', trigger: 'blur' }, { type: 'email', message: '請輸入正確的郵箱地址', trigger: ['blur', 'change'] } ]" > <el-input v-model="dynamicValidateForm.email"></el-input> </el-form-item> <el-form-item v-for="(domain, index) in dynamicValidateForm.domains" :label="'功能變數名稱' + index" :key="domain.key" :prop="'domains.' + index + '.value'" :rules="{ required: true, message: '功能變數名稱不能為空', trigger: 'blur' }" > <el-input v-model="domain.value"></el-input><el-button @click.prevent="removeDomain(domain)">刪除</el-button> </el-form-item> <el-form-item> <el-button type="primary" @click="submitForm('dynamicValidateForm')">提交</el-button> <el-button @click="addDomain">新增功能變數名稱</el-button> <el-button @click="resetForm('dynamicValidateForm')">重置</el-button> </el-form-item> </el-form> </template> <script> export default { data() { return { dynamicValidateForm: { domains: [{ value: '' }], email: '' } }; }, methods: { submitForm(formName) { this.$refs[formName].validate((valid) => { if (valid) { alert('submit!'); this.$route.push("/main"); return true; } else { console.log('error submit!!'); return false; } }); }, resetForm(formName) { this.$refs[formName].resetFields(); }, removeDomain(item) { var index = this.dynamicValidateForm.domains.indexOf(item) if (index !== -1) { this.dynamicValidateForm.domains.splice(index, 1) } }, addDomain() { this.dynamicValidateForm.domains.push({ value: '', key: Date.now() }); } } } </script>
第三步:在router目錄下,新建index.js編寫路由指向
代碼展示:
import Vue from 'vue';
import Router from 'vue-router';
import Login from "../views/Login.vue";
import Main from "../views/main.vue";
Vue.use(Router);
export default new Router({
routes: [
{
//登錄項
path: '/login',
name: 'login',
component: Login
},
{
path: '/main',
name: 'main',
component: Main
}
]
});
第四步:在mian.js中配置路由屬性,並配置ElementUI
在main.js中配置的是啟動項,像路由和elementUI都是需要導入的,不然是找不到屬性的
代碼展示:
import Vue from 'vue'
import router from "./router";
Vue.config.productionTip = false
import ElementUI from 'element-ui'; //導入ElementUI
import 'element-ui/lib/theme-chalk/index.css';//使用ElementUI的css庫
import App from './App.vue';
Vue.use(ElementUI); //導入,使用Vue.use方法使用後,才能配置屬性
Vue.use(router);
new Vue({
el: '#app',
router,//配置路由屬性
render: h => h(App) //配置elementUI屬性,這是elemenUI官網的寫法,詳情參照官網
});
第五步:編寫App.vue組件
此組件是main.js的組件,也是index.html第一就會載入的組件,所以需要考慮的是項目初次進入應該展示什麼
這裡測試項目可以不用展示,主要是展示其它組件,所以我只留下了<router-view>標簽,用於在請求到其它組件時呈現此組件
代碼展示:
<template> <div id="app"> <router-view></router-view> <!-- 組件內容展示,通過改變地址欄請求,獲取組件:/login;/main--> </div> </template> <script> export default { name: 'App', } </script> <style> </style>
第六步:打包,測試
使用一下命令:
npm run dev
註意:如果打包失敗,最大的可能是版本不相容,也就是:sass-loader 版本過高了,需要降低版本
在package.json文件中,找到"sass-loader": "^13.3.2" 這一項,更改後面^13.3.2為^8.0.0或者^7.3.1
在使用一些命令重新更新環境
//初始化使用 npm 初始的環境
npm install
//初始化使用cnpm初始的環境
cnpm install
如果還是打包失敗,請上百度搜索
Vue路由嵌套
嵌套路由,又稱子路由,在實際引用中,通常使用多個嵌套的組件構成的,同樣的,URL中各種動態路徑也按照某種結構對應嵌套的各層組件
使用嵌套路由的好處是,子路由的父級路由組件依舊可以存在,在不使用嵌套路由的情況下,預設只會在當前路由中的組件,換言之,如果在此頁面上,你想顯示多個組件,但是它們有分佈在不同的vue模塊中,就可以使用嵌套路由
嵌套路由雖然可以使多個組件同時存在於頁面上,但是一定要處理每個子路由組件的位置,不然頁面會很難看
嵌套路由配置的關鍵字:
export default new Router({
routes: [
{
//登錄項
path: '/login',
name: 'login',
component: Login
},
{
path: '/main',
name: 'main',
component: Main,
children: [ //嵌套路由,它們會在mian.vue組件下,繼續顯示
{
path:'/user',
name: 'user',
component: user
},
{
path:'/nav',
name: 'nav',
component: navigation
}
]
}
]
});
children關鍵字就是配置嵌套路由的,它可以使得父組件和子組件在同一頁面同時顯示
main.vue組件構建
代碼展示:
<template> <div> <el-container> <el-aside width="200px"> <el-menu :default-openeds="['1']"> <el-submenu index="1"> <template slot="title"><i class="el-icon-caret-right"></i>用戶管理</template> <el-menu-item-group> <el-menu-item index="1-1"> <router-link to="/user">個人信息</router-link><!--呼出,子路由1 user組件--> </el-menu-item> <el-menu-item index="1-2"> <router-link to="/nav">用戶列表</router-link><!--呼出,子路由2 navigation組件--> </el-menu-item> </el-menu-item-group> </el-submenu> <el-submenu index="2"> <template slot="title"><i class="el-icon-caret-right"></i>內容管理</template> <el-menu-item-group> <el-menu-item index="2-1">分類管理</el-menu-item> <el-menu-item index="2-2">內容列表</el-menu-item> </el-menu-item-group> </el-submenu> </el-menu> </el-aside> <el-container> <el-header style="text-align: right; font-size: 12px;"> <el-dropdown> <i class="el-icon-setting" style="margin-right: 15px;"></i> <el-dropdown-menu slot="dropdown"> <el-dropdown-item>個人信息</el-dropdown-item> <el-dropdown-item>退出登陸</el-dropdown-item> </el-dropdown-menu> </el-dropdown> </el-header> <el-main> <router-view/> <!-- 子路由出現的位置,也是其組件內容擺放的地方 --> </el-main> </el-container> </el-container> </div> </template> <script> export default { name:"main" } </script>
被註釋的地方就是嵌套路由的設置地方
由於使用的elementUI組件,所以自己的配置相對來說就很少了
路由參數傳遞及重定向
參數傳遞需要更改三個地方:
- 傳遞參數的組件:需要定義參數名,以及使用v-bind綁定一個對象,有參數後 to 後面就不知一個地址了,還有參數,所以是一個對象,需要v-bind綁定,參數屬性,params
- 路由文件配置:需要在接收路由上配置結構參數名,使用字元串拼接 /:參數名,並開啟可以接收參數的開關,props:true
- 接收參數的組件:在<script>標簽中,配置props:[ ' 接收參數名' ]
註意:參數傳遞都是route模塊在做,所以傳遞的時候會在<router-link>標簽內
傳遞參數的組件
<router-link v-bind:to="{name:'user',params:{id:1}}">個人信息</router-link>
name屬性:參數要去的組件名或者路徑
params:參數對象,以key:value的形式存在,傳遞參數的變數,可以傳送多個
路由文件配置
{
path:'/user/:id',
name: 'user',
component: user,
props: true
}
在路徑上要進行字元串拼接,同步傳輸路徑 /:id ,傳遞參數為 id
props: true ,允許此組件接收參數
接收參數的組件
<template> <diV> <h1>用戶名單</h1> <h1>用戶ID:{{id}}</h1> </diV> </template> <script> export default { props: ['id'], name: "user" } </script>
props:[ 'id'] ,接收參數
{{id}} :取參數
重定向redirect
這個配置也是寫在路由配置中的,和正常的條目是一樣書寫的,只是內部的屬性不一樣
{
path: '/goMain',
redirect: '/main'
}
path:請求重定向的路徑,此路徑被點擊後便可以觸發重定向
redirect:重定向到哪裡去,後面跟重定向的新地址
拓展:重定向和轉發的區別
- 重定向地址欄會發生改變,重定向到新的地址
- 轉發地址欄不會改變,轉發請求