webpack入坑之旅(六)配合vue-router實現SPA


這是一系列文章,此系列所有的練習都存在了我的github倉庫中vue-webpack,在本人有了新的理解與認識之后,會對文章有不定時的更正與更新。下面是目前完成的列表:

在上面的練習當中我們已經成功的加載了一個.vue格式的單文件組件,並且實現了在使用vue情況下的自動刷新。

但是我們最終的目的還是要實現單頁面應用程序,這個時候我們就必不可少的需要使用到路由管理器來進行SPA的開發,vue官方為我們提供了一個官方庫vue-router,並且配有對應的中文文檔。關於里面的內容大家自行前去觀看。在這里,只會把我們需要的東西拿出來講。

vue組件

官網對於組件講解

Vue中定義一個組件非常簡單,只需要一對自定義標簽,在其中填入內容就可以進行我們的組件編寫了,然后使用Vue.component()去注冊我們的組件下面來看一個例子,來直觀的看看vue的組件。

組件入門

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<script src="js/vue.js"></script>
<body>
<div id="app">
<my-component></my-component>
<!-- 自定義標簽作為組件名稱 -->
<my-component></my-component>
<!-- 復用 -->
</div>
<script>
// 定義並且注冊組件
// 在官方的示例中使用 Vue.extend({})先注冊了一個定義模板,再引用,看個人喜好吧
Vue.component( "my-component", {
template: "<h2>hello Vue component</h2>"
})
// 創建根實例
// 在這里 定義並且注冊組件 必須創建根實例前,不然會報錯,因為解析順序的問題?
new Vue({
el: "#app"
});
</script>
</body>

上面就是最簡單的定義組件的方式,template屬性中寫的東西:就是<my-component>這個自定義標簽渲染后展現出來的樣式,這里渲染為:

1
2
3
4
<div id="app">
<h2>hello Vue component</h2>
<h2>hello Vue component</h2>
</div>

使用template標簽

在上面這段代碼中組件內的內容都被寫在template屬性中,如果組件中的內容繼續增加,一堆的引號和加號來拼接這些字符串簡直就是噩夢。所以Vue 引入了template標簽(html5定義的,瀏覽器默認不去解析里面的內容)。<template> 不能用在 <table> 內下面來看看它的使用方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<script src="js/vue.js"></script>
<body>
<!-- 使用 template 並且添加選擇器(只能使用id)-->
<template id="myTemp">
<h2>This is Template </h2>
<p>add ...</p>
</template>
<div id="app">
<my-component></my-component>
<my-component></my-component>
</div>
 
<script>
Vue.component( "my-component", {
template: "#myTemp"//對應上面定義的template標簽中的選擇器
})
new Vue({
el: "#app"
});
</script>
</body>

可以看到在注冊組件中,可以template可以使用選擇器來獲取到上面我們<template>標簽中的內容。所以這里應該會被渲染為:

1
2
3
4
5
6
<div id="app">
<h2>This is Template </h2>
<p>add ...</p>
<h2>This is Template </h2>
<p>add ...</p>
</div>

組件的基礎介紹就到這,更多詳細內容請移步官網

vue-router

剛剛已經對於vue的組件有了一定的了解。現在來結合vue-router,來進行一下動態的切換。

首先是安裝,如果使用npm的形式的話,直接運行npm install vue-router --save,就可以看到vue-router,已經被添加到了項目依賴中。直接上ES6的語法來進行引入

1
2
3
import Vue from "vue";
import VueRouter from "vue-router";
Vue.use(VueRouter);

起步

其實這一部分vue-router中文文檔中已經講的非常詳細了。。在這里與它不同的是它用的CommonJS的規范來進行模塊安裝,而我使用ES6的import,有興趣自己去看- -。其他的內容我就直接扒下來了。

html:

