從 0 開始,vue 項目實戰(二)

前言

上一篇文章 ,已經搭建好所須要的開發環境了,接下來讓開發一個簡單的項目吧。
關於 less 我就不貼代碼了。css

源碼地址vue

正題

先對默認的文件進行改造一下。
刪除了默認的 App.vue、Hello.vue。
而後加了一個 list.vue。
修改一下main.js
而後看到頁面打印出一個 「列表頁」 三個字的時候,就表示成功了。node

列表頁1
列表頁2

一、實例1

先弄個最簡單的實例看看是否是能跑起來。
列表頁3jquery

so easy。

二、實例2

接下來弄個有動態數據的列表,就是這篇文章的主菜,
大概效果長這樣。
1.上一頁
2.下一頁
3.分類

列表頁4

三、導入

先裝上咱們須要的東西。android

cnpm i mint-ui -D
cnpm i vue-router -D
cnpm i less less-loader -S
cnpm i jquery -S

mint-ui => 組件庫,暫時只用到了其中的loading
vue-router => 路由
less => css的預處理器
jquery => 老朋友

四、配置

路由(vue-router):如今只有一個列表頁,那就只寫一個列表頁的路徑,配置 文件放在跟 main.js 同級的地方。ios

{
    path: '/list',
    name: 'list',
    component: List
}

關於 vue-router 更多的信息,點這裏
圖片描述git

若是有更多頁面須要配置的地方,好比編輯頁,詳情頁之類的在這裏添加就對了。

入口(main.js): 函數入口,改了一下以前的配置。github

圖片描述

五、列表頁結構

頁面分爲了三層,因此對應的頁面也有三層。
圖片描述
圖片描述ajax

六、列表頁代碼

分類vue-router

<div class="type-pnl">
    <ul class="type-list">
        <li v-for="type in types" @click="onTabSelect(type.value)" :key="type.value">{{type.text}}</li>
    </ul>
</div>

循環列表,展現內容。

<ul class="list-container">
    <li v-for="(item, i) in list" :key="item.id">
        <span class="index" :title="i + 1">{{(i + 1) > 9999 ? "..." : (i + 1)}}</span>
        <span class="face">
            <img :src="item.author.avatar_url" alt="" :title="item.author.loginname"/>
        </span>
        <span :class="{type: item.tab, good: item.good}" v-if="item.tab">{{item.tab | tab}}</span>
        <span class="name" :title="item.title">{{item.title}}</span>
    </li>
</ul>

分頁

<div class="load-more">
    <span class="prev" @click="prev" v-show="page != 1">上一頁</span>
    <span class="next" @click="next">下一頁</span>
</div>

mounted 作了三件事:
1.從路由獲取數據,也就是從地址欄裏面獲取 分類 和 頁數。
2.請求列表數據
3.設置 分類 的數據

之因此在mounted裏面設置 分類 的數據,是由於不想data裏面數據太亂。 若是把 請求數據那一段話註釋掉的話,就能夠看到 分類 的數據了。

mounted() {
    // 設置默認頁數
    this.page = parseInt(this.$route.query.page) || 1;
    // 設置默認分類
    this.tab = this.$route.query.tab;
    // 請求數據
    this.getData();
    // 設置默認頭部分類
    this.types = [{
        text: "所有",
        value: ""
    }, {
        text: "精華",
        value: "good"
    }, {
        text: "分享",
        value: "share"
    }, {
        text: "招聘",
        value: "job"
    }, {
        text: "回答",
        value: "ask"
    }];
}

methods 裏面添加 getData() 方法,將 ajax 請求回來的數據保存到 list 數據,而後把頁面滾到頂層,這樣子就可以看到數據了。
至於 common.ajaxGet() 方法,我吧全部的 ajax 請求進行了封裝到公共方法裏面了。

getData() {
    // 打開loading
    Indicator.open();
    // 請求數據
    common.ajaxGet(common.api + '/topics', {
        page: this.page, // 頁數
        tab: this.tab // 分類
    }).then(data => {
        if (data.success) {
            // 填充數據
            this.list = data.data;
            // 移動到頂層
            $(".list").animate({
                scrollTop: 0
            }, 200);
        }
        // 關閉loading
        Indicator.close();
    });
}

新建一個文件 src/lib/common.js,這個文件主要放公共的方法,如今暫時只用到裏面的 ajaxGet() 這個方法,ajaxGet() 用了個 promise 包裝了一下。

import $ from 'jquery';
let common = {
    api: " https://cnodejs.org/api/v1",
    isPhone() {
        let u = navigator.userAgent;
        let isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1; //android終端
        let isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios終端
        return isAndroid || isiOS;
    },
    getType(value) {
        let result = value;
        switch (value) {
            case "job":
                result = "招聘";
                break;
            case "good":
                result = "精華";
                break;
            case "share":
                result = "分享";
                break;
            case "ask":
                result = "問答";
                break;
            default:
                result = "所有"
                break;
        }
        return result;
    },
    ajaxGet(url, data) {
        return new Promise((resolve, reject) => {
            $.ajax({
                url: url,
                data: data || {},
                success: data => {
                    resolve(data);
                },
                error: data => {
                    reject();
                    console.error("數據請求失敗");
                }
            })
        });
    }
}
export default common;

data裏面加上幾個使用的參數就OK了。

data() {
    return {
        list: [],
        types: [],
        tab: "",
        page: 1
    }
}

使用 getType() 方法,對數據過濾一下。

filters: {
    tab(value) {
        return common.getType(value);
    }
}

加上css的話,上面幾個步驟應該就能夠看到頁面效果了。
圖片描述

這裏 分頁 還有 分類 其實都是請求同一個接口,爲了在地址欄直接改變 分類 和 分頁 有效,因此只要監控地址欄的變化,而後動態的改數據就ok了,沒必要再寫重複的請求接口了。

watch: {
    $route() {
        // 檢測路由變化
        this.page = this.$route.query.page || 1;
        this.tab = this.$route.query.tab;

        // 獲取數據
        this.getData();
    }
}

這三個方法都是改變地址欄而後經過 wacth 檢測地址欄變化去請求數據。

prev() {
    this.page--;

    // 改變路由
    let query = {
        page: this.page
    }
    if (this.tab) {
        query.tab = this.tab;
    }
    this.$router.push({
        path: 'list',
        query: query
    })
},
next() {
    // 改變當前頁數
    this.page++;

    // 改變路由
    let query = {
        page: this.page
    }
    if (this.tab) {
        query.tab = this.tab;
    }
    this.$router.push({
        path: 'list',
        query: query
    })
},
onTabSelect(value) {
    // 改變當前分類
    this.tab = value;
    this.page = 1;

    // 改變路由
    let query = {
        page: this.page
    }
    if (this.tab) {
        query.tab = this.tab;
    }
    this.$router.push({
        path: 'list',
        query: query
    })
}

輸入 http://localhost:8080/list?pa... 看看頁面是否是就會跳到對應的頁面了呢,這樣子把連接分享出去的話,也能定位到當時的狀態。
圖片描述

項目結構
圖片描述

最後

若是有什麼想跟我討論的話,請私信。
相關文章
相關標籤/搜索