【好好学习】mh_h5

寵の児 提交于 2020-04-14 07:58:13

【今日推荐】:为什么一到面试就懵逼!>>>

老规矩先放下有趣的项目的github地址:
https://github.com/yw738/mh_h5
然后我们放下动图



接下来我们一起分析代码吧
看包的话,UI部分是有用到有赞的UI
首先我们看main.js

import Vue from 'vue'

import router from './router'
import store from './store'
import axios from 'axios'
//获取带参数的值
import qs from 'qs'
import App from './App.vue'
import Vant from 'vant';
import 'vant/lib/index.css';
import "@/components/Js/index"
Vue.use(Vant);
Vue.config.productionTip = false
Vue.prototype.$axios = axios;
Vue.prototype.$qs = qs;

new Vue({
    router,
    store,
    render: h => h(App)
}).$mount('#app')

接下来看route.js中,我们大概会有哪些入口页面
里面有用到路由懒加载

import Vue from 'vue'
import Router from 'vue-router'
import List from './views/List.vue'
import Search from './views/Search.vue'
Vue.use(Router)

export default new Router({
    mode: 'hash',
    base: process.env.BASE_URL,
    routes: [{
            path: '/',
            name: 'home',
            component: () =>
                import ('./views/Home.vue')
        }, {
            path: '/list',
            name: 'list',
            component: List
        },
        {
            path: '/search',
            name: 'search',
            component: Search
        },
        {
            path: '/about',
            name: 'about',
            component: () =>
                import ('./views/About/About.vue'),//按需加载
            // meta: {
            //     isUseCache: true, // 是否需要缓存
            //     keepAlive: true // 缓存
            // }
        },
        {
            path: '/detail',
            name: 'detail',
            component: () =>
                import ('./views/Detail.vue')
        }
    ]
})

接下来我们来看App.vue
在入口route-view中加了判断是不是移动端,不是不显示内容,是就显示内容
同时还进行了缓存判断,进入到某些页面就会缓存起来

<template>
  <div id="app">
    <keep-alive include="AboutIndex" max="1" :exclude="isKeepalive?'':'AboutIndex'">
      <router-view v-if="isShow" />
    </keep-alive>
  </div>
</template>
<script>
import { Dialog } from "vant";
export default {
  data() {
    return {
      isShow: false,//验证用户是否是移动端预览
      isKeepalive: false,//是否对详情进行缓存
    };
  },
  methods: {
    init() {
      var sUserAgent = navigator.userAgent.toLowerCase();
      var bIsIpad = sUserAgent.match(/ipad/i) == "ipad";
      var bIsIphoneOs = sUserAgent.match(/iphone os/i) == "iphone os";
      var bIsMidp = sUserAgent.match(/midp/i) == "midp";
      var bIsUc7 = sUserAgent.match(/rv:1.2.3.4/i) == "rv:1.2.3.4";
      var bIsUc = sUserAgent.match(/ucweb/i) == "ucweb";
      var bIsAndroid = sUserAgent.match(/android/i) == "android";
      var bIsCE = sUserAgent.match(/windows ce/i) == "windows ce";
      var bIsWM = sUserAgent.match(/windows mobile/i) == "windows mobile";
      if (
        bIsIpad ||
        bIsIphoneOs ||
        bIsMidp ||
        bIsUc7 ||
        bIsUc ||
        bIsAndroid ||
        bIsCE ||
        bIsWM
      ) {
        this.isShow = true;
        //这是移动端
      } else {
        //这是pc端
        this.isShow = false;
        Dialog.alert({
          title: "提示",
          message: "请使用移动设备来浏览该网页,以此得到更友好的体验!"
        }).then(() => {
          // on close
        });
      }
    }
  },
  created() {
    this.init();
  },
  watch: {
    //监听路由 判断是否进行keep-alive动态缓存 
    $route: function(to, from) {
      console.log('to>>>>>>>>>>>>>',to)
      console.log('from>>>>>>>>>>>',from)
      if (to.name === "detail"||to.name === "about") {
        this.isKeepalive = true;
      }else{
        this.isKeepalive = false;
      }
    }
  },
};
</script>