1
2
3
4
5
6
7
8
9
10
<div id="app">
<h1>Hello App!</h1>
<p>
<!-- 使用指令 v-link 進行導航。 -->
<a v-link="{ path: '/foo' }">Go to Foo</a>
<a v-link="{ path: '/bar' }">Go to Bar</a>
</p>
<!-- 路由外鏈 -->
<router-view></router-view>
</div>

javascript:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// 定義組件
var Foo = Vue.extend({
template: '<p>This is foo!</p>'
})
var Bar = Vue.extend({
template: '<p>This is bar!</p>'
})
// 路由器需要一個根組件。
// 出於演示的目的,這里使用一個空的組件,直接使用 HTML 作為應用的模板
var App = Vue.extend({})
// 創建一個路由器實例
// 創建實例時可以傳入配置參數進行定制,為保持簡單,這里使用默認配置
var router = new VueRouter()
// 定義路由規則
// 每條路由規則應該映射到一個組件。這里的“組件”可以是一個使用 Vue.extend
// 創建的組件構造函數,也可以是一個組件選項對象。
// 稍后我們會講解嵌套路由
router.map({
'/foo': {
component: Foo
},
'/bar': {
component: Bar
}
})
// 現在我們可以啟動應用了!
// 路由器會創建一個 App 實例,並且掛載到選擇符 #app 匹配的元素上。
router.start(App, '#app')

我個人感覺這部分還是很好理解的,官方也給了一個在線示例應用。很好的展現了它的路由切換。

簡單的介紹到這,下面最重要的部分到了,看看如何結合我們定義的.vue單文件組件。

首先來看我們的文件目錄結構:

01-webpack-vuerouter

定義路由規則

最主要是main.js的變化,直接在文件中講解了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// 引入vue以及vue-router
import Vue from "vue";
import VueRouter from "vue-router";
Vue.use(VueRouter);
// 引入組件!直接使用es6的語法
import index from './components/app.vue';
import list from './components/list.vue';
import hello from './components/hello.vue';
//開啟debug模式
Vue.config.debug = true;
// new Vue(app);//這是上一篇用到的,新建一個vue實例,現在使用vue-router就不需要了。
// 路由器需要一個根組件。
var App = Vue.extend({});
// 創建一個路由器實例
var router = new VueRouter();
// 每條路由規則應該映射到一個組件。這里的“組件”可以是一個使用 Vue.extend創建的組件構造函數,也可以是一個組件選項對象。
// 稍后我們會講解嵌套路由
router.map({ //定義路由映射
'/index':{//訪問地址
name: 'index',//定義路由的名字。方便使用。
component:index, //引用的組件名稱,對應上面使用`import`導入的組件
//component:require("components/app.vue")//還可以直接使用這樣的方式也是沒問題的。不過會沒有import集中引入那么直觀
},
'/list': {
name: 'list',
component: list
},
});
router.redirect({ //定義全局的重定向規則。全局的重定向會在匹配當前路徑之前執行。
'*':"/index"//重定向任意未匹配路徑到/index
});
// 現在我們可以啟動應用了!
// 路由器會創建一個 App 實例,並且掛載到選擇符 #app 匹配的元素上。
router.start(App, '#app');

在index.html需要有用於渲染匹配的組件,如下

1
2
3
<div id="app">
<router-view></router-view>
</div>

 

現在當我們運行 npm start 進入http://localhost:8080/就會自動跳轉到http://localhost:8080/#!/index,並且讀取里面的內容。

實現路由跳轉

主要抽出app.vue中的內容來講解,的內容是:(list.vue里面的內容自行設置查看吧)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<template>
<div>
<h1>姓名:{{name}}</h1>
<h2>{{age}}</h2>
<button @click="golist">$route.router.go查看</button>
<a v-link="{ name: 'list' }">v-link查看列表</a>
<a v-link="{ name: 'index' }">回去主頁</a>
</div>
</template>
<script>
export default {//這里是官方的寫法,默認導出,ES6
data () { //ES6,等同於data:function(){}
return { //必須使用這樣的形式,才能創建出單一的作用域
name: "guowenfh",
age: "21"
}
},
methods :{
golist () { //方法,定義路由跳轉,注意這里必須使用this,不然報錯
this.$route.router.go({name:"list"});
}
}
}
</script>
<style></style>
<!-- 樣式自行設置,或者直接看源碼就好 -->

 

