Node.js+Mock.js+Vue.js实现接口和上拉加载数据

2022-06-09 13:11:00 浏览数 (1)

目录

  • 效果图
  • 一、接口
    • 1、创建项目
    • 2、代码部分
    • 3、启动服务
  • 二、页面
    • 1、代码部分

效果图

一、接口

需要用到ExpressMock.js , 如果不熟悉Express和Mock.js的建议先去他们的官网看看 Express官网 、 Mock.js官网

Express 是一个简洁而灵活的 node.js Web应用框架, 提供了一系列强大特性帮助你创建各种 Web 应用,和丰富的 HTTP 工具。 使用 Express 可以快速地搭建一个完整功能的网站。

Express 框架核心特性:

  • 可以设置中间件来响应 HTTP 请求。
  • 定义了路由表用于执行不同的 HTTP 请求动作。
  • 可以通过向模板传递参数来动态渲染 HTML 页面。

Mock.js 用来生成随机数据,拦截 Ajax 请求

1、创建项目

新建一个名为interface的文件夹 创建 package.json文件,在命令行窗口中输入> cnpm init ,接着默认回车就行 安装 express,在命令行窗口中输入> cnpm install express --save 安装 mock.js,在命令行窗口中输入> cnpm install mockjs --save 最后在interface文件夹里面新建一个名为app的js文件。

项目结构

代码语言:javascript复制
interface
├── node_modules
├── app.js
├── package.json

2、代码部分

app.js 代码

代码语言:javascript复制
var express = require("express");  //引入express模块
var app = express();  //express官网就是这么写的就是用来创建一个express程序,赋值给app。 当公式记住就行
var Mock = require("mockjs");  //引入mock模块
var MockRandom = Mock.Random;  //Mock.Random 是一个工具类,用于生成各种随机数据。

var pageCount = MockRandom.integer(1, 10);  //pageCount:页数 , 生成1-10的随机整数
var ids = 10000;  //自增长id 从10000开始
var templatesList = {};  //数据模板

//设置跨域访问
app.all("*", function(req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "X-Requested-With");
    res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
    res.header("X-Powered-By"," 3.2.1");
    res.header("Content-Type", "application/json;charset=utf-8");
    next();
});

//设置get请求
app.get("/index", function(req, res, next){
    var currentPage = parseInt(req.query.currentPage || 1); //请求的页数,如果请求接口时不传值则默认为第一页
    console.log("当前请求page页:"  currentPage); //在控制台打印当前是第几页
    ids = currentPage * 10000;
    //判断当前页是否小于等于总页数
    if(currentPage <= pageCount){
        templatesList={
            "list|20": [  //每页加载20条数据
                {
                    "id| 1": ids,
                    "title": "@ctitle(5, 50)",
                    "describe": "@cparagraph()",
                    "author": "@cname()",
                    "cover_img": "@image('200x120', '@color', '#FFF', 'Mock.js')",
                    "type|1": ["1","2"],
                    "create_time": "@datetime"
                }
            ],
            "totalPage": pageCount,
        }
    }else{
        templatesList={
            "list": [], //请求的页数大于总页数则返回空数组
            "totalPage": pageCount,
        }
    }

    var mockData = Mock.mock(templatesList); //将定义的数据模板放入mock方法中
    res.json({  //发送一个json的响应
        status: true,
        data: mockData,
        msg: "操作成功"
    });
});

//配置服务端口
var server = app.listen(3333,function(){
    var host = server.address().address;
    var port = server.address().port;
    console.log('listen at http://%s:%s',host,port);
});

3、启动服务

在命令行窗口中输入 node app.js 启动服务 启动好之后就可以在浏览器中输入 http://localhost:3333/index 或者 http://127.0.0.1:3333/index 以及 自己电脑的IPv4地址加端口的形式来访问,我电脑的ipv4地址是172.16.2.8,我就可通过 http://172.16.2.8:3333/index 来访问接口。

在命令行中输入 >ipconfig 来快速查看自己电脑上的ipv4地址。

二、页面

代码比较简单,就不用一步一步创建了,js部分也有注释。 用到了vue.js,如果不会的可以先去 Vue.js 的官网教程中去看看它的语法 还用了vue-lazyload.js 实现图片懒加载,直接引用拿过来用就行了,很方便。vue-lazyload

1、代码部分

index.css 代码

