利用vue-cli配合vue-router搭建一個完整的spa流程(二)

幽夢裡傳心曲發表於2017-04-25

上篇文章太長了,編寫時拖動太麻煩,重開一篇。
利用vue-cli配合vue-router搭建一個完整的spa流程(一)

在(一)中寫到了主要頁面的編寫,現在開始三個路由頁面的編寫。

第一步: 路由例項index.js

先貼出程式碼。

import Vue from `vue`
import Router from `vue-router`
import VueResource from `vue-resource`
import tem from `@/components/showone`
import tem_cont from `@/components/showtwo`
import tem_error from `@/components/error`

//安裝外掛
Vue.use(Router)
Vue.use(VueResource)

export default new Router({
    routes:[
        {
            path:"/user/:list/:listNum",
            component:tem,
            children:[
                {
                    path:"con",
                    component:tem_cont
                }
            ]
        },
        {
            path:"/user/error",
            component:tem_error
        }
    ]
})

程式碼很短,一一解釋下。

import Vue from `vue`
import Router from `vue-router`
import VueResource from `vue-resource`
import tem from `@/components/showone`
import tem_cont from `@/components/showtwo`
import tem_error from `@/components/error`

↑ 這裡是引入所有使用的資料,引數。

//安裝外掛
Vue.use(Router)
Vue.use(VueResource)

↑ 這裡說下 vue-resource 這個一開始沒有安裝,開啟專案右鍵開啟Git 鍵入 npm install vue-resource –save
這是一個ajax外掛,使用起來比較方便而且很簡單。

routes:[
    {
        path:"/user/:list/:listNum",
        component:tem,
        children:[
            {
                path:"con",
                component:tem_cont
            }
        ]
    },
    {
        path:"/user/error",
        component:tem_error
    }
]

↑ 路由配置,詳情頁面是主頁面的子路由。

第二部: 三個路由xxxx.vue檔案編寫

Ⅰ: showone.vue

先貼出程式碼,有些複雜,慢慢解釋。

<template>
    <div style=`cursor:pointer;height: 867px;` >
        <div v-show=`routerData.mainShow`>
            <nav class=`navbar navbar-default`>
                <div class=`container` style="padding: 0;">
                    <div class=`collapse navbar-collapse` style="padding: 0;">
                        <ul class=`nav navbar-nav userNav`>
                            <li><a v-bind:class="{activeBg:isActive==0}" v-on:click=`link(0)`>首頁</a></li>
                            <li><a v-bind:class="{activeBg:isActive==1}" v-on:click=`link(1)`>頁面一</a></li>
                        </ul>
                    </div>
                </div>
            </nav>
            <div class=`media` v-for=`(item,index) in routerData.showData` v-on:click=`go(item,index)`>
                <div>
                    <div class=`media-left`>
                        <img class=`media-object` v-bind:src=`item.thumbnail`>
                    </div>
                    <div class=`media-body`>
                        <h2 class=`media-heading` v-text=`item.title`></h2>
                        <span style=`font-size:25px;color:#ccc`>{{item.content | more}}</span>
                    </div>
                </div>
            </div>
        </div>
        <router-view v-bind:router-nesting=`routerData`></router-view>
    </div>
</template>
<script>
    import router from `.././router`
    export default{
        props:["routerData"],
        data(){
            return {
                isActive:this.$route.path.slice(6,7)
            }
        },
        methods:{
            go(obj,index){
                router.push({path:this.$route.path+"/con",query:{type:index}});
            },
            link(num){
                var listNum=this.$route.path.slice(6,7);
                if(listNum!=num){
                    router.push("/user/"+num+"/0");
                    this.isActive=this.$route.path.slice(6,7);
                }
            }
        },
        filters:{
            more(value){
                var newMessage=value.slice(0,40)+"........點選檢視更多";
                return newMessage;
            }
        }
    }
</script>
<style>
    .activeBg{
        background-color: teal;
        color: white !important;
        transition: 0.5s all ease-in;
    }
    .userNav :hover{
        background-color: cornsilk;
        color: black !important;
    }
</style>

template有倆部分組成:

