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

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

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

可是咱們最終的目的仍是要實現單頁面應用程序,這個時候咱們就必不可少的須要使用到路由管理器來進行SPA的開發,vue官方爲咱們提供了一個官方庫vue-router,而且配有對應的中文文檔。關於裏面的內容你們自行前去觀看。在這裏,只會把咱們須要的東西拿出來說。es6

vue組件

官網對於組件講解github

Vue中定義一個組件很是簡單,只須要一對自定義標籤,在其中填入內容就能夠進行咱們的組件編寫了,而後使用Vue.component()去註冊咱們的組件下面來看一個例子,來直觀的看看vue的組件。

組件入門

<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>這個自定義標籤渲染後展示出來的樣式,這裏渲染爲:

<div id="app">
    <h2>hello Vue component</h2>
    <h2>hello Vue component</h2>
</div>

使用template標籤

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

<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>標籤中的內容。因此這裏應該會被渲染爲:

<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的語法來進行引入

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

起步

其實這一部分vue-router中文文檔中已經講的很是詳細了。。在這裏與它不一樣的是它用的CommonJS的規範來進行模塊安裝,而我使用ES6的import,有興趣本身去看- -。其餘的內容我就直接扒下來了。

html:

<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:

// 定義組件
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的變化,直接在文件中講解了:

// 引入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須要有用於渲染匹配的組件,以下

<div id="app">
        <router-view></router-view>
    </div>

如今當咱們運行 npm start 進入http://localhost:8080/就會自動跳轉到http://localhost:8080/#!/index,而且讀取裏面的內容。

實現路由跳轉

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

<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兩步的效果。引入賦值)。

引入以後,只須要以下注冊:

export default {
    //其它的就
    components:{
        hello//若還有更多的組件,只須要在import的狀況下,以逗號分割,繼續註冊就好
    }
}

最後在app.vue中添加<hello></hello>這一對自定義標籤,就能夠實現加載hello.vue中的內容。

組件的嵌套也就是這樣,很簡單的描述完了,可是怎麼樣去抽離組件,在工做中積累能夠複用的組件纔是咱們真正須要去思考的。

那麼先到這,關於組件之間通訊的問題,留到之後慢慢了解。

路由嵌套

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

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

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

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

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中:

<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的樣式表。

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

相關文章
相關標籤/搜索