就是隻有一個 web 頁面的應用,
是加載單個 HTML 頁面,
並在用戶與應用程序交互時, 動態更新該頁面的 web 應用程序css
區別html
只有第一次會加載頁面,
之後的每次請求,
僅僅是獲取必要的數據.而後,
由頁面中 js 解析獲取的數據,
展現在頁面中前端
單頁面優點 :vue
單頁面劣勢 :node
路由 : 是瀏覽器 URL 中的哈希值( # hash) 與 展現視圖內容 之間的對應規則ios
#
hash) 發生改變後,路由會根據制定好的規則, 展現對應的視圖內容爲何要學習路由?web
npm i vue-router
<script src="./vue.js"></script> // 千萬注意 :引入路由必定要在引入vue以後,由於vue-router是基於vue工做的 <script src="./node_modules/vue-router/dist/vue-router.js"></script>
實例路由對象 + 掛載到vue上vue-router
const router = new VueRouter()
new Vue({ router,data,methods })
#/
# 1. 入口 // 方式1 : url地址爲入口 調試開發用 輸入url地址 改變哈希值 `01-路由的基本使用.html#/one` // 方式2 : 聲明式導航 : router-link+to (見下面介紹) # 2. 路由規則 // path : 路由路徑 // component : 未來要展現的路由組件 routes: [ { path: '/one', component: One }, { path: '/two', component: Two } ] # 3. 組件 // 使用返回值的這個組件名稱 const One = Vue.component('one', { template: ` <div> 子組件 one </div> ` }) # 4. 出口 <!-- 出口 組件要展現的地方--> <router-view></router-view> # 總結 拿到入口哈希路徑, 根據路由匹配規則,找到對應的組件,顯示到對應的出口位置
入口npm
<!-- router-link 組件最終渲染爲 a標籤, to屬性轉化爲 a標籤的href屬性 to 屬性的值 , 實際上就是哈希值,未來要參與路由規則中進行與組件匹配 --> <router-link to="/one">首頁</router-link>
const One = { template: `<div> 子組件 one </div> ` }
<div id="app"> <!-- 1 路由入口:連接導航 --> <router-link to="/one">One</router-link> <router-link to="/two">Two</router-link> <!-- 4 路由出口:用來展現匹配路由視圖內容 --> <router-view></router-view> </div> <!-- 導入 vue.js --> <script src="./vue.js"></script> <!-- 導入 路由文件 --> <script src="./node_modules/vue-router/dist/vue-router.js"></script> <script> // 3 建立兩個組件 const One ={ template: '<h1>這是 one 組件</h1>' } const Two = { template: '<h1>這是 two 組件</h1>' } // 0 建立路由對象 const router = new VueRouter({ // 2. 路由規則 routes: [ { path: '/one', component: One }, { path: '/two', component: Two } ] }) const vm = new Vue({ el: '#app', //0. 不要忘記,將路由與vue實例關聯到一塊兒! router }) </script>
<a href="#/one" class="router-link-exact-active router-link-active">One</a> <a href="#/two" class="">Two</a>
.router-link-exact-active, .router-link-active { color: red; font-size: 50px; }
const router = new VueRouter({ routes: [], // 修改默認高亮的a標籤的類名 // red 是已經存在過的 linkActiveClass: 'red' })
導入 : 列表三個手機都要點擊進去詳情頁, 只須要一個組件,顯示不一樣的數據便可
# 入口 <router-link to="/detail/1">手機1</router-link> <router-link to="/detail/2">手機2</router-link> <router-link to="/detail/3">手機3</router-link> <router-link to="/detail">手機4</router-link> 沒有參數如何???? # 規則 routes: [ // 2 . 路由規則 { path: '/detail/:id?', component: Detail } ] # 獲取參數的三種方式 const Detail = { template: ` // 方式1 : 組件中直接讀取 <div> 顯示詳情頁內容....{{ $route.params.id }} </div> `, created() { // 方式2 : js直接讀取 // 打印只會打印一次,由於組件是複用的,每次進來鉤子函數只會執行一次 console.log(this.$route.params.id) }, // 方式3 : 監聽路由的參數,爲何不須要深度監聽,由於一個路徑變化,就會對應一個對新的路由對象(地址變) watch: { $route(to, from) { console.log(to.params.id) } } }
$route.path編程
string
"/foo/bar"
。# 後面?前面的內容
$route.params
Object
$route.query
Object
/foo?user=1
,則有 $route.query.user == 1
,若是沒有查詢參數,則是個空對象。$route.hash
string
當前路由的 hash 值 (帶 #
) ,若是沒有 hash 值,則爲空字符串。
$route.fullPath
string
# 演示 : <router-link to="/detail/4?age=21#one">detail</router-link> { path: '/detail/:id?', component: detail } 在組件內 created打印 this.$route > fullPath: "/detail/4?id=001#one" > hash : "#one" > params : {id:'4'} > query : {age : 21} > path : '/detail/4'
導入 : url測試 parent 和child, 想讓child 在 parent 中顯示
<router-view> </router-view>
/child 和 child 的區別
/child
=> 那麼訪問就能夠直接訪問#/child
就能夠訪問 子組件child
=> 那麼訪問就應該訪問#/parent/child
才能夠訪問子組件const parent = { template: `<p>parent <router-view> </router-view> </p>` } const child = { template: `<p>child</p>` } const router = new VueRouter({ routes: [ { path: '/parent', component: parent, children: [ { path: '/child', component: child } ] } ] })
routes
配置中給某個路由設置名稱。 ==> 如何命名# 命名 routes: [ { path: '/parent', name: 'parent', component: parent } ] # 入口連接 + 跳轉 (使用 path 和 name 的轉換) <!-- 方式1 : url手動寫 --> <!-- 方式2 : 入口連接 聲明式導航 --> <router-link to="/parent">點擊</router-link> <router-link :to="{ name : 'parent' }">點擊</router-link> # 忘了 帶 : 原始對象類型 <!-- 方式3 : 編程式導航 --> fn() { // this.$router.push('/parent') this.$router.push({ name: 'parent' }) }
導入 : 有時候想同時 (同級) 展現多個視圖,需求 : 訪問 / 根目錄 同時展現如下三個組件
const header = { template: `<p>header </p>` } const main = { template: `<p>main </p>` } const footer = { template: `<p>footer </p>` }
# 之前的那個方式只能顯示三個 header # 演示以前的效果 routes: [ { path: '/', components: { default: header, m: main, f: footer } } ]
<router-view> </router-view> <router-view name="m"> </router-view> <router-view name="f"> </router-view>
redirect: '/header' redirect: { name: 'header' } redirect: to => { // console.log(to) return { name: 'about' } }
# 入口 <router-link to="/header/3">123</router-link> # 規則 routes: [ { path: '/header/:id', component: header, } ] # 獲取參數 const header = { template: `<p>header {{ $route.params.id }} </p>` }
# 入口 <router-link to="/header/3">123</router-link> # 規則 routes: [ { path: '/header/:id', component: header, // 若是 props 被設置爲 true,route.params 將會被設置爲組件屬性 props: true } ] # 獲取參數 const header = { // 參數 id 當成參數 props: ['id'], template: `<p>header {{ id }} </p>` }
# 入口 <router-link to="/header">123</router-link> # 規則 routes: [ { path: '/header', component: header, props: { foo: '0000' } } ] # 組件 const header = { props: ['foo'], template: `<p>header {{ foo }} </p>` }
# 同對象模式同樣 # 區別是props值不同 props: to => { return { foo: '0000' } }
實際生活中的應用界面,一般由多層嵌套的組件組合而成。一樣地,URL 中各段動態路徑也按某種結構對應嵌套的各層組件。
藉助 vue-router
,使用嵌套路由配置,就能夠很簡單地表達這種關係。
<div id="app"> <router-view></router-view> </div>
const User = { template: '<div>User {{ $route.params.id }}</div>' } const router = new VueRouter({ routes: [ { path: '/user/:id', component: User } ] })
這裏的 <router-view>
是最頂層的出口,渲染最高級路由匹配到的組件。一樣地,一個被渲染組件一樣能夠包含本身的嵌套 <router-view>
。例如,在 User
組件的模板添加一個 <router-view>
嵌套路由
const User = { template: ` <div class="user"> <h2>User {{ $route.params.id }}</h2> <router-view></router-view> </div> ` }
VueRouter
的參數中使用 children
配置const router = new VueRouter({ routes: [ { path: '/user/:id', component: User, children: [ { // 當 /user/:id/profile 匹配成功, // UserProfile 會被渲染在 User 的 <router-view> 中 path: 'profile', component: UserProfile }, { // 當 /user/:id/posts 匹配成功 // UserPosts 會被渲染在 User 的 <router-view> 中 path: 'posts', component: UserPosts } ] } ] })
注意,以 /
開頭的嵌套路徑會被看成根路徑。 這讓你充分的使用嵌套組件而無須設置嵌套的路徑。
routes: [ { path: '/header', component: header, meta: { title: 'XXXX' } } ]
created() { document.title = this.$route.meta.title }
在路由導航的時候,能夠用做判斷
const one = { template: ` <div> <button @click="handleClick('back')">返回 上一頁</button> <button @click="handleClick('push')">跳轉 two頁</button> <button @click="handleClick('replace')">替換 two頁</button> </div>`, methods: { handleClick(type) { if (type == 'back') { // 返回 this.$router.back() } else if (type == 'push') { // 跳轉 有歷史記錄 this.$router.push('/two') } else { // 替換 沒有歷史記錄 this.$router.replace('/two') } } } } const two = { template: `<p>two </p>` }
router.beforeEach((to, from, next) => { // 訪問 login if (to.name == 'login') { // 下一步 next() } else { // 中止跳轉 next(false) // 跳轉到下一步 next({ name: 'login' }) 或者 使用路徑 next('/login') } })