接下来我们开始看Home页面
有搜索还有轮播,以及封装了组件,传入大量图片

//HOME.vue
<template>
  <div class>
    <div class="flex tipBox">
      <van-search class="serchBox" disabled placeholder="请输入搜索关键词" @click="toSearch" shape="round" />
      <div>
        <img
          @click="setHouse"
          src="http://css.mangabz.com/v201911081548/mangabz/images/mobile/class.png"
          alt
        />
        <img
          @click="userHome"
          src="http://css.mangabz.com/v201911081548/mangabz/images/mobile/icon_user.png"
          alt
        />
      </div>
    </div>
    <div class="swiper">
      <van-swipe :autoplay="3000" :loop="true" indicator-color="white">
        <van-swipe-item v-for="(item,i) in imgList" :key="i">
          <router-link :to="item.link">
            <img :src="item.url" />
          </router-link>
        </van-swipe-item>
      </van-swipe>
    </div>

    <homeList :tit="topBox" :data="topBoxList" />
    <homeList :tit="bottomBox" :data="bottomList" />
    <!-- <div class="index_border" /> -->
    <!-- 申明 -->
    <div class="sm">
      声明 :
      <br />数据均来源于网络,并不参与存储、上传、创作,版权争议与本站无关。 仅学习交流使用,请勿用于商业(非法)用途!否则,一切后果请自行承担!
    </div>
  </div>
</template>

<script>
import { homeApi } from "@/api/api";
import { mapState } from "vuex";
import homeList from "./Home/HomeList.vue";
import { Dialog } from "vant";