<div v-show=`routerData.mainShow`>
    <nav class=`navbar navbar-default`>
        <div class=`container` style="padding: 0;">
            <div class=`collapse navbar-collapse` style="padding: 0;">
                <ul class=`nav navbar-nav userNav`>
                    <li><a v-bind:class="{activeBg:isActive==0}" v-on:click=`link(0)`>首頁</a></li>
                    <li><a v-bind:class="{activeBg:isActive==1}" v-on:click=`link(1)`>頁面一</a></li>
                </ul>
            </div>
        </div>
    </nav>
    <div class=`media` v-for=`(item,index) in routerData.showData` v-on:click=`go(item,index)`>
        <div>
            <div class=`media-left`>
                <img class=`media-object` v-bind:src=`item.thumbnail`>
            </div>
            <div class=`media-body`>
                <h2 class=`media-heading` v-text=`item.title`></h2>
                <span style=`font-size:25px;color:#ccc`>{{item.content | more}}</span>
            </div>
        </div>
    </div>
</div>

↑ 這是第一部分,包含導航與當前分類中全部內容的一個列表。

①: v-show=`routerData.mainShow` 這個控制整體部分顯示隱藏,與 上一頁,下一頁按鈕為相同的控制資料,因為二者顯示,隱藏邏輯是一樣的。都是在詳情頁隱藏,主頁顯示。

②: v-on:click=`link(0)` 導航按鈕跳轉繫結的函式。

③: v-for=`(item,index) in routerData.showData` 迴圈資料,渲染列表。

④: v-on:click=`go(item,index)` 每個列表繫結跳轉到詳情頁的函式。

⑤: {{item.content | more}} 渲染簡介,並且通過一個過濾器使內容中數字過多時,進行剪下


<router-view v-bind:router-nesting=`routerData`></router-view>

↑ 這是第二部分,子路由入口。v-bind:router-nesting=`routerData` 給子路有中渲染頁面的資料。

接下來是script部分

首先引入router例項 import router from `.././router`
再接收 zjapp.vue 傳輸過來的資料 props:["routerData"]


methods方法裡函式解釋:

go(obj,index){
    router.push({path:this.$route.path+"/con",query:{type:index}});
}

↑ 這是列表中內容點選時執行的函式,從 template 中傳過來 index 值,新增到 url 中,從而獲取這是列表中第幾個。

link(num){
    var listNum=this.$route.path.slice(6,7);
    if(listNum!=num){
        router.push("/user/"+num+"/0");
        this.isActive=this.$route.path.slice(6,7);
    }
}

↑ link(num)函式是導航點選繫結的函式,通過傳志 num 將 url 轉換為對應的分類,從而觸發 watch 重新獲取資料。這裡加了一個判斷,重複點選,無效。

filters:{
    more(value){
        var newMessage=value.slice(0,40)+"........點選檢視更多";
        return newMessage;
    }
}

↑ 過濾器,剪下字數。


style就不解釋了

Ⅱ: showtwo.vue

這個是檔案是詳情頁面,即主頁面中的列表內容點選後,跳轉的頁面。

<template>
    <div style=`height:700px;padding-top:100px`>
        <div>
            <img v-bind:src=`routerNesting.detailedData.src` style=`display:block;margin:0 auto;width:500px`>
            <br>
            <h2 v-text=`routerNesting.detailedData.title`></h2>
            <p>{{routerNesting.detailedData.content}}</p>
            <button v-on:click=`back` class=`btn btn-success`>返回</button>
        </div>
    </div>
</template>
<script>
    import router from `.././router`
    export default{
        props:["routerNesting"],
        methods:{
            back(){
                router.push(this.$route.path.slice(0,9));
            }
        }
    }
</script>
<style></style>

↑ 資料與showone.vue相似,routerNesting資料是通過ziapp.vue->showone.vue->showtwo.vue傳遞過來的。
back() 函式將url從/user/0/0/con?type=2跳轉到/user/0/0 觸發watch更新資料。

Ⅲ: error.vue

<template>
    <div style="margin-top: 150px;">
        <h1 style="text-align: center;">遙遠的404!</h1>
        <div style="width: 150px;margin: 50px auto;">
            <button v-on:click="jump(0)" class="btn btn-primary">首頁</button>
            <button v-on:click="jump(1)" class="btn btn-primary">第一頁</button>
        </div>
    </div>
</template>
<script>
    import router from `.././router`
    export default{
        methods:{
            jump(num){
                num==0?router.push("/user/0/0"):router.push("/user/1/0");
            }
        }
    }
</script>
<style></style>

↑ 嗯~ o( ̄▽ ̄)o,這個比較簡單,不做解釋了。


結語

至此,全部都解清楚了,按照步驟來的話一個簡單的spa也初見其形。

整體思想:通過watch監控url的變化,變化後執行routerPath()函式,隨後重新獲取資料。

新手,有錯誤,和需要指正的地方歡迎留言!


後續會有其他例項專案詳解,至於時間嘛,這要看什麼時候找到工作了(ˉ▽ˉ;)…

相關文章