代码语言:javascript复制
*{
    margin: 0;
    padding: 0;
    list-style: none;
    box-sizing: border-box;
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
}
body{
    color: #333;
    font-family: "微软雅黑";
    background: rgb(245,245,245);
}
/*超过一行省略*/
.surplus-ellipsis {
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}
/*超过两行省略*/
.surplus-ellipsis-2 {
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
}
.container{
    width: 100%;
    min-width: 320px;
    max-width: 750px;
    margin: 0 auto;
}
.list-wrap{
    width: 100%;
    padding: 10px;
}
.list-wrap .list-section{
    width: 100%;
    padding: 0 10px;
    border-radius: 5px;
    box-shadow: 0 0 10px 1px rgba(100,100,100,0.2);
    background: #fff;
    margin-bottom: 10px;
}
.list-wrap .list-section .up{
    width: 100%;
    min-height: 80px;
    display: flex;
    flex-direction: row;
    border-bottom: solid 1px #e5e5e5;
    padding: 10px 0;
}
.list-wrap .list-section .up .left{
    width: 70%;
    padding-right: 10px;
}
.list-wrap .list-section .up .left .title{
    width: 100%;
    font-weight: bold;
}
.list-wrap .list-section .up .left .describe{
    width: 100%;
    font-size: 12px;
    color: #888;
    margin-top: 5px;
}

.list-wrap .list-section .up .right{
    width: 30%;
}
.list-wrap .list-section .up .right img{
    display: block;
    width: 100%;
    height: auto;
}

.list-wrap .list-section  .under{
    width: 100%;
    padding: 10px 0;
    display: flex;
    flex-direction: row;
    align-items: center;
    font-size: 12px;
}
.list-wrap .list-section  .under span{
    color: #888888;
}
.list-wrap .list-section  .under div:nth-of-type(1){
    flex: 1;
}

.data-finish {
    width: 100%;
    padding: 15px 0;
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: center;
    color: #8d8d8d;
    font-size: 12px;
}
.data-finish span {
    display: inline-block;
    position: relative;
}
.data-finish span:before,
.data-finish span:after {
    position: absolute;
    content: "";
    width: 40px;
    height: 1px;
    background: #e5e5e5;
    top: 10px;
}
.data-finish span:before {
    left: -45px;
}
.data-finish span:after {
    right: -45px;
}

index.html 代码

代码语言:javascript复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
    <link rel="stylesheet" href="css/index.css">
</head>
<body>

<div id="app" class="container">
    <div class="list-wrap">
        <template v-for="item in articleList">
            <div class="list-section">
                <div class="up">
                    <div class="left">
                        <div class="title surplus-ellipsis">{{item.title}}</div>
                        <div class="describe surplus-ellipsis-2">{{item.title}}</div>
                    </div>
                    <div class="right">
                        <img v-lazy="item.cover_img" alt="">
                    </div>
                </div>
                <div class="under">
                    <div v-if="item.type==1">
                        <span>作者:</span> {{item.author}}
                    </div>
                    <div v-else>匿名</div>

                    <div>
                        <span>发布时间:</span> {{item.create_time}}
                    </div>
                </div>
            </div>
        </template>
    </div>
    <div class="data-finish" v-if="currentPage>=totalPage">
        <span>数据已加载完毕</span>
    </div>
</div>

<!-- 引入jquery库 -->
<script src="http://www.jq22.com/jquery/jquery-2.1.1.js"></script>
<!-- 引入vue.js -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- 引入vue-lazyload.js 图片懒加载 -->
<script src="js/vue-lazyload.js"></script>

<script>
    $(function () {
        //使用图片懒加载方法
        Vue.use(VueLazyload, {
            preLoad: 1.3,
            error: 'img/loading.png',
            loading: 'img/loading.png',
            attempt: 1
        });

        var app = new Vue({
            el: '#app',
            data: {
                articleList: [], //文章列表
                currentPage: 1, //当前页
                totalPage: 1, //总页数
            },
            //加载完后自动执行
            mounted:function(){
                var that = this;
                that.articleListData(); //调用方法
            },
            watch: {
                articleList(){
                    var that = this;
                    that.$nextTick(function(){
                        documentHeight = parseInt($(document).height()); //整个文档的高度,总高度
                        //页面滚动事件
                        $(window).scroll(function(){
                            var self = $(this);
                            var scrollTop = parseInt(self.scrollTop()); //滚动条距离顶部高度
                            var winHeight = parseInt(self.height()); //视窗高度
                            //触底加载更多
                            if(documentHeight == winHeight   scrollTop ){
                                //如果当前页大于等于总页数则不执行下面的代码
                                if(that.currentPage >= that.totalPage){
                                    return false;
                                }

                                that.currentPage  ; //每次当前页加一
                                that.articleListData(); //再调用方法
                            }
                        });
                    });
                }
            },
            methods: {
                //请求文章列表接口
                articleListData:function () {
                    var that = this;
                    $.ajax({
                        url: "http://172.16.2.8:3333/index",  //访问自己的接口地址
                        type: "GET",
                        data: {
                            currentPage: that.currentPage,
                        },
                        async: false,
                        success:function (res) {
                            that.totalPage = res.data.totalPage;
                            //我这儿用的map方法,也可以用for循环
                            res.data.list.map(function (item,index) {
                                that.articleList.push(item); //将数据push到articleList数组中
                            });
                        }
                    });
                },
            }
        });
    });
</script>

</body>
</html>

简单的接口以及上拉加载例子就完成了

0 人点赞