export default {
  name: "search",
  data() {
    return {
      imgList: [
        {
          link: "/about?url=wbmh69831",
          url:
            "http://img.manhua.weibo.com/hcover/2018/09/07/2084322240_aOFgE7Cs.jpg"
        },
        {
          link: "/about?url=wbmh72406",
          url:
            "http://img.manhua.weibo.com/hcover/2019/07/23/6580997788_6MmPC0WJ.jpg"
        },
        {
          link: "/about?url=wbmh71017",
          url:
            "http://img.manhua.weibo.com/hcover/2018/12/24/6469545963_KjDiUXtX.jpg"
        },
        {
          link: "/about?url=wbmh69375",
          url:
            "http://img.manhua.weibo.com/hcover/2018/09/21/2660188431_ELQqGaB3.jpg"
        }
      ],
      topBoxList: [
        {
          link: "/about?url=http%3A%2F%2F99770.hhxxee.com%2Fcomic%2F32644",
          img:
            "https://gss3.bdstatic.com/7Po3dSag_xI4khGkpoWK1HF6hhy/baike/s%3D220/sign=9ed36f5f3f4e251fe6f7e3fa9787c9c2/e7cd7b899e510fb3d0c3baf2d633c895d0430cf9.jpg",
          tit: "租借女友",
          txt:
            "作品讲述的是大学生木之下和也和从事恋人租赁服务“租赁女朋友”工作的水原千鹤间的恋爱喜剧"
        },
        {
          link: "/about?url=mh123%2Fcomic%2F8550.html",
          img: "https://img.detatu.com/upload/vod/2019-01-07/15467915857.jpg",
          tit: "穿越球场",
          txt:
            "绪方夏树,初中刚毕业的爱好篮球的北国学生,因为以前的队友的怂恿而报名参加篮球名校藤原学院的选秀会"
        },
        {
          link: "/about?url=mhz209859",
          img:
            "https://gss3.bdstatic.com/7Po3dSag_xI4khGkpoWK1HF6hhy/baike/c0%3Dbaike116%2C5%2C5%2C116%2C38/sign=8f5f2b8438adcbef15397654cdc645b8/a6efce1b9d16fdfaf0acd4aebd8f8c5495ee7ba9.jpg",
          tit: "风夏",
          txt:
            "该漫画是濑尾公治以前作《凉风》的主人公秋月大和与朝比奈凉风之女——秋月风夏为女主角"
        },
        {
          link: "/about?url=mh123%2Fcomic%2F2985.html",
          img: "https://img.detatu.com/upload/vod/2019-01-06/154679024514.jpg",
          tit: "东京80年代",
          txt: "纯平参加早稻田大学的入学考试发现一个乡下女孩作弊(森下爱)"
        },
        {
          link: "/about?url=http%3A%2F%2F99770.hhxxee.com%2Fcomic%2F3852",
          img:
            "https://gss0.bdstatic.com/-4o3dSag_xI4khGkpoWK1HF6hhy/baike/c0%3Dbaike150%2C5%2C5%2C150%2C50/sign=352ab83f9922720e6fc3eaa81aa26123/5243fbf2b21193138ca3e2ed64380cd790238d8e.jpg",
          tit: "有你的小镇",
          txt: "桐岛青大追随突然消失的枝叶柚希,离开故乡广岛前往东京"
        },
        {
          link: "/about?url=ccmh%2Fmanhua%2F10739",
          img:
            "https://gss1.bdstatic.com/9vo3dSag_xI4khGkpoWK1HF6hhy/baike/c0%3Dbaike92%2C5%2C5%2C92%2C30/sign=3736e138a66eddc432eabca958b2dd98/472309f7905298224bccf61edcca7bcb0b46d474.jpg",
          tit: "凉风",
          txt:
            "男主角秋月大和独自来东京求学,居住在澡堂宿舍楼中并与女主角朝比奈凉风恋爱的故事"
        }
      ],
      bottomList: [
        {
          link: "/about?url=mh123%2Fcomic%2F8652.html",
          img:
            "https://gss0.bdstatic.com/-4o3dSag_xI4khGkpoWK1HF6hhy/baike/c0%3Dbaike116%2C5%2C5%2C116%2C38/sign=bf79a24c0cb30f242197e451a9fcba26/cefc1e178a82b9018e60ca1e708da9773812efca.jpg",
          tit: "寄生兽",
          txt: "平凡的高中生泉新一和寄生在他体内"
        },
        {
          link: "/about?url=mhz209676",
          img:
            "http://oss.mkzcdn.com/comic/cover/20190416/5cb571cd52a9f-899x1200.jpg!width-300",
          tit: "黑社会的超能力女儿",
          txt: "黑社会的超能力女儿漫画,黑社会干部与从天"
        },
        {
          link: "/about?url=mh123%2Fcomic%2F8816.html",
          img: "https://img.detatu.com/upload/vod/2019-01-07/15467916473.jpg",
          tit: "请叫我英雄",
          txt: "英雄是个曾有过半年连载经验的漫画家"
        },
        {
          link: "/about?url=http%3A%2F%2F99770.hhxxee.com%2Fcomic%2F23246",
          img:
            "https://gss2.bdstatic.com/9fo3dSag_xI4khGkpoWK1HF6hhy/baike/c0%3Dbaike116%2C5%2C5%2C116%2C38/sign=6e79620112950a7b613846966bb809bc/21a4462309f79052ba537e0903f3d7ca7bcbd5bc.jpg",
          tit: "家有女友",
          txt: "夏生因为经常在顶楼遇上来此散心的女老师"
        },
        {
          link: "/about?url=mhdhttps%3A%2F%2Fm.manhuadui.com%2Fmanhua%2Fjinjidejuren%2F",
          img: "https://img01.eshanyao.com/images/cover/201810/15391165129WGophC1Qxvw-Z-u.jpg",
          tit: "进击的巨人",
          txt: "进击的巨人的漫画"
        },
        {
          link: "/about?url=mh123%2Fcomic%2F10749.html",
          img: "https://img.detatu.com/upload/vod/2019-01-07/154679216217.jpg",
          tit: "鬼灭之刃",
          txt: "时值日本大正时期。传说太阳下山后,恶鬼出没吃人"
        }
      ],

      topBox: {
        title: "人氣推薦"
      },
      bottomBox: {
        title: "編輯推薦"
      }
    };
  },
  methods: {
    toSearch() {
      this.$router.push({ path: "/search" });
    },
    /*
     *用户收藏
     */
    setHouse() {
      Dialog.alert({
        title: "提示",
        message: "暂未开放收藏列表!"
      }).then(() => {
        // on close
      });
    },
    /*
     *用户
     */
    userHome() {
      Dialog.alert({
        title: "提示",
        message: "暂未开放个人中心!"
      }).then(() => {
        // on close
      });
    }
  },
  created() {},
  computed: {},
  components: {
    homeList
  }
};
</script>

