vue---better-scroll 右侧内容滑动时 左侧目录更着变化

394 阅读1分钟

1. 安装better-scroll

npm install better-scroll

2.  在具体实现功能里引用better-scroll 并且在store里引入数据

import BetterScroll from 'better-scroll';import { mapGetters } from 'vuex';

3.  在页面的左右目录外层添加ref 做了标记

4.  在data中定义

5.  在computed中引入数据; 在watch 监听左右两边滚动和右边列表高度;并且监听currentIndex

6.  在html中定义左侧滑动的样式

7.methods 里定义 添加this._initBScroll();和this._initRightHeight();方法;用于watch里监听

8. 添加点击左侧目录,右侧内容更着变化的方法

最后完整代码

<template>  <div class="all">    <p>应用列表</p>    <div class="main">      <div class="mulu">        <div class="fenlei">分类目录</div>        <div ref="category">          <ul class="content" id="category">            <li              v-for="(item, i) in applist"              ref="menuList"              :key="i"              :class="{ current: i === currentIndex }"              @click="clickList(i)"            >              <span :class="{ xianSpan: i === currentIndex }"></span>              <span class="btn">{{ item.categoryName }}</span>            </li>          </ul>        </div>      </div>      <div class="wrapper" ref="wrapper">        <ul class="content" ref="itemList">          <li v-for="(app, index) in applist" :key="index" class="cateAndlist">            <div class="catename">{{ app.categoryName }}</div>            <div class="appAll">              <div v-for="(item, i) in app.appList" :key="i" class="listonce" :class="{ nopower: !item.authorized }">                <div class="getInto" @click="toapp(item.appUrl)" v-if="item.authorized">                  <span>进入</span>                  <img src="@/assets/img/goapp.png" width="12" height="12" class="goimg" alt="" />                </div>                <div v-else class="getIntos">                  <span>访问权限未授权</span>                </div>                <div class="bottom">                  <img :src="!item.iconUrl ? defaluteIcon : item.iconUrl" alt="" />                  <div class="bottom_right">                    <div class="appname">{{ item.appName }}</div>                    <div class="description" :title="item.description">{{ item.description }}</div>                  </div>                </div>              </div>            </div>          </li>        </ul>      </div>    </div>  </div></template><script>import BetterScroll from 'better-scroll';import { mapGetters } from 'vuex';export default {  name: 'portal',  data() {    return {      defaluteIcon: 'http://imservice.oss-cn-north-1.unicloudsrv.com/20200723044236469_workeractive.png',      scrollY: 0, //右侧列表滑动的y轴坐标      rightLiTops: [], //所有分类头部位置      leftBscroll: null,      rightBscroll: null,    };  },  watch: {    applist() {      //监听数据      this.$nextTick(() => {        // this.wordlimit();        //左右两边滚动        this._initBScroll();        //右边列表高度        this._initRightHeight();      });    },  },  computed: {    ...mapGetters(['applist']),    currentIndex(index) {      const { scrollY, rightLiTops } = this;      return rightLiTops.findIndex((tops, index) => {        this._initLeftScroll(index);        return scrollY >= tops && scrollY < rightLiTops[index + 1];      });    },  },  mounted() {    // 调用 获取app列表的接口    this.$store.dispatch('getHomeAppList');  },  methods: {    toapp(url) {      window.open(url);    },    _initBScroll() {      // 挂在左右的实例      this.leftBscroll = new BetterScroll(this.$refs.category, {});      this.rightBscroll = new BetterScroll(this.$refs.wrapper, {        scrollY: true,        click: true,        mouseWheel: true,      });      // 监听右侧内容滑动时,左侧目录选中样式跟着变      this.rightBscroll.on('scrollEnd', pos => {        this.scrollY = Math.abs(pos.y);      });      // this.wordlimit();    },    _initRightHeight() {      let itemArray = []; //定义一个伪数组      let top = 0;      itemArray.push(top);      //获取右边所有li的礼      let allList = this.$refs.itemList.getElementsByClassName('cateAndlist');      //allList伪数组转化成真数组      Array.prototype.slice.call(allList).forEach(li => {        top += li.clientHeight; //获取所有li的每一个高度        itemArray.push(top);      });      this.rightLiTops = itemArray;    },    //点击左边实现滚动    clickList(index) {      this.scrollY = this.rightLiTops[index];      this.rightBscroll.scrollTo(0, -this.scrollY, 200);    },    _initLeftScroll(index) {      let menu = this.$refs.menuList;      let el = menu[index];      this.leftBscroll.scrollToElement(el, 300, 0, -300);    },    wordlimit() {      var cname = document.getElementsByClassName('description');      for (var i = 0; i < cname.length; i++) {        var nowhtml = cname[i].innerHTML;        var nowlength = cname[i].innerHTML.length;        if (nowlength > 22) {          cname[i].innerHTML = nowhtml.substr(0, 22) + '…';        }      }    },  },};</script><style lang="scss" scoped>.all {  width: calc(100% - 40px);  height: calc(100% - 40px);  margin: 20px;  background: #ffffff;  box-shadow: 0px 0px 20px 0px rgba(0, 0, 0, 0.07);  border-radius: 4px;  p {    font-size: 20px;    margin: 0;    font-family: SourceHanSansCN-Bold, SourceHanSansCN;    font-weight: bold;    color: #000000;    padding: 20px 26px;    border-bottom: 2px solid #eeeeee;  }  .main {    padding: 20px 20px 0 20px;    display: flex;    height: calc(100% - 110px);    .mulu {      width: 14%;      .fenlei {        color: #707070;        font-size: 18px;        line-height: 25px;        font-weight: 600;      }      #category {        margin-top: 30px;        font-size: 16px;        color: #707070;        line-height: 24px;        padding: 0;        height: 90%;        overflow: auto;        li {          padding-left: 20px;          margin-top: 4px;          cursor: pointer;          position: relative;          .xianSpan {            border-left: 3px solid #1890ff;            position: absolute;            top: 4px;            height: 15px;            left: 10px;            display: inline-block;          }          a {            width: 90%;            overflow: hidden;            white-space: nowrap;            text-overflow: ellipsis;            display: inline-block;            text-decoration: none;            color: #333;          }          .activedom {            color: #1890ff;            font-weight: bold;          }        }        .current {          color: #1890ff;          position: relative;        }      }    }    .wrapper {      height: 100%;      overflow: hidden;      width: 86%;      .content {        .cateAndlist {          .catename {            font-size: 18px;            line-height: 25px;            color: #333333;            margin: 20px 0 10px 10px;            font-weight: 600;          }          .appAll {            width: 100%;            display: flex;            align-items: center;            flex-wrap: wrap;            .listonce {              background: #f0f3f9;              border-radius: 4px;              width: calc(100% - 80% - 42px);              padding: 10px;              margin: 10px;              min-width: 200px;              .getInto {                background: #f5f8ff;                border-radius: 4px;                border: 1px solid #b4c9fc;                padding: 5px 15px;                font-size: 12px;                font-family: MicrosoftYaHei;                color: #278dff;                float: right;                display: flex;                align-items: center;                cursor: pointer;                .goimg {                  margin-left: 4px;                }              }              .getIntos {                font-size: 12px;                font-family: MicrosoftYaHei;                color: #c7c7c7;                text-align: right;                line-height: 28px;              }              .bottom {                clear: both;                display: flex;                align-items: center;                padding-bottom: 20px;                width: 100%;                .bottom_right {                  line-height: 24px;                  width: 60%;                  margin-left: 10px;                  height: 72px;                  .appname {                    font-size: 16px;                    font-family: PingFangSC-Semibold, PingFang SC;                    font-weight: 600;                    color: #000000;                    word-break: break-all;                    white-space: nowrap;                    overflow: hidden;                    text-overflow: ellipsis;                  }                  .description {                    font-size: 12px;                    font-family: PingFangSC-Regular, PingFang SC;                    font-weight: 400;                    color: #666666;                    word-break: break-all;                    text-overflow: -o-ellipsis-lastline;                    overflow: hidden;                    text-overflow: ellipsis;                    display: -webkit-box;                    -webkit-line-clamp: 3;                    line-clamp: 2;                    -webkit-box-orient: vertical;                  }                }              }            }            .nopower {              background: #f3f3f3;            }          }        }      }    }  }}</style>

页面样式