从 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... 看看页面是否是就会跳到对应的页面了呢,这样子把连接分享出去的话,也能定位到当时的状态。
图片描述

项目结构
图片描述

最后

若是有什么想跟我讨论的话,请私信。
相关文章
相关标签/搜索