<style lang="less" scope>
.swiper,
.swiper img {
  height: 220px;
  width: 100%;
}
.tipBox {
  justify-content: space-between;
  align-items: center;
}
.serchBox {
  width: 55%;
}
.tipBox img {
  height: 1.4rem;
  width: 1.4rem;
  margin: 0 1rem;
}
.sm {
  text-align: left;
  padding: 1rem;
  font-size: 0.8rem;
  color: red;
}
</style>

接下来看其引入的homeList组件

<template>
  <div class="home_box">
    <div class="index_border" />
    <div class="flex flexCen head">
      <div class="tit">{{tit.title}}</div>
      <div class="flex flexCen more">
        <span>更多</span>
        <van-icon name="arrow" size="1.5rem" />
      </div>
    </div>
    <div class="content">
      <van-row>
        <van-col class="home_box_list" span="8" v-for="(v,i) in data" :key="i">
          <router-link :to="v.link">
            <div>
              <img :src="v.img" />
              <p class="tit textOverflow">{{v.tit}}</p>
              <p class="txt textOverflow">{{v.txt}}</p>
            </div>
          </router-link>
        </van-col>
      </van-row>
    </div>
  </div>
</template>

<script>
export default {
  name: "",
  data() {
    return {};
  },
  props: {
    tit: { type: Object, default: {} },
    data: { type: Array, default: [] }
  }
};
</script>

<style lang="less" scoped>
.home_box {
  background: #fff;
}
.head {
  height: 2rem;
  line-height: 2rem;
  padding: 1rem 1rem 0.5rem;
}
.head .tit {
  font-size: 20px;
  color: #121212;
  letter-spacing: 0;
  font-weight: bold;
}
.home_box .more span {
  margin-right: 0.4rem;
  font-size: 1rem;
}
.content {
  padding: 0 0.5rem;
}
.content .home_box_list {
  //   margin-right: 1rem;
  padding: 0.5rem;

  box-sizing: border-box;
}
.content div:nth-child(3n) {
  margin-right: 0;
}
.content img {
  width: 100%;
  height: 140px;
  border-radius: 0.5rem;
}
.content .tit {
  margin-top: 5px;
  font-size: 16px;
  color: #121212;
  letter-spacing: 0;
  line-height: 24px;
}
.content .txt {
  margin-top: 3px;
  font-size: 12px;
  color: #909090;
  letter-spacing: 0;
  line-height: 14px;
  min-height: 14px;
  margin-bottom: 0;
}
</style>


接下来看search页面

//search.vue
<template>
  <div class="top">
    <van-search v-model="value" placeholder="请输入搜索关键词" @search="onSearch" show-action shape="round">
      <div slot="action" @click="cancel">取消</div>
    </van-search>
  </div>
</template>

<script>
import { mhSerchApi } from "@/api/api";
import { Toast } from "vant";
import { mapActions, mapState } from "vuex";
export default {
  name: "",
  data() {
    return {
      value: ""
    };
  },
  inject: ["getHomeData"],
  methods: {
    ...mapActions(["setSerchKey"]),
    onSearch() {
      let { value: val, getHomeData } = this;
      // console.log("搜索的值:", val);
      console.log('this>>>>>>>>>>',this)
      if (val.trim() === "") {
        getHomeData();
        this.setSerchKey("");
        return;
      }
      this.$emit("serch", []);
      loading();
      mhSerchApi(val).then(res => {
        let { list, code } = res.data;
        if (code === 0) {
          this.setSerchKey(val);
          this.$emit("serch", list);
        } else {
          Toast.fail("服务器挂了");
        }
      });
    },
    cancel() {
      this.$router.push({
        path: "/"
      });
    }
  },
  created() {
    let { serchKey, onSearch } = this;
    if (serchKey !== "") {
      this.value = serchKey;
      onSearch();
    }
  },
  computed: {
    ...mapState(["serchKey"])
  }
};
</script>

<style lang='less' scoped>
</style>

接下来看about页面

<template>
  <div class="about">
    <div class="back" @click="back">
      <img src="./../../assets/return-details.png" alt />
    </div>
    <div class="img_box">
      <img :src="data.cover" @error="imgErr" class="img" />
    </div>
    <div class="item_box">
      <van-row class="positionR">
        <van-col span="7" class="about_img">
          <img :src="data.cover" />
        </van-col>
        <van-col span="17">
          <div class="tit_box">
            <h3 class="title textOverflow">{{data.name}}</h3>
            <p class="txt">
              <van-icon name="user-o" />
              {{data.author}}
            </p>
            <p class="txt">
              <van-icon name="underway-o" />
              {{data.time}}
            </p>
          </div>
          <div class="btn_box">
            <!-- like -->
            <!-- <van-icon
              :name="isHouse?'like':'like-o'"
              size="2em"
              color="#fb7299"
              @click="setHouse"
              class="like"
            />-->
            <van-button round color="#fb7299" @click="start" type="info">观看{{startJson.name}}</van-button>
          </div>
        </van-col>
      </van-row>
    </div>
    <div
      class="tips tips_box"
      @click="isAllShowTips = !isAllShowTips"
    >{{isAllShowTips?data.introduce:data.introduce.substring(0,90) + '...'}}</div>
    <div class="zj_box">
      <van-row>
        <van-col span="12">
          <div class="sort" style="float:left">全部章节({{list.length}})</div>
        </van-col>
        <van-col span="12">
          <div class="sort" @click="sortFn">
            {{sort?'升序':'降序'}}
            <!-- <van-icon size="1.4em" class="sortTop" name="exchange" /> -->
          </div>
          <div class="sort" @click="chListFn" style="margin: 0 1em;">
            <van-icon size="1.4em" class="sortTop" name="apps-o" />
          </div>
        </van-col>
      </van-row>
    </div>
    <div id="list_box">
      <van-row>
        <van-col :span="listSize" v-for="(item,i) in list" :key="i">
          <div class="list_box">
            <router-link
              :to="{path:'/detail',query:{url:item.url,num:item.num}}"
              class="span"
            >{{item.tit}}</router-link>
          </div>
        </van-col>
      </van-row>
    </div>
  </div>
</template>

<script>
import { mhListApi } from "@/api/api";
export default {
  name: "AboutIndex",
  data() {
    return {
      data: {
        introduce: ""
      },
      list: [],
      sort: true,
      startJson: {
        name: "",
        url: ""
      },
      isAllShowTips: false,
      backUrl: null,
      listSize: 8
    };
  },
  methods: {
    back() {
      this.$router.push({ path: this.backUrl || "/" });
    },
    init() {
      loading();
      //获取路由的url
      let { url } = this.$route.query;
      window.sessionStorage.setItem("parentUrl", url);
      let reg = /0|1|2|3|4|5|6|7|8|9|一|二|三|四|五|六|七|八|九|十/g;
      mhListApi(url)
        .then(res => {
          let { data, list, code } = res.data;
          console.log('......data',res.data)
          if (code === 0) {
            list.map(v => {
              v.tit = v.num.substring(0, 10);
            });
            this.startJson = {
              name: list[0].tit,
              url: list[0].url
            };
            window.sessionStorage.setItem("mhList", JSON.stringify(list));
            this.data = data;
            this.list = list;
          }
          load.clear();
        })
        .catch(err => {
          load.clear();
        });
    },
    sortFn() {
      //DESC ASC
      this.sort = !this.sort;
      let arr = this.list;
      this.list = [];
      this.list = arr.reverse();
    },
    chListFn() {
      console.log('listSize',this.listSize)
      this.listSize == 8 ? (this.listSize = 12) : (this.listSize = 8);
    },
    start() {
      let { url } = this.startJson; //这个url 类似id
      console.log('....this.startJson...',this.startJson)
      this.$router.push({
        path: "/detail",
        query: {
          url: url
        }
      });
    },
    setHouse() {
      //添加收藏
    },
    imgErr() {
      console.log('imgBg',imgBg)
      let imgBg = document.querySelector(".img_box .img");
      imgBg.style.background = "#fb7299b5";
    }
  },
  created() {
    this.init();
  },
  computed: {
    isHouse: function() {
      return false;
    }
  },
  beforeRouteEnter(to, from, next) {
    next(vm => {
      if (from.name === "home" || from.name === "list") {
        vm.backUrl = from.path;
      }
    });
  }
};
</script>

<style lang='less' scoped>
@imgHeight: 160px;
.color,
.about {
  color: "#333";
}
.img_box {
  width: 100%;
  height: @imgHeight;
  overflow: hidden;
}
.img {
  width: 100%;
  height: @imgHeight * 2;
  margin-top: -50px;
  filter: blur(10px);
}
.tips_box {
  padding: 0 10px;
  margin: 70px 0 10px;
  text-indent: 2em;
  color: #999;
  font-size: 12px;
  line-height: 16px;
}

.item_box {
  width: 93%;
  margin: 0 3.5%;
  height: auto;
  position: absolute;
  top: 76px;
  left: 0;
}
.item_box img {
  height: 100%;
  // width: 100%;
  border-radius: 2px;
  box-shadow: 0px 0px 11px -10px #000;
}
.tit_box {
  padding: 0 4%;
  box-sizing: border-box;
}
.title {
  font-size: 21px;
  font-weight: bold;
  margin: 0;
  color: #fff;
}
.txt {
  font-size: 12px;
  margin: 2% 0;
  font-weight: normal;
  color: #fff;
}
.txt i {
  margin: 3px 3px 0 0;
  float: left;
}
.btn_box {
  position: absolute;
  bottom: 0;
  right: 0;
}
.btn_box button {
  width: 200px;
}
.zj_box {
  color: #505050;
  padding: 0 10px;
  box-sizing: border-box;
  font-size: 14px;
  height: 20px;
  line-height: 20px;
}
.zj_box .sort {
  height: 20px;
  line-height: 20px;
  font-size: 14px;
  text-align: right;
  color: #505050;
  float: right;
  display: flex;
  justify-content: center;
  align-items: center;
}
.sortTop {
  float: right;
  margin-left: 4px;
  transform: rotate(90deg);
  color: #fb7299;
}
.like {
  margin: 6px 6px 0 0;
  float: left;
}
#list_box {
  margin-bottom: 30px;
}
.about_img {
  height: 140px;
  overflow: hidden;
}
</style>

接下来看detail页面

这个里面挺有意思的,是从路由里面取到数目,做上一章下一章的,然后还有滚动分页,很好玩啊,做这个的思想也很有意思

<template>
  <div>
    <!-- 图片盒子 -->
    <div id="img_box" @click="choseType">
      <img :src="v.img" v-for="(v,i) in list" :key="i" />
    </div>
    <!-- 操作按钮 -->
    <div class="nav" v-if="isShow">
      <div class="back" @click="back">
        <img src="./../assets/return-details.png" alt />
      </div>
      <div class="morezj">
        <van-button
          round
          color="#fb7299"
          @click="more"
          type="info"
        >{{json.num&&json.num.length>7?json.num.substring(0,7) + '..':json.num}}</van-button>
      </div>
      <div class="nextZj">
        <van-button round color="#000" @click="prevGet" type="info">上一话</van-button>
        <van-button round color="#000" @click="nextGet" type="info">下一话</van-button>
      </div>
    </div>

    <!-- 选择章节 -->
    <van-popup
      v-model="popup"
      @close="cancle"
      :duration=".2"
      round
      position="bottom"
      class="popupClass"
      :style="{ height: '70%'}"
    >
      <div>
        <van-row>
          <van-col span="8" v-for="(item,i) in mhlist" :key="i">
            <div class="list_box">
              <router-link
                :to="{path:'/detail',query:{url:item.url,num:item.num}}"
                :class="index ==i?'span active':'span' "
                @click.native="goDetail(item)"
              >{{item.tit}}</router-link>
            </div>
          </van-col>
        </van-row>
      </div>
    </van-popup>
  </div>
</template>

<script>
import { mhDetailsApi } from "@/api/api";
import { Toast } from "vant";
export default {
  name: "",
  data() {
    return {
      allList: [], //所有的图片
      list: [], //图片列表
      json: {}, //当前章节
      isShow: false, //是否显示操作栏
      popup: false, //是否显示章节列表
      mhlist: [], //该漫画所有章节列表
      index: null, //当前漫画的章节
      timer: true, //延时执行
      page: {
        pageSize: 5, //页数
        pageNo: 1, //页码
        maxPage: 1 //最大页数
      }, //分页
      pageIsOver: false //当前章节分页是否结束
    };
  },
  methods: {
    back() {
      let url = window.sessionStorage.getItem("parentUrl");
      this.$router.push({
        path: "/about",
        query: {
          url: url
        }
      });
    },
    cancle() {
      this.isShow = false;
      this.popup = false;
    },
    choseType() {
      console.log('....is')
      this.isShow ? (this.isShow = false) : (this.isShow = true);
    },
    //页面数据初始化
    getData() {
      this.init();
      let { pageSize, pageNo } = this.page;
      let { url } = this.json;
      loading();
      mhDetailsApi(url).then(res => {
        let { code, list } = res.data;
        if (code === 0) {
          this.allList = list;
          this.list = list.slice(parseInt(pageNo.toString()) - 1, parseInt(pageSize.toString()));
          this.page = {
            pageSize: pageSize,
            pageNo: pageNo,
            maxPage: Math.ceil(list.length / parseInt(pageSize))
          };
        }
        load.clear();
      });
    },
    more() {
      let { url } = this.json;
      console.log('url>>>>>>>>>>>',url)
      this.mhlist = JSON.parse(window.sessionStorage.getItem("mhList"));
      console.log('this.mhlist>>>>>>>>>>>??????????',this.mhlist)
      this.mhlist.forEach((v, i) => {
        if (v.url === url) {
          this.index = i;
          return false;
        }
      });
      this.popup = true;
    },
    goDetail(item) {
      console.log('...this.json,item...',)
      Object.assign(this.json,item);
      this.getData();
    },
    getNextUrl() {
      let { url } = this.json;
      let list = JSON.parse(window.sessionStorage.getItem("mhList"));
      let nextJson = null;
      list.forEach((v, i) => {
        if (url === v.url) {
          if (i + 1 >= list.length) return false; //如果是最后一章 直接弹出。
          nextJson = list[i + 1];
        }
      });
      if (nextJson === null) {
        console.log("最后一话");
        return false;
      } else {
        return nextJson;
      }
      console.log('houhhouh',nextJson)
    },
    getPrevUrl() {
      let { url } = this.json;
      console.log(this.json,'...this.json')
      let list = JSON.parse(window.sessionStorage.getItem("mhList"));
      console.log('list',list)
      let nextJson = null;
      list.forEach((v, i) => {
        if (url === v.url) {
          if (i - 1 < 0) return false; //如果是最后一章 直接弹出。
          nextJson = list[i - 1];
        }
      });
      if (nextJson === null) {
        console.log("第一话");
        return false;
      } else {
        return nextJson;
      }
    },
    /*
     * 调用分页
     */
    pageChange() {
      let {
        allList,
        page: { pageSize, pageNo, maxPage }
      } = this;
      pageNo++;
      if (pageNo <= maxPage) {
        this.page = {
          pageNo: pageNo,
          pageSize: pageSize,
          maxPage: maxPage
        };
        this.list = allList.slice(0, pageNo * pageSize);
      } else {
        if(!this.pageIsOver){
          console.log("分页结束");
          Toast("到底了");
          this.pageIsOver = true;
        }
      }
    },
    /*
     *监听下拉
     */
    scroll() {
      let box = document.querySelector("#img_box");
      let that = this;
      let scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
      let pageHeight = window.screen.availHeight;
      if (box == null) return;
      let h = box.clientHeight;
      if (scrollTop + pageHeight + 300 > h) {
        clearTimeout(that.timer);
        that.timer = setTimeout(() => {
          that.pageChange(); //开始分页
        }, 300);
        return;
      }
    },
    init() {
      this.page = {
        pageSize: 5, //页数
        pageNo: 1, //页码
        maxPage: 1 //最大页数
      }; 
      this.pageIsOver = false;
      this.isShow=false;
      this.popup=false;
      this.$nextTick(()=>{
        document.documentElement.scrollTop?document.documentElement.scrollTop=0:document.body.scrollTop=0;
      }) //滚动条清零
    },
    /*
     * 切换章节
     */
    prevGet() {
      if (!this.getPrevUrl()) {
        Toast("没有上一章");
        return;
      } //检测是否是第一话
      this.json = this.getPrevUrl();
      this.getData();
    },
    nextGet() {
      if (!this.getNextUrl()) {
        Toast("最后一话!");
        return;
      } //检测是否是最后一章
      this.json = this.getNextUrl();
      this.getData();
    }
  },
  created() {
    let { url, num } = this.$route.query;
    this.json = {
      url: url,
      num: num
    };
    this.getData();
  },
  mounted() {
    window.addEventListener("scroll", this.scroll, false);
  },
  beforeDestroy() {
    if (window.removeEventListener) {
      window.removeEventListener("scroll", this.scroll, false);
    } else if (window.attachEvent) {
      window.attachEvent("scroll", this.scroll, false);
    }
    console.log("初始化scroll事件。");
  }
};
</script>

<style lang='less' scoped>
#img_box {
  display: inline-block;
  width: 100%;
}
#img_box img {
  float: left;
  width: 100%;
  border-bottom: 4px solid black;
}
.nav {
  position: fixed;
  bottom: 15px;
  left: 10px;
  right: 10px;
  z-index: 999;
}
.nav .back {
  position: relative;
  width: 40px;
  height: 40px;
  padding: 0;
  left: 0;
  top: 0;
}
.nav > div {
  float: left;
}
.nav .back img {
  width: 40px;
  height: 40px;
  background: black;
  border-radius: 50%;
}
.morezj {
  margin-left: 10px;
}
.popupClass {
  padding: 10px 0;
}
.nav .nextZj {
  float: right;
  line-height: 40px;
  font-size: 1rem;
}
.nav .nextZj  button{
  margin-left:0.5rem; 
}
</style>

看一下搜索的list页面

<template>
  <div>
    <serch @serch="serch" />
    <div id="content">
      <van-row>
        <van-col span="8" v-for="(item, index) in data" :key="index">
          <router-link :to="{ path: '/about', query: { url: item.url } }">
            <div class="list">
              <div class="img_box">
                <img :src="item.cover" />
              </div>
              <div>
                <h3 class="tit">{{ item.name }}</h3>
                <p class="zj">{{ item.latest }}</p>
              </div>
            </div>
          </router-link>
        </van-col>
      </van-row>
    </div>
  </div>
</template>

<script>
import { homeApi } from "@/api/api";
import serch from "./Module/Search.vue";
import { mapState } from "vuex";
export default {
  name: "list",
  data() {
    return {
      data: [],
      allList:[],
      page:{
        pageSize:20,
        pageNo:1
      }
    };
  },
  provide() {
    return {
      getHomeData: this.getHomeData
    };
  },
  methods: {
    serch(list) {
      this.data = [];
      this.data = list;
      if(load&&load.clear)load.clear();
    },
    getHomeData() {
      homeApi().then(res => {
        let { mhlist } = res.data;
        this.data = mhlist.slice(0, 30);
      });
    },
  },
  created() {
    if (this.serchKey === "") {
      this.getHomeData();
    }
  },
  computed: {
    ...mapState(["serchKey"])
  },
  components: {
    serch
  }
};
</script>

<style lang="less">
.top {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  border-bottom: 1px solid #ebeef5;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  transition: all ease 0.3;
}
.list {
  height: 190px;
  margin: 5px;
  box-sizing: border-box;
}
#content {
  margin-top: 56px;
}
.img_box,
.img_box img {
  width: 100%;
  height: 150px;
}
.tit,
.zj {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  margin: 2px 0 0 0;
}
.tit {
  color: #202121;
  font-size: 13px;
}
.zj {
  color: #999;
  font-size: 12px;
}
</style>
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!