詳解VueRouter 路由
vue router
1、認(rèn)識(shí)路由的概念
1.1、何為路由
通過(guò)互聯(lián)的網(wǎng)絡(luò)把信息從源地址傳輸?shù)侥康牡刂返幕顒?dòng).
1.2、后端路由階段
早期的網(wǎng)站開(kāi)發(fā)整個(gè)HTML頁(yè)面是由服務(wù)器來(lái)渲染的.
服務(wù)器直接生產(chǎn)渲染好對(duì)應(yīng)的HTML頁(yè)面, 返回給客戶端進(jìn)行展示.
但是, 一個(gè)網(wǎng)站, 這么多頁(yè)面服務(wù)器如何處理呢?
一個(gè)頁(yè)面有自己對(duì)應(yīng)的網(wǎng)址, 也就是URL.
URL會(huì)發(fā)送到服務(wù)器, 服務(wù)器會(huì)通過(guò)正則對(duì)該URL進(jìn)行匹配, 并且最后交給一個(gè)Controller進(jìn)行處理.
Controller進(jìn)行各種處理, 最終生成HTML或者數(shù)據(jù), 返回給前端.
這就完成了一個(gè)IO操作.
上面的這種操作, 就是后端路由.
當(dāng)我們頁(yè)面中需要請(qǐng)求不同的路徑內(nèi)容時(shí), 交給服務(wù)器來(lái)進(jìn)行處理, 服務(wù)器渲染好整個(gè)頁(yè)面, 并且將頁(yè)面返回給客戶端
這種情況下渲染好的頁(yè)面, 不需要單獨(dú)加載任何的js和css, 可以直接交給瀏覽器展示, 這樣也有利于SEO的優(yōu)化.
后端路由的缺點(diǎn):
一種情況是整個(gè)頁(yè)面的模塊由后端人員來(lái)編寫(xiě)和維護(hù)的.
另一種情況是前端開(kāi)發(fā)人員如果要開(kāi)發(fā)頁(yè)面, 需要通過(guò)PHP和Java等語(yǔ)言來(lái)編寫(xiě)頁(yè)面代碼.
而且通常情況下HTML代碼和數(shù)據(jù)以及對(duì)應(yīng)的邏輯會(huì)混在一起, 編寫(xiě)和維護(hù)都是非常糟糕的事情.
1.3、前端路由階段
前后端分離階段:
隨著Ajax的出現(xiàn), 有了前后端分離的開(kāi)發(fā)模式.
后端只提供API來(lái)返回?cái)?shù)據(jù), 前端通過(guò)Ajax獲取數(shù)據(jù), 并且可以通過(guò)JavaScript將數(shù)據(jù)渲染到頁(yè)面中.
這樣做最大的優(yōu)點(diǎn)就是前后端責(zé)任的清晰, 后端專注于數(shù)據(jù)上, 前端專注于交互和可視化上.
并且當(dāng)移動(dòng)端(iOS/Android)出現(xiàn)后, 后端不需要進(jìn)行任何處理, 依然使用之前的一套API即可.
目前很多的網(wǎng)站依然采用這種模式開(kāi)發(fā).
單頁(yè)面富應(yīng)用階段:
其實(shí)SPA最主要的特點(diǎn)就是在前后端分離的基礎(chǔ)上加了一層前端路由.
也就是前端來(lái)維護(hù)一套路由規(guī)則.
前端路由的核心是什么呢?
改變URL,但是頁(yè)面不進(jìn)行整體的刷新。
如何實(shí)現(xiàn)呢?
1.4、前端渲染和后端渲染?
前端渲染:服務(wù)器直接生產(chǎn)渲染好對(duì)應(yīng)的HTML頁(yè)面, 返回給客戶端進(jìn)行展示。比如:jsp頁(yè)面
后端渲染:后端返回JSON數(shù)據(jù),前端利用預(yù)先寫(xiě)的html模板,循環(huán)讀取JSON數(shù)據(jù),拼接字符串,并插入頁(yè)面。
2、前端路由的規(guī)則
2.1、URL的hash 方式
location說(shuō)明
location.href效果 頁(yè)面整個(gè)刷新
location.hash 局部刷新 而非全部刷新
2.2、HTML5的history模式
- pushState back 棧結(jié)構(gòu)
特點(diǎn):先進(jìn)后出 pushState:入棧 back:出棧
效果如下
- replaceState back 替換
不能回退
- go
history.go(-1) 后退一步
history.go(1) <=> history.forward() 前進(jìn)一步
3、route-view的基礎(chǔ)
3.1 認(rèn)識(shí)vue-router
- vue-router是基于組件和路由實(shí)現(xiàn)
路由用于設(shè)定訪問(wèn)路徑, 將路徑和組件映射起來(lái).
在vue-router的單頁(yè)面應(yīng)用中, 頁(yè)面的路徑的改變就是組件的切換.
3.2、安裝和使用vue-router
- 使用webpack創(chuàng)建工程化開(kāi)發(fā)
- 安裝npm install vue-router --save
- 模塊化使用
導(dǎo)入路由對(duì)象,并且調(diào)用Vue.use(VueRouter)
創(chuàng)建路由實(shí)例,并且傳入路由映射配置
在vue實(shí)例中掛載創(chuàng)建的路由實(shí)例
- 使用vue-router步驟
創(chuàng)建路由組件
配置路由映射,組件和路徑映射關(guān)系
About.vue
<template> <div> <h2>我是關(guān)于</h2> <p>我是關(guān)于內(nèi)容, 呵呵呵</p> </div> </template> <script> export default { name: "About" } </script> <style scoped> </style>
Home.vue
<template> <div> <h2>我是首頁(yè)</h2> <p>我是首頁(yè)內(nèi)容, 哈哈哈</p> </div> </template> <script> export default { name: "Home" } </script> <style scoped> </style>
router -> index.js
// 創(chuàng)建VueRouter對(duì)象 const routes = [ { path: '', <!--路由的默認(rèn)值--> // 頁(yè)面默認(rèn)加載 直接訪問(wèn)主頁(yè) redirect: '/home' }, { path: '/home', component: Home }, { path: '/about', component: About }, ] const router = new VueRouter({ // 配置路由和組件之間的應(yīng)用關(guān)系 routes, mode:"history", linkActiveClass:"active" })
- 使用路由 router-link和router-view 顯示
<template> <div id="app"> <router-link to="/home">首頁(yè)</router-link> <router-link to="about">About</router-link> <router-view/> </div> </template>
大致流程
1、通過(guò)指令創(chuàng)建vue項(xiàng)目
vue create vuerouterstudy
2、刪除默認(rèn)生成的HelloWorld組件相關(guān)信息
3、創(chuàng)建路由實(shí)例,并且傳入路由映射配置
Home.vue
<template> <div> 我是首頁(yè)內(nèi)容 </div> </template>
index.js
import VueRouter from 'vue-router' import Vue from 'vue' import Home from '../components/Home' // 1、通過(guò)Vue.use(插件名) 安裝插件 Vue.use(VueRouter) // 2、創(chuàng)建VueRouter對(duì)象 const routes = [ { path: '/home', component: Home } ] // 3、配置路由和組件之間映射關(guān)系 const router = new VueRouter({ routes }) // 4、將router對(duì)象傳入Vue實(shí)例 export default router
使用路由
App.vue
<template> <div id="app"> <!-- 渲染超鏈接 a --> <router-link to="/home" tag="button">主頁(yè)</router-link> <router-link to="/about" tag="button">關(guān)于</router-link> <!-- 動(dòng)態(tài)渲染組件 --> <router-view></router-view> </div> </template> <script> export default { name: "App", components: {}, }; </script> <style> </style>
簡(jiǎn)要說(shuō)明組件
<router-link>:該標(biāo)簽是一個(gè)vue-router已經(jīng)內(nèi)置的組件,最終會(huì)被渲染一個(gè)a鏈接 <router-view>:該標(biāo)簽會(huì)根據(jù)當(dāng)前路徑,動(dòng)態(tài)渲染出不同組件 網(wǎng)頁(yè)的其他內(nèi)容,比如頂部的標(biāo)題導(dǎo)航,或者說(shuō) 底部的一些版權(quán)信息和<router-view>處于同一登記 路由切換時(shí)候,切換就是<router-view>掛載的組件,其他內(nèi)容不改變
最終效果圖
3.3、路由的默認(rèn)路徑
默認(rèn)情況下, 進(jìn)入網(wǎng)站的首頁(yè), 我們希望<router-view>渲染首頁(yè)的內(nèi)容.
但是我們的實(shí)現(xiàn)中, 默認(rèn)沒(méi)有顯示首頁(yè)組件, 必須讓用戶點(diǎn)擊才可以.
如何可以讓路徑默認(rèn)跳到到首頁(yè), 并且<router-view>渲染首頁(yè)組件呢?
非常簡(jiǎn)單, 我們只需要配置多配置一個(gè)映射就可以了.
配置解析
我們?cè)趓outes中又配置了一個(gè)映射.
path配置的是根路徑: /
redirect是重定向, 也就是我們將根路徑重定向到/home的路徑下, 這樣就可以得到我們想要的結(jié)果了.
3.4、HTML5的history模式
頁(yè)面默認(rèn)是 url的hash模式
想要改成html5中history,可以進(jìn)行一下配置
修改后
3.5、router-link補(bǔ)充
- tag屬性:tag可以指定之后渲染成什么組件, 比如上面的代碼會(huì)被渲染成一個(gè)元素, 而不是
- replace屬性:replace不會(huì)留下history記錄, 所以指定replace的情況下, 后退鍵返回不能返回到上一個(gè)頁(yè)面中
- active-class屬性: 當(dāng)對(duì)應(yīng)的路由匹配成功時(shí), 會(huì)自動(dòng)給當(dāng)前元素設(shè)置一個(gè)router-link-active的class, 設(shè)置active-class可以修改默認(rèn)的名稱.
在進(jìn)行高亮顯示的導(dǎo)航菜單或者底部tabbar時(shí), 會(huì)使用到該類.
但是通常不會(huì)修改類的屬性, 會(huì)直接使用默認(rèn)的router-link-active即可.
也可以通過(guò)這種方式 在路由配置的index.js
3.6、路由代碼跳轉(zhuǎn)
源碼實(shí)現(xiàn)
<template> <div id="app"> <!-- 渲染超鏈接 a --> <!-- <router-link to="/home" tag="h1" replace>主頁(yè)</router-link> --> <!-- <router-link to="/about" tag="h1" replace active-class>關(guān)于</router-link> --> <button @click="handleHome">主頁(yè)</button> <button @click="handleAbout">關(guān)于</button> <!-- 動(dòng)態(tài)渲染組件 --> <router-view></router-view> </div> </template> <script> export default { name: "App", components: {}, methods:{ handleHome(){ this.$router.push('/home') }, handleAbout(){ this.$router.push('/about') } } }; </script> <style></style>
效果圖
3.7、動(dòng)態(tài)路由
在某些情況下,一個(gè)頁(yè)面的path路徑可能是不確定的,比如我們進(jìn)入用戶界面時(shí),希望是如下的路徑:
/user/aaaa或/user/bbbb
除了有前面的/user之外,后面還跟上了用戶的ID
這種path和Component的匹配關(guān)系,我們稱之為動(dòng)態(tài)路由(也是路由傳遞數(shù)據(jù)的一種方式)。
1、配置組件和路徑的映射關(guān)系
// 配置路由相關(guān)的信息 import Vue from 'vue' import VueRouter from "vue-router" import Home from '../components/Home' import About from '../components/About' import User from '../components/User' // 通過(guò)Vue.use(插件),安裝插件 Vue.use(VueRouter) // 創(chuàng)建VueRouter對(duì)象 const routes = [ { path: '', redirect: '/home' }, { path: '/home', component: Home }, { path: '/about', component: About }, <!--這是關(guān)鍵代碼--> { path: '/user/:id', component: User }, ] const router = new VueRouter({ // 配置路由和組件之間的應(yīng)用關(guān)系 routes, mode: "history", linkActiveClass: "active" }) // 將router對(duì)象傳入Vue實(shí)例 export default router
2、創(chuàng)建組件User User.vue
<template> <div> <h1>我是APP頁(yè)面</h1> {{$route.params.id}} </div> </template>
3、首頁(yè)顯示
App.vue
<router-link to="/home/極客鼠" >測(cè)試獲取用戶名</router-link><br>
4、效果圖
4、路由的懶加載
4.1、認(rèn)識(shí)懶加載
官方給出了解釋:
當(dāng)打包構(gòu)建應(yīng)用時(shí),Javascript 包會(huì)變得非常大,影響頁(yè)面加載。
如果我們能把不同路由對(duì)應(yīng)的組件分割成不同的代碼塊,然后當(dāng)路由被訪問(wèn)的時(shí)候才加載對(duì)應(yīng)組件,這樣就更加高效了
官方在說(shuō)什么呢?
首先, 我們知道路由中通常會(huì)定義很多不同的頁(yè)面.
這個(gè)頁(yè)面最后被打包在哪里呢? 一般情況下, 是放在一個(gè)js文件中.
但是, 頁(yè)面這么多放在一個(gè)js文件中, 必然會(huì)造成這個(gè)頁(yè)面非常的大.
如果我們一次性從服務(wù)器請(qǐng)求下來(lái)這個(gè)頁(yè)面, 可能需要花費(fèi)一定的時(shí)間, 甚至用戶的電腦上還出現(xiàn)了短暫空白的情況.
如何避免這種情況呢? 使用路由懶加載就可以了.
路由懶加載做了什么?
路由懶加載的主要作用就是將路由對(duì)應(yīng)的組件打包成一個(gè)個(gè)的js代碼塊.
只有在這個(gè)路由被訪問(wèn)到的時(shí)候, 才加載對(duì)應(yīng)的組件
4.2、懶加載效果
// 配置路由相關(guān)的信息 import Vue from 'vue' import VueRouter from "vue-router" const Home = () => import ('../components/Home') const About = () => import ('../components/About') const User = () => import ('../components/User') // 通過(guò)Vue.use(插件),安裝插件 Vue.use(VueRouter) // 創(chuàng)建VueRouter對(duì)象 const routes = [ { path: '', redirect: '/home' }, { path: '/home', component: Home }, { path: '/about', component: About }, { path: '/user/:id', component: User }, ] const router = new VueRouter({ // 配置路由和組件之間的應(yīng)用關(guān)系 routes, mode: "history", linkActiveClass: "active" }) // 將router對(duì)象傳入Vue實(shí)例 export default router
4.3、懶加載方式
5、路由的嵌套使用
5.1、認(rèn)識(shí)嵌套路由
嵌套路由是一個(gè)很常見(jiàn)的功能
比如在home頁(yè)面中, 我們希望通過(guò)/home/news和/home/message訪問(wèn)一些內(nèi)容.
一個(gè)路徑映射一個(gè)組件, 訪問(wèn)這兩個(gè)路徑也會(huì)分別渲染兩個(gè)組件.
組件和路徑關(guān)系
5.2、實(shí)現(xiàn)過(guò)程
1、創(chuàng)建兩個(gè)組件Message,News
Message.vue
<template> <div id="about">最新消息</div> </template> <script> </script>
News.vue
<template> <div id="about">新聞內(nèi)容</div> </template> <script> </script>
2、配置路由信息 主要是子路由
import Vue from 'vue' import VueRouter from 'vue-router' const Home = () => import('../components/Home') const About = () => import('../components/About') const Message = () => import('../components/Message') const News = () => import('../components/News') // 1、通過(guò)Vue.use(插件名) 安裝插件 Vue.use(VueRouter); // 2、創(chuàng)建VueRouter對(duì)象 const routes = [ { path:'/home', component:Home, children:[ { path:'news', component: News }, { path:'message', component: Message } ] }, { path: '/home/:username', component: Home }, { path: '/about', component: About } ] // 3、配置路由和組件之間映射關(guān)系 const router = new VueRouter({ routes, mode: 'history', // linkActiveClass: 'active' }) // 4、將router對(duì)象傳入Vue實(shí)例 export default router
3、父組件渲染子組件信息
Home.vue
<template> <div id="home"> 我是首頁(yè)內(nèi)容<br> <router-link to="/home/news"> 新聞</router-link> <router-link to="/home/message"> 消息</router-link> <router-view></router-view> <!-- <h2>用戶名:{{ $route.params.username }}</h2> --> </div> </template> <script> export default { name: "Home", }; </script>
4、效果圖
5.3、嵌套路由的默認(rèn)路徑
重定向redirect
{ path: '/user', component: User, children: [ { path: 'message', component: Message, }, { path: 'news', component: News, }, // 重定向 /user/news { path: '', redirect: 'news', }, ] },
6、路由傳遞參數(shù)
傳遞參數(shù)主要有兩種類型:params和query
params類型
1.配置路由格式:/router/:id
2.傳遞的方式:在path后面跟上對(duì)應(yīng)的值
3.傳遞后形成的路徑:/router/123,/router/abc
query類型
1.配置路由格式:/router,也就是普通配置
2.傳遞方式:對(duì)象中使用query的key作為傳遞方式
3.傳遞后形成的路徑:/router?id=123,/router?id=abc
6.1、準(zhǔn)備工作
傳遞參數(shù)之一:router-link
1、創(chuàng)建組件Profile.vue
<template> <div> <h2>我是Profile頁(yè)面</h2> <p>我是profile頁(yè)面具體內(nèi)容</p> <!--獲取字符串入?yún)?譬如:/profile/123--> <p>$route.params:{{ $route.params }}</p> <!--獲取對(duì)象類型入?yún)?譬如: /profile?name=1&age=10--> <p>$route.query:{{ $route.query }}</p> </div> </template> <script> export default { name: "Profile", }; </script> <style scoped> </style>
2、配置路由
const Profile = () => import('../components/Profile') { path: '/profile/:id', component: Profile }
3、app.vue 頁(yè)面顯示
<router-link :to="{ path: '/profile/' + 123, query: { name: 'geekmice', hobby: '籃球' } }" tag="button" >router-link傳遞參數(shù)</router-link >
4、最終效果
傳遞參數(shù)之二:js實(shí)現(xiàn)
<button @click="jsTransferParams">js傳遞參數(shù)</button> jsTransferParams() { this.$router.push({ path: "/profile/" + 666, query: { name: "geekmice", hobby: "探索黑科技" }, }); }, profile.vue獲取參數(shù) <p>$route.params:{{ $route.params }}</p> <p>$route.query:{{ $route.query }}</p>
6.2、獲取參數(shù)
獲取參數(shù)通過(guò)$route對(duì)象獲取的.
在使用了vue-router應(yīng)用中,路由對(duì)象會(huì)被注入每個(gè)組件中,賦值為this.$route,并且路由切換時(shí)候,路由對(duì)象會(huì)被更新。
$route傳遞的信息如下
6.3、router和route區(qū)別
簡(jiǎn)單理解 即一個(gè)獲取路由信息,一個(gè)是用來(lái)操作路由的;
$router為VueRouter實(shí)例,想要導(dǎo)航到不同URL,則使用$router.push方法
路由的跳轉(zhuǎn)方法,鉤子函數(shù)等
$route為當(dāng)前router跳轉(zhuǎn)對(duì)象里面可以獲取name、meta、path、hash、query、params、fullPath、matched、redirectedFrom等
7、路由導(dǎo)航守衛(wèi)
vue-router提供的導(dǎo)航守衛(wèi)主要用來(lái)監(jiān)聽(tīng)路由的進(jìn)入和離開(kāi)的
vue-router提供了beforeEach和afterEach的鉤子函數(shù),它們會(huì)在路由即將改變前和改變后觸發(fā)
利用beforeEach完成標(biāo)題的修改
- 首先,我們可以在鉤子中定義一些標(biāo)題,可以利用meta來(lái)定義
- 其次,利用導(dǎo)航守衛(wèi),修改我們的標(biāo)題
// 配置路由相關(guān)的信息 import Vue from 'vue' import VueRouter from "vue-router" const Home = () => import('../components/Home') const About = () => import('../components/About') const User = () => import('../components/User') const Message = () => import('../components/Message') const News = () => import('../components/News') const Profile = () => import('../components/Profile') // 通過(guò)Vue.use(插件),安裝插件 Vue.use(VueRouter) // 創(chuàng)建VueRouter對(duì)象 const routes = [ { path: '', redirect: '/home' }, { path: '/home', component: Home, meta: { title: "首頁(yè)" } }, { path: '/profile/:id', component: Profile, meta: { title: "檔案" } }, { path: '/about', component: About, meta: { title: "關(guān)于" } }, { path: '/user', component: User, children: [ { path: 'message', component: Message, }, { path: 'news', component: News, }, { path: '', redirect: 'news', }, ] }, ] const router = new VueRouter({ // 配置路由和組件之間的應(yīng)用關(guān)系 routes, mode: "history", linkActiveClass: "active" }) router.afterEach((to, from, next) => { document.title = to.matched[0].meta.title; next() }) // 將router對(duì)象傳入Vue實(shí)例 export default router
效果圖
簡(jiǎn)要說(shuō)明
導(dǎo)航鉤子的三個(gè)參數(shù)解析
- to: 即將要進(jìn)入的目標(biāo)的路由對(duì)象
- from: 當(dāng)前導(dǎo)航即將離開(kāi)的路由對(duì)象
- next調(diào)用該方法之后,才能進(jìn)入下一個(gè)鉤子
8、keep-alive
這個(gè)組件 Vue的內(nèi)置組件,能在組件切換過(guò)程中將狀態(tài)保留在內(nèi)存中,防止重復(fù)渲染DOM。
案例說(shuō)明理解一下
需求:現(xiàn)在有兩個(gè)組件KeepStart,KeepEnd組件,KeepStart組件 有input輸入框,輸入信息 可以緩存 KeepEnd組件不能緩存
源碼實(shí)現(xiàn)
1、KeepStart.vue
<template> <div> <h1>開(kāi)始頁(yè)面</h1> <input type="text" placeholder="請(qǐng)輸入。。。"> </div> </template>
2、KeepEnd.vue
<template> <div> <h1>不需要緩存頁(yè)面</h1> <input type="text" placeholder="請(qǐng)輸入"> </div> </template>
3、router->index.js
const KeepStart = () => import('../components/KeepStart') const KeepEnd = () => import('../components/KeepEnd') { path: '/keepStart', component: KeepStart, name:'keepStart', meta: { keepAlive: true } }, { path: '/keepEnd', name:'keepEnd', component: KeepEnd, meta: { keepAlive: false } }
4、App.vue
<router-link to="/keepStart" tag="button">keepstart頁(yè)面</router-link> <router-link to="/keepEnd" tag="button">keepend頁(yè)面</router-link> <!-- 動(dòng)態(tài)渲染組件 --> <!-- <router-view></router-view> --> <keep-alive> <router-view v-if="$route.meta.keepAlive"></router-view> </keep-alive> <router-view v-if="!$route.meta.keepAlive"></router-view>
效果圖
9、TabBar練習(xí)
9.1、需求表述
效果圖
表述
實(shí)現(xiàn)一個(gè)導(dǎo)航欄,分別是分類,首頁(yè),購(gòu)物車,我的四個(gè)欄目;用戶點(diǎn)擊各自的欄目顯示不同頁(yè)面;采用插槽的思想來(lái)實(shí)現(xiàn)可擴(kuò)展性。
9.2、需求分析
- 1、如果在下方有一個(gè)單獨(dú)的TabBar組件,如何安裝
自定義TabBar組件,在APP中使用
讓Tabbar處于底部,設(shè)置相關(guān)的樣式
- 2、TabBar中顯示的內(nèi)容由外部決定
定義插槽
flex布局評(píng)分TabBar
- 3、自定義TabBarItem,可以傳入圖片和文字
定義TabBarItem,并且定義兩個(gè)插槽:圖片,文字
給兩個(gè)插槽外層包裝div,用于設(shè)置樣式
填充插槽,實(shí)現(xiàn)底部TabBar的效果
- 4、傳入選中高亮圖片
定義另外一個(gè)插槽,插入active-icon的數(shù)據(jù)
定義個(gè)變量isActive,通過(guò)v-show來(lái)決定是否顯示對(duì)應(yīng)的icon
- 5、TabBarItem綁定路由數(shù)據(jù)
安裝路由 npm install vue-router --save
完成router->index.js,創(chuàng)建對(duì)應(yīng)的組件
main.js注冊(cè)router
App.vue加入router-view組件 渲染
- 6、點(diǎn)擊item跳轉(zhuǎn)到對(duì)應(yīng)路由表,并且動(dòng)態(tài)絕對(duì)isActive
監(jiān)聽(tīng)item的點(diǎn)擊,通過(guò)this.$router.replace()替換路由路徑
通過(guò)this.$route.path.indexOf(this.link) !== -1 來(lái)判斷是否是active
- 7、動(dòng)態(tài)計(jì)算active樣式
封裝新的計(jì)算屬性 this.isActive ? {‘color':‘red'}:{}
9.3、需求實(shí)現(xiàn)
實(shí)現(xiàn)版本1
創(chuàng)建vue項(xiàng)目
vue create navbar
刪除無(wú)用的組件 HelloWorld 圖片
簡(jiǎn)易目錄結(jié)構(gòu)
App.vue
<template> <div id="app"> <div id="tab-bar"> <div id="tab-bar-item">首頁(yè)</div> <div id="tab-bar-item">分類</div> <div id="tab-bar-item">購(gòu)物車</div> <div id="tab-bar-item">我的</div> </div> </div> </template> <script> export default { name: "App", components: {}, }; </script> <style> /* 引入css樣式 */ @import url("./assets/css/base.css"); #tab-bar { display: flex; background-color: rgb(246, 246, 246); /* 絕對(duì)定位 */ position: fixed; left: 0; bottom: 0; right: 0; } #tab-bar-item { flex: 1; text-align: center; height: 49px; } </style>
base.css
body{ padding: 0; margin: 0; }
效果圖
最終版本
目錄結(jié)構(gòu)
關(guān)鍵源碼實(shí)現(xiàn)
TabBar.vue 封裝
<template> <div id="tab-bar"> <slot></slot> </div> </template> <script> export default { name: "TabBar" } </script> <style scoped> #tab-bar { display: flex; background-color: #f6f6f6; position: fixed; left: 0; right: 0; bottom: 0; box-shadow: 0 -1px 1px rgba(100,100,100,.2); } </style>
TabBarItem.vue 封裝
<template> <!--所有的item都展示同一個(gè)圖片, 同一個(gè)文字--> <div class="tab-bar-item" @click="itemClick"> <div v-if="!isActive"><slot name="item-icon"></slot></div> <div v-else><slot name="item-icon-active"></slot></div> <div :style="activeStyle"><slot name="item-text"></slot></div> </div> </template> <script> export default { name: "TabBarItem", props: { path: String, activeColor: { type: String, default: 'red' } }, data() { return { // isActive: true } }, computed: { isActive() { // /home -> item1(/home) = true // /home -> item1(/category) = false // /home -> item1(/cart) = true // /home -> item1(/profile) = true return this.$route.path.indexOf(this.path) !== -1 }, activeStyle() { return this.isActive ? {color: this.activeColor} : {} } }, methods: { itemClick() { this.$router.replace(this.path) } } } </script> <style scoped> .tab-bar-item { flex: 1; text-align: center; height: 49px; font-size: 14px; } .tab-bar-item img { width: 24px; height: 24px; margin-top: 3px; vertical-align: middle; margin-bottom: 2px; } </style>
配置路由 index.js
import Vue from 'vue' import VueRouter from 'vue-router' const Home = () => import('../views/home/Home') const Category = () => import('../views/category/Category') const Cart = () => import('../views/cart/Cart') const Profile = () => import('../views/profile/Profile') // 1.安裝插件 Vue.use(VueRouter) // 2.創(chuàng)建路由對(duì)象 const routes = [ { path: '', redirect: '/home' }, { path: '/home', component: Home }, { path: '/category', component: Category }, { path: '/cart', component: Cart }, { path: '/profile', component: Profile } ] const router = new VueRouter({ routes, mode: 'history' }) // 3.導(dǎo)出router export default router
最終效果
到此這篇關(guān)于詳解VueRouter 路由的文章就介紹到這了,更多相關(guān)VueRouter 路由內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
巧用Vue.js+Vuex制作專門收藏微信公眾號(hào)的app
這篇文章主要為大家詳細(xì)介紹了vue自定義指令三步如何實(shí)現(xiàn)數(shù)據(jù)拉取更新,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-11-11html中引入Vue.js的cdn實(shí)現(xiàn)簡(jiǎn)單的文檔單頁(yè)
這篇文章主要為大家介紹了html中引入Vue.js的cdn實(shí)現(xiàn)簡(jiǎn)單的文檔單頁(yè)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08Vue使用pdfobject實(shí)現(xiàn)預(yù)覽pdf的示例詳解
PDFObject?是一個(gè)?JavaScript?庫(kù)用來(lái)在HTML中動(dòng)態(tài)嵌入?PDF?文檔。這篇文章主要為大家詳細(xì)介紹了使用pdfobject實(shí)現(xiàn)預(yù)覽pdf的功能,需要的可以了解一下2023-03-03jdk1.8+vue elementui實(shí)現(xiàn)多級(jí)菜單功能
這篇文章主要介紹了jdk1.8+vue elementui實(shí)現(xiàn)多級(jí)菜單功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-09-09vue-cli3.X快速創(chuàng)建項(xiàng)目的方法步驟
這篇文章主要介紹了vue-cli3.X快速創(chuàng)建項(xiàng)目的方法步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11vue webuploader 文件上傳組件開(kāi)發(fā)
本篇文章主要介紹了vue webuploader 文件上傳組件開(kāi)發(fā),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-09-09vue實(shí)現(xiàn)錄音并轉(zhuǎn)文字功能包括PC端web手機(jī)端web(實(shí)現(xiàn)過(guò)程)
vue實(shí)現(xiàn)錄音并轉(zhuǎn)文字功能,包括PC端,手機(jī)端和企業(yè)微信自建應(yīng)用端,本文通過(guò)實(shí)例代碼介紹vue實(shí)現(xiàn)錄音并轉(zhuǎn)文字功能包括PC端web手機(jī)端web,感興趣的朋友跟隨小編一起看看吧2024-08-08vue中動(dòng)態(tài)渲染數(shù)據(jù)時(shí)使用$refs無(wú)效的解決
這篇文章主要介紹了vue中動(dòng)態(tài)渲染數(shù)據(jù)時(shí)使用$refs無(wú)效的解決方案,具有很好的參考價(jià)值。希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-01-01