因為自刷新的緣故,直接切換到瀏覽器。

點擊上面使用的v-link,與router.go的方式都可以跳轉到list定義的路由。(觀察瀏覽器地址欄的變化)在這里我們使用的{name:"list"},使用{ path: '/list' }會有同樣的效果。

引用Vue組件

在第一小點里面我們看到了在頁面內的組件的使用方法,第二小點中學習到了vue-router的制定路由規則。

看過這兩個地方之后,我們把思維發散開來,應該就能觸類旁通的想到如何在頁面中嵌套加載別的組件了。
我們創建一個hello.vue ,里面內容隨意。現在我們如果要在app.vue中加載它,那么只需要在app.vue中使用import hello from "./hello.vue"(其實這個達到了使用require兩步的效果。引入賦值)。

引入之后,只需要如下注冊:

1
2
3
4
5
6
export default {
//其它的就
components:{
hello //若還有更多的組件,只需要在import的情況下,以逗號分割,繼續注冊就好
}
}

最后在app.vue中添加<hello></hello>這一對自定義標簽,就可以實現加載hello.vue中的內容。

組件的嵌套也就是這樣,很簡單的描述完了,但是怎么樣去抽離組件,在工作中積累可以復用的組件才是我們真正需要去思考的。

那么先到這,關於組件之間通信的問題,留到以后慢慢了解。

路由嵌套

還是剛剛的代碼與目錄結構,我們已經實現了組件之間的嵌套,但是有時並不希望組件直接就加載進來,而是在用戶點擊后才展現在頁面中,這是就需要使用到路由嵌套。

為了偷懶,這里就直接使用hello.vue。實現嵌套路由主要有以下幾步:

第一步:制定嵌套路由規則:

main.js下面這部分的代碼:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
router.map({
'/index':{
name: 'index',
component:index,
// 在/index下設置一個子路由
subRoutes:{
// 當匹配到/index/hello時,會在index的<router-view>內渲染
'/hello':{
name: 'hello',//可有可無,主要是為了方便使用
// 一個hello組件
component:hello
}
}
},
});

第二步:在組件中添加<router-view>

來自官網的解釋:<router-view> 用於渲染匹配的組件,它基於Vue的動態組件系統,所以它繼承了一個正常動態組件的很多特性。

<router-view>寫在app.vue<template></template>標簽中。

第三步:寫入跳轉路徑

還是在app.vue中:

1
2
3
<a v-link="{ name: 'index' }">回去主頁</a>
<!-- 點擊這兩個標簽就會實現頁面內的切換效果 -->
<a v-link="{ name: 'hello' }">嵌套的路由</a>

 

,切換到瀏覽器,點擊該嵌套的路由即可讓hello.vue中的展現出來,在這里直接使用了v-link來實現跳轉(知道為什么要寫name了吧。。如果使用path會是這樣的{ path: '/index/hello' }- -。 ) ,當然router.go同理。(注意在點擊兩個不同的文字時,地址欄的變化,以及展現內容的切換)

注意:

在我的源碼中是在<style scoped></style>標簽中定義樣式的,請注意scoped的使用,它表示在該style中定義的樣式只會在當前的組件中起到效果,而不會去影響全局的css樣式。

最簡單的理解應該就是:

未寫該scoped屬性的所有組件中的樣式,在經過vue-loader編譯之后擁有全局作用域。相當於共用一份css樣式表。

而寫了該屬性的的組件中定義的樣式,擁有獨立作用域。相當於除去引入了公用的一份css樣式表外,但單獨擁有一份css的樣式表。

好了,先到這。講的有些凌亂,下次見


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM